2026-05-26 08:14:29 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
|
|
use App\Models\AppSetting;
|
2026-06-02 22:07:16 +02:00
|
|
|
use App\Models\CalendarioConnessione;
|
2026-06-02 20:29:47 +02:00
|
|
|
use App\Models\Documento;
|
2026-05-26 14:10:04 +02:00
|
|
|
use App\Models\EmailSetting;
|
2026-05-26 08:14:29 +02:00
|
|
|
use App\Models\Ruolo;
|
2026-05-27 08:37:37 +02:00
|
|
|
use App\Models\SenderAccount;
|
2026-05-28 09:34:28 +02:00
|
|
|
use App\Models\StorageRepository;
|
2026-06-09 11:22:56 +02:00
|
|
|
use App\Models\Tag;
|
2026-05-26 08:14:29 +02:00
|
|
|
use App\Models\TipologiaDocumento;
|
2026-05-26 12:28:39 +02:00
|
|
|
use App\Models\TipologiaEvento;
|
2026-05-28 13:25:47 +02:00
|
|
|
use Illuminate\Http\RedirectResponse;
|
2026-05-26 08:14:29 +02:00
|
|
|
use Illuminate\Http\Request;
|
2026-05-28 13:25:47 +02:00
|
|
|
use Illuminate\Support\Facades\Crypt;
|
2026-05-28 09:34:28 +02:00
|
|
|
use Illuminate\Support\Facades\Log;
|
2026-05-26 08:14:29 +02:00
|
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
|
|
|
|
|
|
class ImpostazioniController extends Controller
|
|
|
|
|
{
|
|
|
|
|
public function index()
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$tipologie = TipologiaDocumento::orderBy('ordine')->get();
|
2026-05-26 12:28:39 +02:00
|
|
|
$tipologieEventi = TipologiaEvento::orderBy('ordine')->get();
|
2026-05-26 08:14:29 +02:00
|
|
|
$ruoli = Ruolo::orderBy('ordine')->get();
|
2026-06-09 11:22:56 +02:00
|
|
|
$tags = Tag::orderBy('order_column')->get();
|
2026-05-26 08:14:29 +02:00
|
|
|
$appSettings = AppSetting::first();
|
2026-05-26 14:10:04 +02:00
|
|
|
$emailSettings = EmailSetting::first() ?? new EmailSetting();
|
2026-05-27 08:37:37 +02:00
|
|
|
$senderAccounts = SenderAccount::orderBy('email_address')->get();
|
2026-05-28 09:34:28 +02:00
|
|
|
$repositories = StorageRepository::orderBy('ordine')->get();
|
2026-05-28 13:25:47 +02:00
|
|
|
$googleDriveNewToken = session('google_drive_new_token');
|
2026-06-02 22:07:16 +02:00
|
|
|
$calendarioConnessioni = CalendarioConnessione::orderBy('ordine')->get();
|
2026-05-26 08:14:29 +02:00
|
|
|
|
2026-06-09 11:22:56 +02:00
|
|
|
return view('impostazioni.index', compact('tipologie', 'tipologieEventi', 'ruoli', 'tags', 'appSettings', 'emailSettings', 'senderAccounts', 'repositories', 'googleDriveNewToken', 'calendarioConnessioni'));
|
2026-05-26 08:14:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function saveAppSettings(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'nome_applicazione' => 'nullable|string|max:100',
|
|
|
|
|
'nome_organizzazione' => 'nullable|string|max:255',
|
|
|
|
|
'footer_text' => 'nullable|string|max:255',
|
|
|
|
|
'app_version' => 'nullable|string|max:50',
|
|
|
|
|
'dashboard_welcome' => 'nullable|string|max:1000',
|
|
|
|
|
'show_version' => 'boolean',
|
2026-05-28 09:34:28 +02:00
|
|
|
'documenti_storage_disk' => 'nullable|string|in:local,public',
|
|
|
|
|
'documenti_storage_path' => 'nullable|string|max:255',
|
2026-05-26 08:14:29 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$settings = AppSetting::first() ?? new AppSetting();
|
2026-05-28 09:34:28 +02:00
|
|
|
|
|
|
|
|
$oldDisk = $settings->documenti_storage_disk ?? 'local';
|
|
|
|
|
$oldPath = $settings->documenti_storage_path ?? 'documenti';
|
2026-05-26 08:14:29 +02:00
|
|
|
|
2026-05-28 09:34:28 +02:00
|
|
|
$settings->nome_applicazione = $validated['nome_applicazione'] ?? $settings->nome_applicazione ?? '';
|
|
|
|
|
$settings->nome_organizzazione = $validated['nome_organizzazione'] ?? $settings->nome_organizzazione ?? '';
|
|
|
|
|
$settings->footer_text = $validated['footer_text'] ?? $settings->footer_text ?? '';
|
|
|
|
|
$settings->app_version = $validated['app_version'] ?? $settings->app_version ?? '';
|
|
|
|
|
$settings->dashboard_welcome = $validated['dashboard_welcome'] ?? $settings->dashboard_welcome ?? null;
|
2026-05-26 08:14:29 +02:00
|
|
|
$settings->show_version = $request->boolean('show_version');
|
2026-05-28 09:34:28 +02:00
|
|
|
$settings->documenti_storage_disk = $validated['documenti_storage_disk'] ?? $settings->documenti_storage_disk ?? 'local';
|
|
|
|
|
$settings->documenti_storage_path = $validated['documenti_storage_path'] ?? $settings->documenti_storage_path ?? 'documenti';
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$settings->save();
|
|
|
|
|
|
2026-05-28 09:34:28 +02:00
|
|
|
$newDisk = $settings->documenti_storage_disk;
|
|
|
|
|
$newPath = $settings->documenti_storage_path;
|
|
|
|
|
|
|
|
|
|
$pathChanged = $oldDisk !== $newDisk || $oldPath !== $newPath;
|
|
|
|
|
|
|
|
|
|
if ($pathChanged) {
|
|
|
|
|
try {
|
|
|
|
|
Storage::disk($newDisk)->makeDirectory($newPath);
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
Log::error('Creazione directory documenti fallita: ' . $e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$fileCount = Documento::whereNull('repository_id')->count();
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#documenti')
|
|
|
|
|
->with('success', 'Percorso di archiviazione aggiornato. La nuova directory è stata creata.')
|
|
|
|
|
->with('path_changed', true)
|
|
|
|
|
->with('old_storage_disk', $oldDisk)
|
|
|
|
|
->with('old_storage_path', $oldPath)
|
|
|
|
|
->with('new_storage_disk', $newDisk)
|
|
|
|
|
->with('new_storage_path', $newPath)
|
|
|
|
|
->with('migration_count', $fileCount);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 08:14:29 +02:00
|
|
|
return redirect('/impostazioni#applicazione')->with('success', 'Impostazioni applicazione salvate.');
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-28 09:34:28 +02:00
|
|
|
public function migrateStoragePath(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeWrite('settings');
|
|
|
|
|
|
|
|
|
|
$oldDisk = $request->input('old_storage_disk', 'local');
|
|
|
|
|
$oldPath = $request->input('old_storage_path', 'documenti');
|
|
|
|
|
$newDisk = $request->input('new_storage_disk', 'local');
|
|
|
|
|
$newPath = $request->input('new_storage_path', 'documenti');
|
|
|
|
|
|
|
|
|
|
$documents = Documento::whereNull('repository_id')->get();
|
|
|
|
|
$moved = 0;
|
|
|
|
|
$errors = [];
|
|
|
|
|
|
|
|
|
|
foreach ($documents as $doc) {
|
|
|
|
|
$oldFilePath = $doc->file_path;
|
|
|
|
|
$relativePath = $oldFilePath;
|
|
|
|
|
|
|
|
|
|
if (str_starts_with($relativePath, $oldPath . '/') || $relativePath === $oldPath) {
|
|
|
|
|
$relativePath = substr($relativePath, strlen($oldPath));
|
|
|
|
|
$relativePath = ltrim($relativePath, '/');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$newFilePath = $newPath . ($relativePath ? '/' . $relativePath : '');
|
|
|
|
|
|
|
|
|
|
if ($newFilePath === $oldFilePath && $oldDisk === $newDisk) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (!Storage::disk($oldDisk)->exists($oldFilePath)) {
|
|
|
|
|
$errors[] = "File non trovato: {$oldFilePath}";
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Storage::disk($newDisk)->writeStream(
|
|
|
|
|
$newFilePath,
|
|
|
|
|
Storage::disk($oldDisk)->readStream($oldFilePath)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$doc->update([
|
|
|
|
|
'file_path' => $newFilePath,
|
|
|
|
|
'storage_disk' => $newDisk,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
Storage::disk($oldDisk)->delete($oldFilePath);
|
|
|
|
|
|
|
|
|
|
$moved++;
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$errors[] = "Errore su {$oldFilePath}: " . $e->getMessage();
|
|
|
|
|
Log::error('Migrazione file fallita: ' . $e->getMessage(), [
|
|
|
|
|
'doc_id' => $doc->id,
|
|
|
|
|
'old' => $oldFilePath,
|
|
|
|
|
'new' => $newFilePath,
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$message = "Migrazione completata: {$moved} file spostati.";
|
|
|
|
|
if (count($errors) > 0) {
|
|
|
|
|
$message .= ' ' . count($errors) . ' errori. Controlla i log per i dettagli.';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#documenti')
|
|
|
|
|
->with('success', $message)
|
|
|
|
|
->with('migration_errors', count($errors) > 0 ? $errors : null);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 08:14:29 +02:00
|
|
|
public function tipologieStore(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'nome' => 'required|string|max:50|unique:tipologie_documenti,nome',
|
|
|
|
|
'descrizione' => 'nullable|string|max:255',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$maxOrdine = TipologiaDocumento::max('ordine') ?? 0;
|
|
|
|
|
|
|
|
|
|
TipologiaDocumento::create([
|
|
|
|
|
'nome' => $validated['nome'],
|
|
|
|
|
'descrizione' => $validated['descrizione'] ?? null,
|
|
|
|
|
'ordine' => $maxOrdine + 1,
|
|
|
|
|
'attiva' => true,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tipologie')->with('success', 'Tipologia aggiunta.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tipologieUpdate(Request $request, $id)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$tipologia = TipologiaDocumento::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'nome' => 'required|string|max:50|unique:tipologie_documenti,nome,' . $id,
|
|
|
|
|
'descrizione' => 'nullable|string|max:255',
|
|
|
|
|
'attiva' => 'boolean',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$tipologia->update($validated);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tipologie')->with('success', 'Tipologia aggiornata.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tipologieDestroy($id)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeDelete('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
$tipologia = TipologiaDocumento::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$count = $tipologia->documenti()->count();
|
|
|
|
|
if ($count > 0) {
|
|
|
|
|
return redirect('/impostazioni#tipologie')->with('error', 'Impossibile eliminare: ' . $count . ' documenti associati.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$tipologia->delete();
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tipologie')->with('success', 'Tipologia eliminata.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tipologieReorder(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$order = $request->input('order', []);
|
|
|
|
|
|
|
|
|
|
foreach ($order as $index => $id) {
|
|
|
|
|
TipologiaDocumento::where('id', $id)->update(['ordine' => $index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response()->json(['success' => true]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function ruoliStore(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'nome' => 'required|string|max:50|unique:ruoli,nome',
|
|
|
|
|
'descrizione' => 'nullable|string|max:255',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$maxOrdine = Ruolo::max('ordine') ?? 0;
|
|
|
|
|
|
|
|
|
|
Ruolo::create([
|
|
|
|
|
'nome' => $validated['nome'],
|
|
|
|
|
'descrizione' => $validated['descrizione'] ?? null,
|
|
|
|
|
'ordine' => $maxOrdine + 1,
|
|
|
|
|
'attiva' => true,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#ruoli')->with('success', 'Ruolo aggiunto.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function ruoliUpdate(Request $request, $id)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$ruolo = Ruolo::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'nome' => 'required|string|max:50|unique:ruoli,nome,' . $id,
|
|
|
|
|
'descrizione' => 'nullable|string|max:255',
|
|
|
|
|
'attiva' => 'boolean',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$ruolo->update($validated);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#ruoli')->with('success', 'Ruolo aggiornato.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function ruoliDestroy($id)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeDelete('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$ruolo = Ruolo::findOrFail($id);
|
|
|
|
|
|
2026-06-02 20:29:47 +02:00
|
|
|
$allRows = \DB::table('gruppo_individuo')
|
2026-05-26 08:14:29 +02:00
|
|
|
->whereNotNull('ruolo_ids')
|
2026-06-02 20:29:47 +02:00
|
|
|
->get(['id', 'ruolo_ids']);
|
|
|
|
|
|
|
|
|
|
$count = 0;
|
|
|
|
|
foreach ($allRows as $row) {
|
|
|
|
|
$ids = json_decode($row->ruolo_ids, true);
|
|
|
|
|
if (is_array($ids) && in_array((int) $id, $ids)) {
|
|
|
|
|
$count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
if ($count > 0) {
|
|
|
|
|
return redirect('/impostazioni#ruoli')->with('error', 'Impossibile eliminare: ' . $count . ' membri associati a questo ruolo.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$ruolo->delete();
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#ruoli')->with('success', 'Ruolo eliminato.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function ruoliReorder(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$order = $request->input('order', []);
|
|
|
|
|
|
|
|
|
|
foreach ($order as $index => $id) {
|
|
|
|
|
Ruolo::where('id', $id)->update(['ordine' => $index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response()->json(['success' => true]);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 12:28:39 +02:00
|
|
|
public function tipologieEventiStore(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 12:28:39 +02:00
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'nome' => 'required|string|max:50|unique:tipologie_eventi,nome',
|
|
|
|
|
'descrizione' => 'nullable|string|max:255',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$maxOrdine = TipologiaEvento::max('ordine') ?? 0;
|
|
|
|
|
|
|
|
|
|
TipologiaEvento::create([
|
|
|
|
|
'nome' => $validated['nome'],
|
|
|
|
|
'descrizione' => $validated['descrizione'] ?? null,
|
|
|
|
|
'ordine' => $maxOrdine + 1,
|
|
|
|
|
'attiva' => true,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tipologie-eventi')->with('success', 'Tipologia evento aggiunta.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tipologieEventiUpdate(Request $request, $id)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 12:28:39 +02:00
|
|
|
|
|
|
|
|
$tipologia = TipologiaEvento::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'nome' => 'required|string|max:50|unique:tipologie_eventi,nome,' . $id,
|
|
|
|
|
'descrizione' => 'nullable|string|max:255',
|
|
|
|
|
'attiva' => 'boolean',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$tipologia->update($validated);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tipologie-eventi')->with('success', 'Tipologia evento aggiornata.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tipologieEventiDestroy($id)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeDelete('settings');
|
2026-05-26 12:28:39 +02:00
|
|
|
$tipologia = TipologiaEvento::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$count = $tipologia->eventi()->count();
|
|
|
|
|
if ($count > 0) {
|
|
|
|
|
return redirect('/impostazioni#tipologie-eventi')->with('error', 'Impossibile eliminare: ' . $count . ' eventi associati.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$tipologia->delete();
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tipologie-eventi')->with('success', 'Tipologia evento eliminata.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tipologieEventiReorder(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 12:28:39 +02:00
|
|
|
|
|
|
|
|
$order = $request->input('order', []);
|
|
|
|
|
|
|
|
|
|
foreach ($order as $index => $id) {
|
|
|
|
|
TipologiaEvento::where('id', $id)->update(['ordine' => $index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response()->json(['success' => true]);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-09 11:22:56 +02:00
|
|
|
public function tagStore(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeWrite('settings');
|
|
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'name' => 'required|string|max:100|unique:tags,name',
|
|
|
|
|
'color' => 'nullable|string|max:7',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$maxOrdine = Tag::max('order_column') ?? 0;
|
|
|
|
|
|
|
|
|
|
Tag::create([
|
|
|
|
|
'name' => $validated['name'],
|
|
|
|
|
'slug' => str()->slug($validated['name']),
|
|
|
|
|
'color' => $validated['color'] ?? null,
|
|
|
|
|
'order_column' => $maxOrdine + 1,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tag')->with('success', 'Tag aggiunto.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tagUpdate(Request $request, $id)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeWrite('settings');
|
|
|
|
|
|
|
|
|
|
$tag = Tag::findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
|
|
'name' => 'required|string|max:100|unique:tags,name,' . $id,
|
|
|
|
|
'color' => 'nullable|string|max:7',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$tag->update([
|
|
|
|
|
'name' => $validated['name'],
|
|
|
|
|
'slug' => str()->slug($validated['name']),
|
|
|
|
|
'color' => $validated['color'] ?? null,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tag')->with('success', 'Tag aggiornato.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tagDestroy($id)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeDelete('settings');
|
|
|
|
|
|
|
|
|
|
$tag = Tag::findOrFail($id);
|
|
|
|
|
$tag->delete();
|
|
|
|
|
|
|
|
|
|
return redirect('/impostazioni#tag')->with('success', 'Tag eliminato.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tagReorder(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$this->authorizeWrite('settings');
|
|
|
|
|
|
|
|
|
|
$order = $request->input('order', []);
|
|
|
|
|
|
|
|
|
|
foreach ($order as $index => $id) {
|
|
|
|
|
Tag::where('id', $id)->update(['order_column' => $index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response()->json(['success' => true]);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 08:14:29 +02:00
|
|
|
public function uploadLogo(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$request->validate([
|
|
|
|
|
'logo' => 'nullable|image|mimes:png,jpg,jpeg,gif,svg|max:2048',
|
|
|
|
|
'logo_small' => 'nullable|image|mimes:png,jpg,jpeg,gif,svg|max:512',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$settings = AppSetting::first() ?? new AppSetting();
|
|
|
|
|
|
|
|
|
|
if ($request->hasFile('logo')) {
|
|
|
|
|
$path = $request->file('logo')->store('logos', 'public');
|
|
|
|
|
$settings->logo_path = $path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($request->hasFile('logo_small')) {
|
|
|
|
|
$path = $request->file('logo_small')->store('logos', 'public');
|
|
|
|
|
$settings->logo_small_path = $path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($settings->id) {
|
|
|
|
|
$settings->save();
|
|
|
|
|
} else {
|
|
|
|
|
$settings->save();
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-08 20:10:33 +02:00
|
|
|
$linkPath = public_path('storage');
|
|
|
|
|
if (!file_exists($linkPath) && !is_link($linkPath)) {
|
|
|
|
|
try {
|
|
|
|
|
symlink(storage_path('app/public'), $linkPath);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
Log::warning('Impossibile creare symlink storage: ' . $e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 08:14:29 +02:00
|
|
|
return redirect('/impostazioni#logo')->with('success', 'Logo caricato con successo.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function removeLogo(Request $request)
|
|
|
|
|
{
|
2026-05-26 14:10:04 +02:00
|
|
|
$this->authorizeWrite('settings');
|
2026-05-26 08:14:29 +02:00
|
|
|
|
|
|
|
|
$type = $request->input('type');
|
|
|
|
|
|
|
|
|
|
$settings = AppSetting::first();
|
|
|
|
|
|
|
|
|
|
if ($settings) {
|
|
|
|
|
if ($type === 'logo') {
|
|
|
|
|
if ($settings->logo_path) {
|
|
|
|
|
Storage::disk('public')->delete($settings->logo_path);
|
|
|
|
|
$settings->logo_path = null;
|
|
|
|
|
}
|
|
|
|
|
} elseif ($type === 'logo_small') {
|
|
|
|
|
if ($settings->logo_small_path) {
|
|
|
|
|
Storage::disk('public')->delete($settings->logo_small_path);
|
|
|
|
|
$settings->logo_small_path = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$settings->save();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response()->json(['success' => true]);
|
|
|
|
|
}
|
|
|
|
|
}
|