981 lines
42 KiB
PHP
981 lines
42 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="it">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>{{ $appName ?? 'Glastree' }} — Guida alla Configurazione</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
font-size: 11pt;
|
|
line-height: 1.6;
|
|
color: #333;
|
|
padding: 30px 40px;
|
|
}
|
|
h1 { font-size: 22pt; color: #1a237e; margin-bottom: 5px; }
|
|
h2 { font-size: 16pt; color: #283593; margin-top: 28px; margin-bottom: 10px; border-bottom: 2px solid #e0e0e0; padding-bottom: 4px; }
|
|
h3 { font-size: 13pt; color: #303f9f; margin-top: 20px; margin-bottom: 8px; }
|
|
h4 { font-size: 12pt; color: #3949ab; margin-top: 16px; margin-bottom: 6px; }
|
|
h5 { font-size: 11pt; color: #5c6bc0; margin-top: 14px; margin-bottom: 5px; }
|
|
h6 { font-size: 11pt; color: #5c6bc0; margin-top: 12px; margin-bottom: 4px; }
|
|
p { margin-bottom: 8px; }
|
|
ul, ol { margin: 6px 0 10px 20px; }
|
|
li { margin-bottom: 3px; }
|
|
table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 10pt; }
|
|
th, td { border: 1px solid #ccc; padding: 6px 8px; text-align: left; }
|
|
th { background: #e8eaf6; font-weight: 600; }
|
|
code { background: #f5f5f5; padding: 1px 5px; border-radius: 3px; font-family: 'Consolas', 'Courier New', monospace; font-size: 9.5pt; color: #c62828; }
|
|
pre { background: #263238; color: #e0e0e0; padding: 12px 16px; border-radius: 5px; font-family: 'Consolas', 'Courier New', monospace; font-size: 9pt; line-height: 1.4; overflow-x: auto; margin: 8px 0 14px; white-space: pre-wrap; word-break: break-word; }
|
|
pre code { background: none; color: inherit; padding: 0; font-size: inherit; }
|
|
.callout { border-left: 4px solid; padding: 10px 14px; margin: 12px 0; background: #f5f5f5; border-radius: 0 4px 4px 0; }
|
|
.callout-info { border-color: #2196f3; background: #e3f2fd; }
|
|
.callout-danger { border-color: #f44336; background: #ffebee; }
|
|
.callout-warning { border-color: #ff9800; background: #fff3e0; }
|
|
.callout-success { border-color: #4caf50; background: #e8f5e9; }
|
|
.badge { display: inline-block; padding: 2px 7px; font-size: 9pt; border-radius: 3px; background: #e0e0e0; }
|
|
.badge-primary { background: #1976d2; color: #fff; }
|
|
.badge-success { background: #388e3c; color: #fff; }
|
|
.badge-info { background: #0288d1; color: #fff; }
|
|
.badge-secondary { background: #757575; color: #fff; }
|
|
.subtitle { font-size: 12pt; color: #666; margin-bottom: 20px; }
|
|
.page-break { page-break-before: always; }
|
|
hr { border: none; border-top: 1px solid #ddd; margin: 24px 0; }
|
|
.toc { margin: 20px 0; padding: 16px 20px; background: #f5f5f5; border-radius: 5px; }
|
|
.toc a { color: #1565c0; text-decoration: none; }
|
|
.toc li { margin-bottom: 5px; }
|
|
@media print {
|
|
body { padding: 0; font-size: 10pt; }
|
|
pre { font-size: 8pt; padding: 8px 12px; }
|
|
h2 { page-break-after: avoid; }
|
|
h3, h4, h5 { page-break-after: avoid; }
|
|
.callout, table, pre { page-break-inside: avoid; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h1>{{ $appName ?? 'Glastree' }}</h1>
|
|
<p class="subtitle">Guida completa alla configurazione, installazione e migrazione</p>
|
|
|
|
<div class="toc">
|
|
<strong>Indice</strong>
|
|
<ol>
|
|
<li><a href="#webdav">WebDAV / Nextcloud</a></li>
|
|
<li><a href="#googledrive">Google Drive</a></li>
|
|
<li><a href="#calendario">Google Calendar</a></li>
|
|
<li><a href="#tipologie">Tipologie e Gestione Dati</a></li>
|
|
<li><a href="#email">Email / SMTP</a></li>
|
|
<li><a href="#installazione">Guida all'Installazione</a></li>
|
|
<li><a href="#backup">Backup e Migrazione Server</a></li>
|
|
<li><a href="#docker">Docker</a></li>
|
|
<li><a href="#tag">Tag e Ricerca per Tag</a></li>
|
|
</ol>
|
|
</div>
|
|
|
|
{{-- 1. WebDAV / Nextcloud --}}
|
|
<h2 id="webdav">1. WebDAV / Nextcloud</h2>
|
|
|
|
<h3>Cos'è</h3>
|
|
<p>WebDAV è un protocollo che permette di accedere a file su server remoti. Nextcloud lo utilizza per la sincronizzazione dei file.</p>
|
|
|
|
<h3>Configurazione</h3>
|
|
<p>Vai in <strong>Impostazioni → Repository</strong> e crea un nuovo repository di tipo WebDAV.</p>
|
|
|
|
<div class="callout callout-info">
|
|
<h4>Campi obbligatori</h4>
|
|
<dl>
|
|
<dt><strong>Nome</strong></dt>
|
|
<dd>Un nome descrittivo (es. "Nextcloud Lavoro")</dd>
|
|
<dt><strong>Base URI</strong></dt>
|
|
<dd>L'URL del tuo server WebDAV.<br>
|
|
<em>Nextcloud:</em> <code>https://tuodominio.it/remote.php/dav/files/utente/</code><br>
|
|
<em>Altri:</em> <code>https://server.webdav.it/</code></dd>
|
|
<dt><strong>Root</strong></dt>
|
|
<dd>Percorso base all'interno del server (es. <code>/Documenti/</code>). Lascia <code>/</code> per usare la root.</dd>
|
|
<dt><strong>Username</strong></dt>
|
|
<dd>Il tuo nome utente</dd>
|
|
<dt><strong>Password</strong></dt>
|
|
<dd>La password dell'account</dd>
|
|
<dt><strong>Auth Type</strong></dt>
|
|
<dd><code>Basic</code> per la maggior parte dei server (Nextcloud, ownCloud).</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3>Nome utente con @ (chiocciola)</h3>
|
|
<p>Se il tuo nome utente contiene il carattere <code>@</code> (es. <code>mario.rossi@azienda.com</code>), segui queste regole:</p>
|
|
<ul>
|
|
<li><strong>Nel campo "Base URI":</strong> l'indirizzo email deve essere <strong>URL-encoded</strong>:<br>
|
|
<code>https://server.it/remote.php/dav/files/mario.rossi%40azienda.com/</code><br>
|
|
<small>(il carattere <code>@</code> diventa <code>%40</code>)</small></li>
|
|
<li><strong>Nel campo "Username":</strong> inserisci l'indirizzo email <strong>normale</strong> con la <code>@</code> vera.</li>
|
|
</ul>
|
|
<p>Il sistema gestisce automaticamente la differenza tra l'URI (che richiede <code>%40</code>) e l'autenticazione (che usa la <code>@</code> reale).</p>
|
|
|
|
<h3>Test connessione</h3>
|
|
<p>Dopo aver salvato, usa il pulsante <strong>Test</strong> nella tabella dei repository per verificare che la connessione funzioni.</p>
|
|
|
|
<h3>Importare file</h3>
|
|
<p>Apri la sezione <strong>Documenti</strong>, clicca sul pulsante del repository nella toolbar per sfogliare i file remoti, poi clicca <strong>Salva tra i documenti</strong> su un file per importarlo come documento locale.</p>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 2. Google Drive --}}
|
|
<h2 id="googledrive">2. Google Drive</h2>
|
|
|
|
<h3>Cos'è</h3>
|
|
<p>Integrazione con Google Drive per sfogliare e importare file direttamente dal tuo spazio Google Drive.</p>
|
|
|
|
<h3>Requisiti</h3>
|
|
<ol>
|
|
<li>Un account Google / Google Workspace</li>
|
|
<li>Un progetto sulla <strong>Google Cloud Console</strong> con l'API Google Drive abilitata</li>
|
|
<li>Credenziali OAuth 2.0 (Client ID e Client Secret)</li>
|
|
</ol>
|
|
|
|
<h3>Passo 1: Creare il progetto Google Cloud</h3>
|
|
<ol>
|
|
<li>Vai su <strong>Google Cloud Console</strong> (console.developers.google.com)</li>
|
|
<li>Crea un nuovo progetto o selezionane uno esistente</li>
|
|
<li>Vai a <strong>API e servizi → Libreria</strong></li>
|
|
<li>Cerca "<strong>Google Drive API</strong>" e <strong>abilitala</strong></li>
|
|
<li>Vai a <strong>API e servizi → Credenziali</strong></li>
|
|
<li>Clicca "<strong>Crea credenziali → ID client OAuth</strong>"</li>
|
|
<li>Tipo applicazione: "<strong>Applicazione Web</strong>"</li>
|
|
<li><strong>URI di reindirizzamento autorizzato:</strong> aggiungi <code>{{ url('/auth/google-drive/callback') }}</code></li>
|
|
<li>Completa la creazione e <strong>copia Client ID e Client Secret</strong></li>
|
|
</ol>
|
|
|
|
<h3>Passo 2: Configurazione nell'app</h3>
|
|
<ol>
|
|
<li>Vai in <strong>Impostazioni → Repository</strong></li>
|
|
<li>Clicca "<strong>Nuovo Repository</strong>" e seleziona tipo <strong>Google Drive</strong></li>
|
|
<li>Inserisci un nome descrittivo (es. "Drive Lavoro")</li>
|
|
<li>Incolla <strong>Client ID</strong> e <strong>Client Secret</strong></li>
|
|
<li><strong>Folder ID (opzionale):</strong> se vuoi limitare l'accesso a una cartella specifica, inserisci il suo ID (lo trovi nell'URL quando apri la cartella in Google Drive: <code>https://drive.google.com/drive/folders/<strong>ID_QUI</strong></code>)</li>
|
|
<li>Clicca "<strong>Autorizza Google Drive</strong>" — verrai reindirizzato a Google per concedere i permessi</li>
|
|
<li>Dopo l'autorizzazione, il refresh token verrà salvato automaticamente</li>
|
|
</ol>
|
|
|
|
<h3>Google Drive API non abilitata</h3>
|
|
<p>Se vedi l'errore <em>"Google Drive API non abilitata"</em> nel test connessione, significa che l'API Drive non è stata attivata nel tuo progetto Google Cloud.</p>
|
|
<div class="callout callout-danger">
|
|
<h4>Soluzione</h4>
|
|
<p>Vai su <code>https://console.developers.google.com/apis/api/drive.googleapis.com/overview</code></p>
|
|
<p>Seleziona il progetto corretto dall'header in alto, clicca <strong>"Enable"</strong> e attendi qualche minuto prima di riprovare.</p>
|
|
</div>
|
|
|
|
<h3>Importare file</h3>
|
|
<p>Stessa procedura di WebDAV: apri <strong>Documenti</strong>, clicca sul repository Drive, sfoglia i file e usa <strong>Salva tra i documenti</strong>.</p>
|
|
|
|
<h3>File Google (Documenti, Fogli, Presentazioni)</h3>
|
|
<p>I file creati con Google Workspace (Documenti Google, Fogli Google, Presentazioni Google, Disegni Google) non possono essere scaricati direttamente perché non hanno un formato binario nativo.</p>
|
|
<p>Il sistema li converte automaticamente in formato Office Open XML durante l'import:</p>
|
|
<table>
|
|
<thead><tr><th>File Google</th><th>Formato convertito</th></tr></thead>
|
|
<tbody>
|
|
<tr><td>Documento Google</td><td><code>.docx</code> (Word)</td></tr>
|
|
<tr><td>Foglio Google</td><td><code>.xlsx</code> (Excel)</td></tr>
|
|
<tr><td>Presentazione Google</td><td><code>.pptx</code> (PowerPoint)</td></tr>
|
|
<tr><td>Disegno Google</td><td><code>.png</code> (Immagine)</td></tr>
|
|
<tr><td>Altri (Moduli, Script)</td><td><code>.pdf</code> (PDF)</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Il nome del file viene automaticamente esteso con l'estensione corretta (es. "Relazione" → "Relazione.docx").</p>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 3. Google Calendar --}}
|
|
<h2 id="calendario">3. Google Calendar</h2>
|
|
|
|
<h3>Cos'è</h3>
|
|
<p>Integrazione con Google Calendar per sincronizzare gli eventi tra l'app e il tuo calendario Google. Supporta import, export e sincronizzazione bidirezionale.</p>
|
|
|
|
<h3>Requisiti</h3>
|
|
<ol>
|
|
<li>Un account Google / Google Workspace</li>
|
|
<li>Un progetto sulla <strong>Google Cloud Console</strong> con l'API Google Calendar abilitata</li>
|
|
<li>Credenziali OAuth 2.0 (Client ID e Client Secret)</li>
|
|
</ol>
|
|
|
|
<h3>Passo 1: Creare il progetto Google Cloud</h3>
|
|
<ol>
|
|
<li>Vai su <strong>Google Cloud Console</strong> (console.developers.google.com)</li>
|
|
<li>Crea un nuovo progetto o selezionane uno esistente</li>
|
|
<li>Vai a <strong>API e servizi → Libreria</strong></li>
|
|
<li>Cerca "<strong>Google Calendar API</strong>" e <strong>abilitala</strong></li>
|
|
<li>Vai a <strong>API e servizi → Credenziali</strong></li>
|
|
<li>Clicca "<strong>Crea credenziali → ID client OAuth</strong>"</li>
|
|
<li>Tipo applicazione: "<strong>Applicazione Web</strong>"</li>
|
|
<li><strong>URI di reindirizzamento autorizzato:</strong> aggiungi <code>https://developers.google.com/oauthplayground</code></li>
|
|
<li>Completa la creazione e <strong>copia Client ID e Client Secret</strong></li>
|
|
</ol>
|
|
|
|
<h3>Passo 2: Ottenere il Refresh Token</h3>
|
|
<p>A differenza di Google Drive, per Google Calendar il refresh token va ottenuto manualmente tramite il Google OAuth Playground:</p>
|
|
<ol>
|
|
<li>Vai su <strong>Google OAuth Playground</strong> (developers.google.com/oauthplayground)</li>
|
|
<li>Clicca l'ingranaggio ⚙️ in alto a destra</li>
|
|
<li>Spunta "<strong>Use your own OAuth credentials</strong>"</li>
|
|
<li>Incolla <strong>Client ID</strong> e <strong>Client Secret</strong> creati al Passo 1</li>
|
|
<li>Nella colonna sinistra, espandi "<strong>Google Calendar API v3</strong>" e seleziona lo scope <code>https://www.googleapis.com/auth/calendar</code></li>
|
|
<li>Clicca "<strong>Authorize APIs</strong>" e autorizza con l'account Google</li>
|
|
<li>Clicca "<strong>Exchange authorization code for tokens</strong>"</li>
|
|
<li><strong>Copia il Refresh Token</strong> generato</li>
|
|
</ol>
|
|
|
|
<h3>Passo 3: Configurazione nell'app</h3>
|
|
<ol>
|
|
<li>Vai in <strong>Impostazioni → Calendario</strong></li>
|
|
<li>Clicca "<strong>Nuova Connessione</strong>"</li>
|
|
<li>Inserisci un nome descrittivo (es. "Calendario Lavoro")</li>
|
|
<li>Seleziona tipo <strong>Google Calendar</strong></li>
|
|
<li>Incolla <strong>Client ID</strong>, <strong>Client Secret</strong> e il <strong>Refresh Token</strong> ottenuto</li>
|
|
<li><strong>Calendar ID (opzionale):</strong> lascia <code>primary</code> per il calendario principale, oppure inserisci l'ID di un calendario specifico</li>
|
|
<li>Seleziona la <strong>direzione di sincronizzazione</strong> (import, export o bidirezionale)</li>
|
|
<li>Clicca "<strong>Salva</strong>"</li>
|
|
</ol>
|
|
|
|
<h3>Test connessione</h3>
|
|
<p>Dopo aver salvato, usa il pulsante <strong>Test</strong> nella tabella delle connessioni per verificare che l'autorizzazione funzioni correttamente.</p>
|
|
|
|
<h3>Sincronizzazione</h3>
|
|
<p>Dopo aver configurato la connessione, puoi sincronizzare gli eventi manualmente cliccando <strong>Sync</strong>. La sincronizzazione automatica viene eseguita in base all'intervallo impostato (richiede il cron di Laravel configurato).</p>
|
|
|
|
<div class="callout callout-info">
|
|
<h4>Refresh Token permanente</h4>
|
|
<p>Il Refresh Token è permanente finché non viene revocato dall'utente. Se la connessione smette di funzionare, potrebbe essere necessario rigenerarlo ripetendo il Passo 2.</p>
|
|
</div>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 4. Tipologie e Dati --}}
|
|
<h2 id="tipologie">4. Tipologie e Gestione Dati</h2>
|
|
|
|
<h3>Tipologie Documenti</h3>
|
|
<p>Le tipologie classificano i documenti (avatar, galleria, documento, statuto, altro).</p>
|
|
<p>Si gestiscono in <strong>Impostazioni → Tipologie Documenti</strong>. Puoi aggiungere, rinominare, riordinare ed eliminare tipologie (tranne quelle con documenti associati).</p>
|
|
|
|
<h3>Tipologie Individui</h3>
|
|
<p>Classificano gli individui (es. socio, volontario, dipendente). Si gestiscono in <strong>Impostazioni → Tipologie</strong>.</p>
|
|
|
|
<h3>Tipologie Eventi</h3>
|
|
<p>Classificano gli eventi (es. riunione, assemblea, formazione). Si gestiscono in <strong>Impostazioni → Tipologie Eventi</strong>.</p>
|
|
|
|
<h3>Ruoli Individui</h3>
|
|
<p>Definiscono il ruolo o la carica di un individuo (es. presidente, segretario, tesoriere). Si gestiscono in <strong>Impostazioni → Ruoli</strong>.</p>
|
|
|
|
<h3>Visibilità Documenti</h3>
|
|
<p>Ogni documento può avere diversi livelli di visibilità:</p>
|
|
<ul>
|
|
<li><strong>Pubblico</strong> — visibile a tutti gli utenti</li>
|
|
<li><strong>Individuo</strong> — visibile solo a uno specifico individuo</li>
|
|
<li><strong>Gruppo</strong> — visibile solo ai membri di un gruppo</li>
|
|
<li><strong>Evento</strong> — visibile solo ai partecipanti di un evento</li>
|
|
<li><strong>Mailing</strong> — visibile solo ai membri di una mailing list</li>
|
|
</ul>
|
|
|
|
<h3>Tag</h3>
|
|
<p>I <strong>tag</strong> affiancano le tipologie con un sistema trasversale di classificazione applicabile a individui, gruppi, eventi, documenti e mailing list. A differenza delle tipologie (specifiche per ogni entità), i tag sono condivisi tra tutte le entità e permettono ricerche incrociate.</p>
|
|
<p>Vedi la sezione <a href="#tag">Tag e Ricerca per Tag</a> per la gestione e l'assegnazione.</p>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 5. Email / SMTP --}}
|
|
<h2 id="email">5. Email / SMTP</h2>
|
|
|
|
<h3>Configurazione Email</h3>
|
|
<p>Vai in <strong>Impostazioni → Email</strong> per configurare la posta elettronica.</p>
|
|
|
|
<h3>Server IMAP (Ricezione)</h3>
|
|
<p>Usato per ricevere e leggere le email direttamente nell'app.</p>
|
|
<div class="callout callout-info">
|
|
<h4>Campi consigliati per provider comuni</h4>
|
|
<table>
|
|
<thead><tr><th>Provider</th><th>Host</th><th>Porta</th><th>Crittografia</th></tr></thead>
|
|
<tbody>
|
|
<tr><td>Gmail</td><td><code>imap.gmail.com</code></td><td><code>993</code></td><td>SSL</td></tr>
|
|
<tr><td>Outlook/Office 365</td><td><code>outlook.office365.com</code></td><td><code>993</code></td><td>SSL</td></tr>
|
|
<tr><td>Libero</td><td><code>imapmail.libero.it</code></td><td><code>993</code></td><td>SSL</td></tr>
|
|
<tr><td>Aruba</td><td><code>imap.aruba.it</code></td><td><code>993</code></td><td>SSL</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<h3>Server SMTP (Invio)</h3>
|
|
<p>Usato per inviare email dall'app. Supporta account multipli (mittenti).</p>
|
|
<div class="callout callout-info">
|
|
<h4>Campi consigliati per provider comuni</h4>
|
|
<table>
|
|
<thead><tr><th>Provider</th><th>Host</th><th>Porta</th><th>Crittografia</th></tr></thead>
|
|
<tbody>
|
|
<tr><td>Gmail</td><td><code>smtp.gmail.com</code></td><td><code>587</code></td><td>TLS</td></tr>
|
|
<tr><td>Outlook/Office 365</td><td><code>smtp.office365.com</code></td><td><code>587</code></td><td>TLS</td></tr>
|
|
<tr><td>Libero</td><td><code>smtp.libero.it</code></td><td><code>465</code></td><td>SSL</td></tr>
|
|
<tr><td>Aruba</td><td><code>smtp.aruba.it</code></td><td><code>465</code></td><td>SSL</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<h3>Gmail / Google Workspace</h3>
|
|
<div class="callout callout-warning">
|
|
Gmail richiede una <strong>Password per l'app</strong> (non la password normale) se usi la verifica in due passaggi. Puoi generarla su <code>https://myaccount.google.com/apppasswords</code>.
|
|
</div>
|
|
|
|
<h3>Mailing</h3>
|
|
<p>Le <strong>Mailing List</strong> permettono di inviare email a gruppi predefiniti di destinatari.</p>
|
|
<ul>
|
|
<li>Crea una mailing list in <strong>Mailing List → Nuova</strong></li>
|
|
<li>Puoi popolare la lista da individui, gruppi o manualmente</li>
|
|
<li>Invia email alla lista da <strong>Email → Nuova Email</strong>, selezionando la mailing list come destinatario</li>
|
|
</ul>
|
|
|
|
<div class="callout callout-warning">
|
|
<h4>Avviso contatti senza email</h4>
|
|
<p>Se nella mailing list sono presenti individui che non hanno un indirizzo email nei contatti, il sistema mostra un avviso con l'elenco dei nominativi esclusi dall'invio. Verifica sempre la presenza di email valide prima di procedere con l'invio.</p>
|
|
</div>
|
|
|
|
<h3>Test connessione</h3>
|
|
<p>Dopo aver configurato i server, usa il pulsante <strong>Test Connessione</strong> per verificare che IMAP e SMTP funzionino correttamente.</p>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 6. Installazione --}}
|
|
<h2 id="installazione">6. Guida all'Installazione</h2>
|
|
|
|
<h3>Panoramica</h3>
|
|
<p>L'installazione avviene tramite l'interattivo <code>install.php</code> che guida passo-passo. Supporta due modalità:</p>
|
|
|
|
<table>
|
|
<thead><tr><th>Modalità</th><th>Descrizione</th></tr></thead>
|
|
<tbody>
|
|
<tr><td><strong>Fresh Install</strong></td><td>Installa l'applicazione da zero su un nuovo server: crea il database, esegue le migration, popola i dati di base e crea l'amministratore.</td></tr>
|
|
<tr><td><strong>Restore da Backup</strong></td><td>Ripristina un'installazione esistente da un file ZIP di backup: importa il database, ripristina i documenti e la configurazione.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3>Requisiti del Server</h3>
|
|
<table>
|
|
<thead><tr><th>Componente</th><th>Versione Minima</th><th>Note</th></tr></thead>
|
|
<tbody>
|
|
<tr><td>Web Server</td><td>Apache 2.4+</td><td>Con mod_rewrite abilitato</td></tr>
|
|
<tr><td>PHP</td><td>8.2+ (consigliato 8.4)</td><td>Estensioni: pdo_mysql, mbstring, xml, curl, zip, gd, fileinfo</td></tr>
|
|
<tr><td>MySQL / MariaDB</td><td>MySQL 8.0+ / MariaDB 10.5+</td><td>Supporto utf8mb4</td></tr>
|
|
<tr><td>Composer</td><td>2.x</td><td>Per gestione dipendenze PHP</td></tr>
|
|
<tr><td>Node.js / npm</td><td>Node 20+ / npm 10+</td><td>Per compilazione asset frontend (opzionale se precompilati)</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3>Installazione Passo-Passo</h3>
|
|
|
|
<h4>Passo 1: Preparare il server LAMP</h4>
|
|
<pre>sudo apt update && sudo apt upgrade -y
|
|
|
|
sudo apt install -y apache2 mariadb-server php8.4 php8.4-cli \
|
|
php8.4-mysql php8.4-xml php8.4-mbstring php8.4-curl \
|
|
php8.4-zip php8.4-bcmath php8.4-gd php8.4-intl \
|
|
composer git unzip
|
|
|
|
sudo a2enmod rewrite
|
|
sudo systemctl restart apache2</pre>
|
|
|
|
<h4>Passo 2: Ottenere l'applicazione</h4>
|
|
<p>Puoi clonare il repository con git oppure estrarre il file ZIP ricevuto nella cartella <code>/var/www/glastree</code>.</p>
|
|
<pre>cd /var/www
|
|
|
|
# Opzione A — Git clone
|
|
git clone <URL_REPOSITORY> glastree
|
|
|
|
# Opzione B — ZIP (se non hai git)
|
|
# unzip /percorso/del/glastree.zip -d glastree
|
|
|
|
cd glastree</pre>
|
|
|
|
<h4>Passo 3: Eseguire l'installer</h4>
|
|
<p>Lancia l'installer interattivo che guida attraverso tutte le fasi:</p>
|
|
<pre>php install.php</pre>
|
|
<p>L'installer chiede: modalità (Fresh Install Apache/Docker o Restore), nome sito, dati amministratore, URL pubblico, database (MySQL o SQLite).<br>
|
|
Esegue automaticamente: <code>.env</code> + <code>APP_KEY</code>, composer, migration/seed, admin user, asset (se npm presente), permessi.</p>
|
|
|
|
<h4>Passo 4: Configurare Apache (solo Fresh Install)</h4>
|
|
<pre>sudo tee /etc/apache2/sites-available/glastree.conf <<APACHE
|
|
<VirtualHost *:80>
|
|
ServerName glastree.esempio.it
|
|
DocumentRoot /var/www/glastree/public
|
|
|
|
<Directory /var/www/glastree/public>
|
|
Options -Indexes +FollowSymLinks
|
|
AllowOverride All
|
|
Require all granted
|
|
</Directory>
|
|
|
|
ErrorLog \${APACHE_LOG_DIR}/glastree_error.log
|
|
CustomLog \${APACHE_LOG_DIR}/glastree_access.log combined
|
|
</VirtualHost>
|
|
APACHE
|
|
|
|
sudo a2dissite 000-default.conf
|
|
sudo a2ensite glastree.conf
|
|
sudo systemctl reload apache2</pre>
|
|
|
|
<p>Configura SSL con Let's Encrypt dopo l'installazione.</p>
|
|
php artisan tinker --execute="
|
|
\$u = new \App\Models\User;
|
|
\$u->name = 'Admin';
|
|
\$u->email = 'admin@esempio.it';
|
|
\$u->password = bcrypt('password_sicura');
|
|
\$u->save();
|
|
"</pre>
|
|
|
|
<p><strong>Restore da Backup:</strong></p>
|
|
<pre># Importa il database
|
|
# mysql -u root -p glastree < database.sql
|
|
|
|
# Ripristina i file dei documenti
|
|
# tar -xzf storage.tar.gz -C storage/
|
|
|
|
# Rigenera APP_KEY
|
|
php artisan key:generate
|
|
|
|
# Crea il collegamento storage
|
|
php artisan storage:link</pre>
|
|
|
|
<h3>Dopo l'Installazione</h3>
|
|
<ol>
|
|
<li><strong>Configura SSL</strong> con Let's Encrypt:
|
|
<pre>sudo apt install -y certbot python3-certbot-apache
|
|
sudo certbot --apache -d glastree.esempio.it</pre>
|
|
</li>
|
|
<li><strong>Accedi</strong> con le credenziali amministratore create durante l'installazione</li>
|
|
<li><strong>Configura l'applicazione</strong> in Impostazioni:
|
|
<ul>
|
|
<li>Nome applicazione e logo</li>
|
|
<li>Email (SMTP per invio, IMAP per ricezione)</li>
|
|
<li>Repository remoti (Google Drive, Nextcloud)</li>
|
|
</ul>
|
|
</li>
|
|
<li><strong>Crea utenti</strong> dal pannello Admin → Utenti</li>
|
|
<li><strong>Configura il cron</strong> per backup automatico e sync email:
|
|
<pre>sudo crontab -u www-data -e
|
|
# Inserisci:
|
|
* * * * * cd /var/www/glastree && php artisan schedule:run >> /dev/null 2>&1</pre>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3>Risoluzione Problemi</h3>
|
|
|
|
<div class="callout callout-danger">
|
|
<h4>Errore "500 | Server Error" dopo l'installazione</h4>
|
|
<p>Probabilmente mancano permessi sulle cartelle <code>storage</code> o <code>bootstrap/cache</code>:</p>
|
|
<pre>sudo chown -R www-data:www-data storage bootstrap/cache
|
|
sudo chmod -R 775 storage bootstrap/cache</pre>
|
|
</div>
|
|
|
|
<div class="callout callout-danger">
|
|
<h4>Errore "No application encryption key"</h4>
|
|
<p>APP_KEY non generata. Nella cartella dell'app:</p>
|
|
<pre>php artisan key:generate</pre>
|
|
</div>
|
|
|
|
<div class="callout callout-warning">
|
|
<h4>mod_rewrite non funziona</h4>
|
|
<p>Se le rotte restituiscono 404, verifica che Apache abbia AllowOverride:</p>
|
|
<pre>sudo a2enmod rewrite
|
|
# Nel VirtualHost: AllowOverride All
|
|
sudo systemctl reload apache2</pre>
|
|
</div>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 7. Backup e Migrazione --}}
|
|
<h2 id="backup">7. Backup e Migrazione Server</h2>
|
|
|
|
<h3>Cos'è</h3>
|
|
<p>Il sistema di backup crea un archivio ZIP contenente tutto il necessario per ripristinare l'applicazione su un nuovo server. Include database, file caricati e configurazione.</p>
|
|
|
|
<h3>Cosa include il backup</h3>
|
|
<table>
|
|
<thead><tr><th>Componente</th><th>Incluso</th><th>Dettagli</th></tr></thead>
|
|
<tbody>
|
|
<tr><td>Database (MySQL)</td><td>Sempre</td><td>Struttura, dati, stored procedure, eventi, trigger</td></tr>
|
|
<tr><td>File caricati</td><td>Opzionale</td><td>Documenti, avatar, gallerie</td></tr>
|
|
<tr><td>Configurazione .env</td><td>Opzionale</td><td>APP_KEY, credenziali DB, SMTP, token OAuth</td></tr>
|
|
<tr><td>Metadati</td><td>Sempre</td><td>Versione app, PHP, Laravel</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3>Come eseguire un backup</h3>
|
|
|
|
<table>
|
|
<thead><tr><th>Via Interfaccia Web</th><th>Via Comando</th></tr></thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<ol>
|
|
<li>Vai su <strong>Admin → Backup</strong></li>
|
|
<li>Verifica le impostazioni (includi files/.env)</li>
|
|
<li>Clicca <strong>Esegui Backup Ora</strong></li>
|
|
<li>Scarica il file ZIP generato</li>
|
|
</ol>
|
|
</td>
|
|
<td>
|
|
<pre>php artisan backup:run</pre>
|
|
<p>Il file viene creato in <code>storage/app/backups/</code></p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3>Backup automatico</h3>
|
|
<p>Puoi abilitare il backup automatico dalla pagina <strong>Admin → Backup</strong>:</p>
|
|
<ul>
|
|
<li><strong>Frequenza:</strong> giornaliero, settimanale o mensile</li>
|
|
<li><strong>Ora:</strong> consigliata 03:00 (notte)</li>
|
|
<li><strong>Requisito:</strong> il cron di Laravel deve essere configurato sul server</li>
|
|
</ul>
|
|
|
|
<div class="callout callout-warning">
|
|
<i class="fas fa-clock mr-2"></i>
|
|
Per il backup automatico, aggiungi questo cron:
|
|
<pre>* * * * * cd {{ base_path() }} && php artisan schedule:run >> /dev/null 2>&1</pre>
|
|
</div>
|
|
|
|
<hr>
|
|
|
|
<h3>Procedura di Migrazione Completa</h3>
|
|
<p>Segui questa procedura per migrare l'applicazione su un nuovo server LAMP (Linux, Apache, MySQL, PHP).</p>
|
|
|
|
<div class="callout callout-danger">
|
|
<strong>ATTENZIONE: APP_KEY</strong>
|
|
<p>L'APP_KEY cripta i dati sensibili (password email SMTP, token OAuth Google Drive, ecc.).</p>
|
|
<ul>
|
|
<li><strong>Se hai il .env originale dal backup:</strong> NON rigenerare APP_KEY — mantieni i dati criptati accessibili.</li>
|
|
<li><strong>Se hai perso il .env:</strong> DEVI rigenerare APP_KEY, ma perderai l'accesso ai dati criptati esistenti. Dovrai riconfigurare SMTP e OAuth.</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<h4>Passo 1: Preparazione del server</h4>
|
|
<pre>sudo apt update && sudo apt upgrade -y</pre>
|
|
|
|
<h4>Passo 2: Installa LAMP + PHP 8.4</h4>
|
|
<pre>sudo apt install -y apache2 mariadb-server php8.4 php8.4-cli \
|
|
php8.4-mysql php8.4-xml php8.4-mbstring php8.4-curl \
|
|
php8.4-zip php8.4-bcmath php8.4-gd php8.4-intl \
|
|
composer git unzip
|
|
|
|
sudo a2enmod rewrite</pre>
|
|
|
|
<h4>Passo 3: Ottieni l'applicazione</h4>
|
|
<p>Puoi clonare il repository con git oppure estrarre il file ZIP ricevuto nella cartella <code>/var/www/glastree</code>.</p>
|
|
<pre>cd /var/www
|
|
|
|
# Opzione A — Git clone
|
|
git clone <URL_REPOSITORY> glastree
|
|
|
|
# Opzione B — ZIP (se non hai git)
|
|
# unzip /percorso/del/glastree.zip -d glastree
|
|
|
|
cd glastree
|
|
composer install --no-dev --optimize-autoloader
|
|
npm ci && npm run build</pre>
|
|
|
|
<h4>Passo 4: Carica il backup</h4>
|
|
<p>Copia il file <code>backup.zip</code> sul nuovo server e estrailo:</p>
|
|
<pre>mkdir -p /tmp/restore
|
|
unzip backup.zip -d /tmp/restore/
|
|
ls -la /tmp/restore/
|
|
# Dovresti vedere: database.sql .env files/ manifest.json</pre>
|
|
|
|
<h4>Passo 5: Crea database e importa</h4>
|
|
<pre>sudo mysql -u root <<EOF
|
|
CREATE DATABASE glastree CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
CREATE USER 'glastree'@'localhost' IDENTIFIED BY 'ScegliPasswordFortep4ss!';
|
|
GRANT ALL ON glastree.* TO 'glastree'@'localhost';
|
|
FLUSH PRIVILEGES;
|
|
EOF
|
|
|
|
mysql -u glastree -p glastree < /tmp/restore/database.sql</pre>
|
|
|
|
<h4>Passo 6: Configura .env</h4>
|
|
<pre>cp /tmp/restore/.env .env
|
|
# Modifica se necessario:
|
|
# APP_URL=https://nuovo-dominio.it
|
|
# DB_HOST=localhost
|
|
# DB_DATABASE=glastree
|
|
# DB_USERNAME=glastree
|
|
# DB_PASSWORD=ScegliPasswordFortep4ss!
|
|
|
|
# DECIDI SULL'APP_KEY (leggi avviso sopra!)
|
|
# php artisan key:generate ← SOLO se non hai il .env originale</pre>
|
|
|
|
<h4>Passo 7: Ripristina file e permessi</h4>
|
|
<pre>cp -r /tmp/restore/files/* storage/app/documenti/
|
|
|
|
sudo chown -R www-data:www-data storage bootstrap/cache
|
|
sudo chmod -R 755 storage bootstrap/cache
|
|
|
|
php artisan storage:link</pre>
|
|
|
|
<h4>Passo 8: Cache</h4>
|
|
<pre>php artisan optimize:clear
|
|
php artisan config:cache
|
|
php artisan route:cache
|
|
php artisan view:cache</pre>
|
|
|
|
<h4>Passo 9: Configura Apache</h4>
|
|
<pre>sudo tee /etc/apache2/sites-available/glastree.conf <<APACHE
|
|
<VirtualHost *:80>
|
|
ServerName glastree.esempio.it
|
|
DocumentRoot /var/www/glastree/public
|
|
|
|
<Directory /var/www/glastree/public>
|
|
Options -Indexes +FollowSymLinks
|
|
AllowOverride All
|
|
Require all granted
|
|
</Directory>
|
|
|
|
ErrorLog \${APACHE_LOG_DIR}/glastree_error.log
|
|
CustomLog \${APACHE_LOG_DIR}/glastree_access.log combined
|
|
</VirtualHost>
|
|
APACHE
|
|
|
|
sudo a2dissite 000-default.conf
|
|
sudo a2ensite glastree.conf
|
|
sudo systemctl reload apache2</pre>
|
|
|
|
<h4>Passo 10: SSL Let's Encrypt</h4>
|
|
<pre>sudo apt install -y certbot python3-certbot-apache
|
|
sudo certbot --apache -d glastree.esempio.it</pre>
|
|
|
|
<h4>Passo 11: Cron per backup automatico</h4>
|
|
<pre>sudo crontab -u www-data -e
|
|
# Inserisci:
|
|
* * * * * cd /var/www/glastree && php artisan schedule:run >> /dev/null 2>&1</pre>
|
|
|
|
<h4>Passo 12: Verifica finale</h4>
|
|
<ol>
|
|
<li>Apri https://glastree.esempio.it nel browser</li>
|
|
<li>Fai login con le credenziali esistenti</li>
|
|
<li>Verifica: Dashboard, Documenti, Impostazioni, Email</li>
|
|
<li>Se hai rigenerato APP_KEY: riconfigura SMTP e OAuth Google Drive</li>
|
|
</ol>
|
|
|
|
<hr>
|
|
|
|
<h3>Comandi Artisan</h3>
|
|
<p>Per installazione e ripristino usa i comandi Artisan da terminale. Vedi la sezione <strong>Installazione</strong> per la guida completa.</p>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 8. Docker --}}
|
|
<h2 id="docker">8. Docker</h2>
|
|
|
|
<h3>Creare un'immagine Docker con dati di base</h3>
|
|
<p>Puoi creare un'immagine Docker pronta all'uso che include l'applicazione e i dati di base (tipologie documenti, tipologie eventi, ruoli). Scegli la configurazione in base alle tue esigenze:</p>
|
|
|
|
<table>
|
|
<thead><tr><th>Configurazione</th><th>Descrizione</th></tr></thead>
|
|
<tbody>
|
|
<tr><td><strong>SQLite (Leggero)</strong></td><td>Database embedded, nessun servizio aggiuntivo. Ideale per demo, test, sviluppo locale o ambienti con poca concorrenza.</td></tr>
|
|
<tr><td><strong>MySQL (Standard)</strong></td><td>Database separato in un container MySQL. Configurazione standard, ideale per produzione, staging e ambienti con più utenti.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h3>1. Dockerfile (comune a entrambe le modalità)</h3>
|
|
<pre>FROM php:8.4-apache
|
|
|
|
# Abilita mod_rewrite
|
|
RUN docker-php-ext-enable opcache \
|
|
&& a2enmod rewrite
|
|
|
|
# Installa estensioni PHP (sia SQLite che MySQL)
|
|
RUN docker-php-ext-install pdo_mysql pdo_sqlite bcmath gd zip
|
|
|
|
# Installa Composer
|
|
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
|
|
|
# Configura DocumentRoot per Laravel
|
|
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
|
|
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
|
|
&& sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
|
|
|
|
# Copia l'applicazione
|
|
COPY . /var/www/html/
|
|
|
|
# Installa dipendenze e compila asset
|
|
RUN composer install --no-dev --optimize-autoloader \
|
|
&& mkdir -p storage/app/public \
|
|
&& mkdir -p storage/framework/cache/data \
|
|
&& mkdir -p storage/framework/sessions \
|
|
&& mkdir -p storage/framework/views \
|
|
&& mkdir -p storage/logs \
|
|
&& mkdir -p bootstrap/cache \
|
|
&& chown -R www-data:www-data storage bootstrap/cache
|
|
|
|
# Entrypoint per inizializzazione
|
|
COPY docker-entrypoint.sh /usr/local/bin/
|
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
|
|
|
ENTRYPOINT ["docker-entrypoint.sh"]
|
|
CMD ["apache2-foreground"]</pre>
|
|
|
|
<h3>2. Entrypoint Script (comune)</h3>
|
|
<p>Crea <code>docker-entrypoint.sh</code>. Lo script rileva automaticamente la configurazione in base alle variabili d'ambiente:</p>
|
|
<pre>#!/bin/bash
|
|
set -e
|
|
|
|
# Se .env non esiste, lo genera dalle variabili d'ambiente
|
|
if [ ! -f .env ]; then
|
|
cp .env.example .env
|
|
|
|
if [ "$DB_CONNECTION" = "mysql" ]; then
|
|
# Configura MySQL
|
|
sed -i "s/DB_CONNECTION=mysql/DB_CONNECTION=mysql/" .env
|
|
sed -i "s/DB_HOST=.*/DB_HOST=${DB_HOST:-mysql}/" .env
|
|
sed -i "s/DB_PORT=.*/DB_PORT=${DB_PORT:-3306}/" .env
|
|
sed -i "s/DB_DATABASE=.*/DB_DATABASE=${DB_DATABASE:-glastree}/" .env
|
|
sed -i "s/DB_USERNAME=.*/DB_USERNAME=${DB_USERNAME:-glastree}/" .env
|
|
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=${DB_PASSWORD:-secret}/" .env
|
|
|
|
# Attende che MySQL sia pronto
|
|
echo "Attendo MySQL..."
|
|
until php -r "new PDO('mysql:host=${DB_HOST:-mysql};dbname=${DB_DATABASE:-glastree}', '${DB_USERNAME:-glastree}', '${DB_PASSWORD:-secret}');" 2>/dev/null; do
|
|
sleep 2
|
|
done
|
|
echo "MySQL pronto."
|
|
else
|
|
# Configura SQLite
|
|
sed -i 's/DB_CONNECTION=mysql/DB_CONNECTION=sqlite/' .env
|
|
sed -i 's/DB_HOST=.*//' .env
|
|
sed -i 's/DB_PORT=.*//' .env
|
|
sed -i 's/DB_DATABASE=.*/DB_DATABASE=\/var\/www\/html\/database\/database.sqlite/' .env
|
|
sed -i 's/DB_USERNAME=.*//' .env
|
|
sed -i 's/DB_PASSWORD=.*//' .env
|
|
|
|
touch database/database.sqlite
|
|
chmod 664 database/database.sqlite
|
|
fi
|
|
|
|
# Genera APP_KEY
|
|
php artisan key:generate --force
|
|
fi
|
|
|
|
# Esegui migration e seed se il database è vuoto
|
|
if [ ! -f .db_initialized ]; then
|
|
php artisan migrate --force
|
|
php artisan db:seed --force
|
|
touch .db_initialized
|
|
fi
|
|
|
|
# Configura storage link
|
|
php artisan storage:link --force 2>/dev/null || true
|
|
|
|
exec "$@"</pre>
|
|
<pre>chmod +x docker-entrypoint.sh</pre>
|
|
|
|
<h3>3. Seed Base Dati (comune)</h3>
|
|
<p>Per includere tipologie documenti, tipologie eventi e ruoli, crea un seeder dedicato:</p>
|
|
<pre>php artisan make:seeder DockerBaseDataSeeder</pre>
|
|
|
|
<p>Contenuto di <code>database/seeders/DockerBaseDataSeeder.php</code>:</p>
|
|
<pre><?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use Illuminate\Database\Seeder;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class DockerBaseDataSeeder extends Seeder
|
|
{
|
|
public function run(): void
|
|
{
|
|
// Tipologie Documenti
|
|
$tipologieDoc = ['documento', 'avatar', 'galleria', 'statuto', 'programma', 'locandina', 'altro'];
|
|
foreach ($tipologieDoc as $ord => $nome) {
|
|
DB::table('tipologie_documenti')->updateOrInsert(
|
|
['nome' => $nome],
|
|
['descrizione' => ucfirst($nome), 'ordine' => $ord + 1, 'attiva' => true]
|
|
);
|
|
}
|
|
|
|
// Tipologie Eventi
|
|
$tipologieEventi = [
|
|
['nome' => 'catechesi', 'descrizione' => 'Catechesi'],
|
|
['nome' => 'liturgia', 'descrizione' => 'Liturgia'],
|
|
['nome' => 'animazione', 'descrizione' => 'Animazione'],
|
|
['nome' => 'formazione', 'descrizione' => 'Formazione'],
|
|
['nome' => 'incontro', 'descrizione' => 'Incontro'],
|
|
['nome' => 'riunione', 'descrizione' => 'Riunione'],
|
|
['nome' => 'festa', 'descrizione' => 'Festa'],
|
|
['nome' => 'altro', 'descrizione' => 'Altro'],
|
|
];
|
|
foreach ($tipologieEventi as $ord => $t) {
|
|
DB::table('tipologie_eventi')->updateOrInsert(
|
|
['nome' => $t['nome']],
|
|
['descrizione' => $t['descrizione'], 'ordine' => $ord + 1, 'attiva' => true]
|
|
);
|
|
}
|
|
|
|
// Ruoli
|
|
$ruoli = ['presidente', 'vicepresidente', 'segretario', 'tesoriere', 'consigliere', 'volontario', 'socio', 'altro'];
|
|
foreach ($ruoli as $ord => $nome) {
|
|
DB::table('ruoli')->updateOrInsert(
|
|
['nome' => $nome],
|
|
['descrizione' => ucfirst($nome), 'ordine' => $ord + 1, 'attiva' => true]
|
|
);
|
|
}
|
|
}
|
|
}</pre>
|
|
|
|
<p>Registralo in <code>database/seeders/DatabaseSeeder.php</code>:</p>
|
|
<pre>$this->call([
|
|
// ... altri seeder ...
|
|
DockerBaseDataSeeder::class,
|
|
]);</pre>
|
|
|
|
<h3>4. Docker Compose</h3>
|
|
|
|
<h4>Opzione A — SQLite (leggero)</h4>
|
|
<pre>services:
|
|
glastree:
|
|
build: .
|
|
ports:
|
|
- "8080:80"
|
|
volumes:
|
|
- glastree_storage:/var/www/html/storage
|
|
- glastree_db:/var/www/html/database
|
|
environment:
|
|
- APP_ENV=production
|
|
- APP_DEBUG=false
|
|
- APP_URL=http://localhost:8080
|
|
- DB_CONNECTION=sqlite
|
|
|
|
volumes:
|
|
glastree_storage:
|
|
glastree_db:</pre>
|
|
|
|
<h4>Opzione B — MySQL (standard)</h4>
|
|
<pre>services:
|
|
glastree:
|
|
build: .
|
|
ports:
|
|
- "8080:80"
|
|
volumes:
|
|
- glastree_storage:/var/www/html/storage
|
|
depends_on:
|
|
mysql:
|
|
condition: service_healthy
|
|
environment:
|
|
- APP_ENV=production
|
|
- APP_DEBUG=false
|
|
- APP_URL=http://localhost:8080
|
|
- DB_CONNECTION=mysql
|
|
- DB_HOST=mysql
|
|
- DB_PORT=3306
|
|
- DB_DATABASE=glastree
|
|
- DB_USERNAME=glastree
|
|
- DB_PASSWORD=secret
|
|
|
|
mysql:
|
|
image: mysql:8.0
|
|
volumes:
|
|
- mysql_data:/var/lib/mysql
|
|
environment:
|
|
- MYSQL_DATABASE=glastree
|
|
- MYSQL_USER=glastree
|
|
- MYSQL_PASSWORD=secret
|
|
- MYSQL_ROOT_PASSWORD=root_secret
|
|
healthcheck:
|
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 10
|
|
|
|
volumes:
|
|
glastree_storage:
|
|
mysql_data:</pre>
|
|
|
|
<h3>5. Build e avvio</h3>
|
|
<p>Assicurati di essere nella cartella del progetto (ottenuta via <code>git clone</code> o estraendo il ZIP), poi:</p>
|
|
<pre># Costruisci l'immagine (comune)
|
|
docker build -t glastree:latest .
|
|
|
|
# Avvia con SQLite
|
|
docker compose -f docker-compose.yml up -d
|
|
|
|
# Oppure avvia con MySQL
|
|
# docker compose -f docker-compose.mysql.yml up -d
|
|
|
|
# Apri nel browser
|
|
open http://localhost:8080</pre>
|
|
|
|
<h3>6. Primo accesso</h3>
|
|
<p>Al primo avvio, l'entrypoint esegue automaticamente migration e seed. Troverai già popolati:</p>
|
|
<ul>
|
|
<li><strong>Tipologie Documenti:</strong> documento, avatar, galleria, statuto, programma, locandina, altro</li>
|
|
<li><strong>Tipologie Eventi:</strong> catechesi, liturgia, animazione, formazione, incontro, riunione, festa, altro</li>
|
|
<li><strong>Ruoli:</strong> presidente, vicepresidente, segretario, tesoriere, consigliere, volontario, socio, altro</li>
|
|
</ul>
|
|
<p>Dovrai creare il primo utente amministratore via CLI:</p>
|
|
<pre>docker exec -it glastree php artisan tinker --execute="
|
|
\$u = new \App\Models\User;
|
|
\$u->name = 'Amministratore';
|
|
\$u->email = 'admin@esempio.it';
|
|
\$u->password = bcrypt('password-forte');
|
|
\$u->is_admin = true;
|
|
\$u->permissions = ['individui' => 2, 'gruppi' => 2, 'eventi' => 2, 'documenti' => 2, 'mailing' => 2, 'viste' => 2, 'report' => 2, 'settings' => 2];
|
|
\$u->save();
|
|
echo 'Utente creato con successo!';
|
|
"</pre>
|
|
|
|
<div class="callout callout-warning">
|
|
<h4>Note importanti</h4>
|
|
<ul>
|
|
<li><strong>Persistenza:</strong> i volumi Docker preservano storage e database tra i riavvii</li>
|
|
<li><strong>APP_KEY:</strong> viene generata al primo avvio — se elimini i volumi, la perdi e i dati criptati diventano inaccessibili</li>
|
|
<li><strong>MySQL in produzione:</strong> imposta password sicure per <code>MYSQL_PASSWORD</code> e <code>MYSQL_ROOT_PASSWORD</code></li>
|
|
<li><strong>File compose separati:</strong> puoi mantenere entrambi i file (<code>docker-compose.yml</code> per SQLite, <code>docker-compose.mysql.yml</code> per MySQL) e scegliere con <code>-f</code></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
{{-- 9. Tag e Ricerca --}}
|
|
<h2 id="tag">9. Tag e Ricerca per Tag</h2>
|
|
|
|
<h3>Cos'è il sistema di Tag</h3>
|
|
<p>I tag permettono di classificare e raggruppare trasversalmente elementi di tipo diverso: individui, gruppi, eventi, documenti e mailing list. A differenza delle tipologie (specifiche per ogni entità), i tag sono <strong>condivisi</strong> tra tutte le entità.</p>
|
|
|
|
<h3>Gestione Tag</h3>
|
|
<p>Vai in <strong>Impostazioni → Tag</strong> per creare, modificare, riordinare ed eliminare i tag. Ogni tag ha:</p>
|
|
<ul>
|
|
<li><strong>Nome</strong> — il nome visualizzato</li>
|
|
<li><strong>Colore</strong> — colore personalizzato per il badge (es. <code>#dc3545</code> per rosso)</li>
|
|
<li><strong>Slug</strong> — identificatore univoco generato automaticamente dal nome</li>
|
|
</ul>
|
|
|
|
<h3>Assegnare Tag</h3>
|
|
<p>I tag si assegnano nelle pagine di creazione e modifica di ciascuna entità — individui, gruppi, eventi, documenti, mailing list — tramite il selettore a pillole colorate. Clicca su un tag per selezionarlo (il badge diventa opaco), clicca di nuovo per deselezionarlo. Usa la barra di ricerca per filtrare i tag per nome.</p>
|
|
|
|
<h3>Assegnazione Massiva di Tag</h3>
|
|
<p>Puoi assegnare o rimuovere tag a più elementi contemporaneamente:</p>
|
|
<ul>
|
|
<li><strong>Individui:</strong> seleziona gli individui nella tabella, apri <strong>Azioni → Assegna Tag</strong>, scegli Assegna/Rimuovi e seleziona i tag</li>
|
|
<li><strong>Gruppi:</strong> stessa procedura — seleziona i gruppi, <strong>Azioni → Assegna Tag</strong></li>
|
|
<li><strong>Documenti:</strong> seleziona i documenti, pulsante <strong>Tag</strong> nella toolbar</li>
|
|
</ul>
|
|
|
|
<h3>Filtrare per Tag</h3>
|
|
<p>In ogni pagina elenco (Individui, Gruppi, Eventi, Documenti, Mailing List) trovi una barra con tutti i tag. Clicca su un tag per filtrare la tabella mostrando solo gli elementi con quel tag. Clicca <strong>Cancella filtri</strong> per rimuovere il filtro.</p>
|
|
|
|
<h3>Ricerca per Tag</h3>
|
|
<p>La sezione <strong>Ricerca per Tag</strong> (sidebar → Ricerca per Tag) permette di trovare elementi di qualsiasi tipo in base ai tag:</p>
|
|
<ul>
|
|
<li><strong>Tag singolo:</strong> seleziona un tag per vedere tutti gli elementi associati</li>
|
|
<li><strong>Tag multipli (AND):</strong> seleziona più tag (Ctrl+click) per trovare elementi che hanno <strong>tutti</strong> i tag selezionati — utile per ricerche precise (es. "animatore" + "giovane")</li>
|
|
</ul>
|
|
<p>I risultati sono raggruppati per tipo con info-box colorati e tabelle dettagliate.</p>
|
|
|
|
</body>
|
|
</html>
|