247 lines
13 KiB
PHP
247 lines
13 KiB
PHP
@extends('layouts.adminlte')
|
|
|
|
@section('title', 'Backup - ' . $appName)
|
|
@section('page_title', 'Backup e Migrazione')
|
|
@section('breadcrumbs')
|
|
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
|
<li class="breadcrumb-item"><a href="/admin/utenti">Admin</a></li>
|
|
<li class="breadcrumb-item active">Backup</li>
|
|
@endsection
|
|
|
|
@section('content')
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
{{-- Lista backup --}}
|
|
<div class="card card-outline card-primary">
|
|
<div class="card-header">
|
|
<h3 class="card-title"><i class="fas fa-hdd mr-2"></i>Backup Disponibili</h3>
|
|
<div class="card-tools">
|
|
<form method="POST" action="{{ route('admin.backup.run') }}" style="display:inline">
|
|
@csrf
|
|
<button type="submit" class="btn btn-primary btn-sm">
|
|
<i class="fas fa-play mr-1"></i> Esegui Backup Ora
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
@if(count($backups) > 0)
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-striped mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>File</th>
|
|
<th>Data</th>
|
|
<th>Dimensione</th>
|
|
<th>Contenuto</th>
|
|
<th class="text-center">Azioni</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($backups as $backup)
|
|
<tr>
|
|
<td><code>{{ $backup['filename'] }}</code></td>
|
|
<td>{{ date('d/m/Y H:i', $backup['last_modified']) }}</td>
|
|
<td>{{ $backup['size_formatted'] }}</td>
|
|
<td>
|
|
@if($backup['manifest'])
|
|
<span class="badge badge-info" title="PHP {{ $backup['manifest']['php_version'] ?? '?' }}, Laravel {{ $backup['manifest']['laravel_version'] ?? '?' }}">
|
|
<i class="fas fa-database mr-1"></i>DB
|
|
</span>
|
|
@if(isset($backup['manifest']['db_name']))
|
|
<small class="text-muted">{{ $backup['manifest']['db_name'] }}</small>
|
|
@endif
|
|
@else
|
|
<span class="badge badge-secondary">N/A</span>
|
|
@endif
|
|
</td>
|
|
<td class="text-center">
|
|
<a href="{{ route('admin.backup.download', $backup['filename']) }}" class="btn btn-success btn-sm" title="Scarica">
|
|
<i class="fas fa-download"></i>
|
|
</a>
|
|
<form method="POST" action="{{ route('admin.backup.destroy', $backup['filename']) }}" style="display:inline" onsubmit="return confirm('Eliminare definitivamente questo backup?')">
|
|
@csrf
|
|
@method('DELETE')
|
|
<button type="submit" class="btn btn-danger btn-sm" title="Elimina">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@else
|
|
<div class="text-center py-5">
|
|
<i class="fas fa-hdd fa-3x text-muted mb-3"></i>
|
|
<p class="text-muted mb-0">Nessun backup disponibile.</p>
|
|
<p class="text-muted">Clicca "Esegui Backup Ora" per creare il primo backup.</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Info sul backup --}}
|
|
<div class="card card-outline card-info">
|
|
<div class="card-header">
|
|
<h3 class="card-title"><i class="fas fa-info-circle mr-2"></i>Cosa Include il Backup</h3>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<table class="table table-bordered mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Componente</th>
|
|
<th>Incluso</th>
|
|
<th>Dettagli</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><i class="fas fa-database text-primary mr-2"></i> Database (MySQL)</td>
|
|
<td><span class="badge badge-success">Sempre</span></td>
|
|
<td>Struttura, dati, stored procedure, eventi, trigger</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="fas fa-file text-warning mr-2"></i> File caricati</td>
|
|
<td>
|
|
@if($config['backup_include_files'])
|
|
<span class="badge badge-success">Sì</span>
|
|
@else
|
|
<span class="badge badge-secondary">No</span>
|
|
@endif
|
|
</td>
|
|
<td>Documenti, avatar, gallerie — dalla cartella storage</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="fas fa-cog text-secondary mr-2"></i> Configurazione (.env)</td>
|
|
<td>
|
|
@if($config['backup_include_env'])
|
|
<span class="badge badge-success">Sì</span>
|
|
@else
|
|
<span class="badge badge-secondary">No</span>
|
|
@endif
|
|
</td>
|
|
<td>APP_KEY, DB credentials, SMTP, OAuth token</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="fas fa-tag text-info mr-2"></i> Metadati</td>
|
|
<td><span class="badge badge-success">Sempre</span></td>
|
|
<td>Manifest JSON con versione app, PHP, Laravel</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
{{-- Configurazione --}}
|
|
<div class="card card-outline card-secondary">
|
|
<div class="card-header">
|
|
<h3 class="card-title"><i class="fas fa-sliders-h mr-2"></i>Configurazione Backup</h3>
|
|
</div>
|
|
<form method="POST" action="{{ route('admin.backup.config') }}">
|
|
@csrf
|
|
<div class="card-body">
|
|
<div class="form-group">
|
|
<label for="backup_path">Percorso backup</label>
|
|
<div class="input-group">
|
|
<div class="input-group-prepend">
|
|
<span class="input-group-text"><code>storage/app/</code></span>
|
|
</div>
|
|
<input type="text" name="backup_path" id="backup_path" class="form-control" value="{{ $config['backup_path'] }}">
|
|
</div>
|
|
<small class="text-muted">Cartella dove salvare i backup (relativa a storage/app/)</small>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="backup_retention_days">Ritenzione (giorni)</label>
|
|
<input type="number" name="backup_retention_days" id="backup_retention_days" class="form-control" value="{{ $config['backup_retention_days'] }}" min="1" max="365">
|
|
<small class="text-muted">I backup più vecchi vengono eliminati automaticamente</small>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<div class="custom-control custom-switch">
|
|
<input type="checkbox" class="custom-control-input" id="backup_include_files" name="backup_include_files" value="1" {{ $config['backup_include_files'] ? 'checked' : '' }}>
|
|
<label class="custom-control-label" for="backup_include_files">Includi file caricati</label>
|
|
</div>
|
|
<div class="custom-control custom-switch mt-2">
|
|
<input type="checkbox" class="custom-control-input" id="backup_include_env" name="backup_include_env" value="1" {{ $config['backup_include_env'] ? 'checked' : '' }}>
|
|
<label class="custom-control-label" for="backup_include_env">Includi .env (configurazione)</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-secondary btn-block">
|
|
<i class="fas fa-save mr-1"></i> Salva Configurazione
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
{{-- Backup automatico --}}
|
|
<div class="card card-outline card-warning">
|
|
<div class="card-header">
|
|
<h3 class="card-title"><i class="fas fa-clock mr-2"></i>Backup Automatico</h3>
|
|
<div class="card-tools">
|
|
@php $autoEnabled = \App\Models\AppSetting::getSetting('backup_auto_enabled', false) @endphp
|
|
<form method="POST" action="{{ route('admin.backup.toggle-auto') }}" style="display:inline">
|
|
@csrf
|
|
<button type="submit" class="btn btn-sm {{ $autoEnabled ? 'btn-success' : 'btn-secondary' }}">
|
|
<i class="fas {{ $autoEnabled ? 'fa-check-circle' : 'fa-times-circle' }} mr-1"></i>
|
|
{{ $autoEnabled ? 'Attivo' : 'Disattivo' }}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<form method="POST" action="{{ route('admin.backup.save-auto') }}">
|
|
@csrf
|
|
<div class="card-body">
|
|
<div class="form-group">
|
|
<label for="backup_auto_frequency">Frequenza</label>
|
|
<select name="backup_auto_frequency" id="backup_auto_frequency" class="form-control">
|
|
<option value="daily" {{ \App\Models\AppSetting::getSetting('backup_auto_frequency', 'daily') === 'daily' ? 'selected' : '' }}>Giornaliero</option>
|
|
<option value="weekly" {{ \App\Models\AppSetting::getSetting('backup_auto_frequency', 'daily') === 'weekly' ? 'selected' : '' }}>Settimanale</option>
|
|
<option value="monthly" {{ \App\Models\AppSetting::getSetting('backup_auto_frequency', 'daily') === 'monthly' ? 'selected' : '' }}>Mensile</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group mb-0">
|
|
<label for="backup_auto_hour">Ora di esecuzione</label>
|
|
<select name="backup_auto_hour" id="backup_auto_hour" class="form-control">
|
|
@for($h = 0; $h <= 23; $h++)
|
|
<option value="{{ $h }}" {{ \App\Models\AppSetting::getSetting('backup_auto_hour', 3) == $h ? 'selected' : '' }}>{{ sprintf('%02d:00', $h) }}</option>
|
|
@endfor
|
|
</select>
|
|
<small class="text-muted">Ora del giorno (formato 24h). Consigliato: 03:00 (notte)</small>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer">
|
|
<button type="submit" class="btn btn-warning btn-block">
|
|
<i class="fas fa-save mr-1"></i> Salva Automatico
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
{{-- Migrazione --}}
|
|
<div class="card card-outline card-danger">
|
|
<div class="card-header">
|
|
<h3 class="card-title"><i class="fas fa-truck mr-2"></i>Migrazione Server</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="text-muted">Scarica il backup, poi esegui lo script di setup sul nuovo server per una migrazione completa.</p>
|
|
<a href="{{ route('help') }}#help-backup" class="btn btn-danger btn-block" target="_blank">
|
|
<i class="fas fa-book mr-1"></i> Guida alla Migrazione
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Alert notifica cron --}}
|
|
<div class="alert alert-info">
|
|
<i class="fas fa-info-circle mr-2"></i>
|
|
<strong>Importante:</strong> Per il backup automatico, assicurati che il cron di Laravel sia configurato sul server:
|
|
<code class="ml-2">* * * * * cd {{ base_path() }} && php artisan schedule:run >> /dev/null 2>&1</code>
|
|
</div>
|
|
@endsection
|