info('=== Diagnostica Email Settings ==='); $this->newLine(); // 1. APP_KEY $this->section('APP_KEY'); $appKey = config('app.key'); if ($appKey && str_starts_with($appKey, 'base64:')) { $this->line('APP_KEY: presente e valida ✓'); } elseif ($appKey) { $this->warn('APP_KEY: presente ma non in formato base64 (potrebbe funzionare lo stesso)'); } else { $this->error('APP_KEY: NON IMPOSTATA — crittografia password non funzionerà!'); } // 2. Tabella email_settings $this->newLine(); $this->section('Tabella email_settings'); if (Schema::hasTable('email_settings')) { $this->line('Tabella email_settings: esiste ✓'); $columns = Schema::getColumnListing('email_settings'); $this->line('Colonne: ' . implode(', ', $columns)); $required = ['imap_host', 'imap_username', 'imap_password', 'email_address']; $missing = array_diff($required, $columns); if ($missing) { $this->error('Colonne mancanti: ' . implode(', ', $missing)); } else { $this->line('Colonne richieste presenti ✓'); } } else { $this->error('Tabella email_settings NON ESISTE! Esegui: php artisan migrate'); } // 3. Record email_settings $this->newLine(); $this->section('Record email_settings'); $settings = EmailSetting::first(); if ($settings) { $this->line('Record trovato (ID: ' . $settings->id . ')'); $this->line(' imap_host: ' . ($settings->imap_host ?: 'VUOTO')); $this->line(' imap_username: ' . ($settings->imap_username ?: 'VUOTO')); $this->line(' imap_password: ' . ($settings->imap_password ? '[CRITTATO]' : 'VUOTO')); $this->line(' email_address: ' . ($settings->email_address ?: 'VUOTO')); $this->line(' smtp_host: ' . ($settings->smtp_host ?: 'VUOTO')); // Prova decrittazione if ($settings->imap_password) { try { $decrypted = Crypt::decryptString($settings->imap_password); $this->line(' -> password IMAP decrittata: ' . (strlen($decrypted) > 0 ? 'OK (' . strlen($decrypted) . ' caratteri)' : 'VUOTA')); } catch (\Exception $e) { $this->error(' -> ERRORE decrittazione password IMAP: ' . $e->getMessage()); $this->warn(' Causa probabile: APP_KEY diversa da quando è stata salvata.'); } } } else { $this->warn('NESSUN record in email_settings — nessuna configurazione salvata.'); $this->line('Vai su /impostazioni#email-imap, compila e clicca "Salva Impostazioni Email"'); } // 4. Tabella sender_accounts $this->newLine(); $this->section('Tabella sender_accounts'); if (Schema::hasTable('sender_accounts')) { $this->line('Tabella sender_accounts: esiste ✓'); $count = DB::table('sender_accounts')->count(); $this->line('Record presenti: ' . $count); } else { $this->error('Tabella sender_accounts NON ESISTE!'); } // 5. Log recenti $this->newLine(); $this->section('Errori recenti (storage/logs/laravel.log)'); $logPath = storage_path('logs/laravel.log'); if (file_exists($logPath)) { $lines = $this->getLastErrorLines($logPath, 20); if ($lines) { foreach ($lines as $line) { $this->line($line); } } else { $this->line('Nessun errore recente trovato.'); } } else { $this->warn('File di log non trovato: ' . $logPath); } // 6. Estensioni PHP $this->newLine(); $this->section('Estensioni PHP'); $requiredExts = ['openssl', 'json', 'mbstring', 'pdo', 'fileinfo']; foreach ($requiredExts as $ext) { if (extension_loaded($ext)) { $this->line($ext . ': OK ✓'); } else { $this->error($ext . ': MANCANTE!'); } } $this->newLine(); $this->info('=== Diagnostica completata ==='); return self::SUCCESS; } private function section(string $title): void { $this->line("--- {$title} ---"); } private function getLastErrorLines(string $path, int $maxLines): array { $lines = []; $fp = fopen($path, 'r'); if (!$fp) { return $lines; } fseek($fp, -1, SEEK_END); $pos = ftell($fp); $buffer = ''; while ($pos > 0 && count($lines) < $maxLines) { $char = fgetc($fp); if ($char === "\n") { if (trim($buffer) !== '') { $lines[] = trim($buffer); } $buffer = ''; } else { $buffer = $char . $buffer; } $pos--; fseek($fp, $pos); } if (trim($buffer) !== '') { $lines[] = trim($buffer); } fclose($fp); return $lines; } }