netgescon-master/app/Debug/Commands/SystemDebug.php

297 lines
11 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Route;
class SystemDebug extends Command
{
protected $signature = 'netgescon:debug
{--scan : Scansiona tutto il sistema}
{--duplicates : Trova solo duplicati}
{--routes : Verifica route e view}
{--models : Controlla relationship dei model}
{--clean : Pulisce duplicati automaticamente}
{--report : Genera report completo}';
protected $description = 'Sistema di debug avanzato NetGescon per gestione duplicati, view, route e model';
protected $issues = [];
protected $duplicates = [];
protected $missingViews = [];
protected $brokenRelationships = [];
public function handle()
{
$this->info("🔍 NetGescon System Debug v1.0");
$this->info("=====================================\n");
if ($this->option('scan') || !$this->hasOptions()) {
$this->scanAll();
}
if ($this->option('duplicates')) {
$this->findDuplicates();
}
if ($this->option('routes')) {
$this->verifyRoutes();
}
if ($this->option('models')) {
$this->checkModels();
}
if ($this->option('clean')) {
$this->cleanDuplicates();
}
if ($this->option('report')) {
$this->generateReport();
}
$this->showSummary();
}
protected function scanAll()
{
$this->info("📊 Scansione completa del sistema...");
$this->findDuplicates();
$this->verifyRoutes();
$this->checkModels();
$this->info("✅ Scansione completata!\n");
}
protected function findDuplicates()
{
$this->info("🔍 Ricerca duplicati...");
$directories = [
'resources/views',
'_DUPLICATES_MOVED/resources/views',
'_BACKUP_OLD_netgescon-laravel_INACTIVE/resources/views',
'_BACKUP_OLD_netgescon_INACTIVE/vendor/laravel/breeze/stubs'
];
$viewFiles = [];
$duplicates = [];
foreach ($directories as $dir) {
if (!File::exists(base_path($dir))) continue;
$files = File::allFiles(base_path($dir));
foreach ($files as $file) {
if ($file->getExtension() === 'php') {
$relativePath = str_replace(base_path($dir) . '/', '', $file->getPathname());
$filename = $file->getFilename();
if (!isset($viewFiles[$filename])) {
$viewFiles[$filename] = [];
}
$viewFiles[$filename][] = [
'path' => $file->getPathname(),
'directory' => $dir,
'size' => $file->getSize(),
'modified' => $file->getMTime()
];
}
}
}
foreach ($viewFiles as $filename => $files) {
if (count($files) > 1) {
$this->duplicates[$filename] = $files;
$this->warn("⚠️ {$filename}: " . count($files) . " copie trovate");
}
}
$this->info("📈 Trovati " . count($this->duplicates) . " file duplicati\n");
}
protected function verifyRoutes()
{
$this->info("🛤️ Verifica route e view...");
$routes = Route::getRoutes();
$missingViews = [];
foreach ($routes as $route) {
$action = $route->getAction();
if (isset($action['controller'])) {
$controller = $action['controller'];
$controllerPath = base_path('app/Http/Controllers/' . str_replace('App\\Http\\Controllers\\', '', explode('@', $controller)[0]) . '.php');
if (File::exists($controllerPath)) {
$content = File::get($controllerPath);
preg_match_all('/view\([\'"]([^\'"]+)[\'"]\)/', $content, $matches);
foreach ($matches[1] as $viewName) {
$viewPath = resource_path('views/' . str_replace('.', '/', $viewName) . '.blade.php');
if (!File::exists($viewPath)) {
$missingViews[] = [
'view' => $viewName,
'controller' => $controller,
'route' => $route->uri()
];
}
}
}
}
}
foreach ($missingViews as $missing) {
$this->error("❌ View [{$missing['view']}] mancante per route {$missing['route']}");
}
$this->missingViews = $missingViews;
$this->info("📈 Trovate " . count($missingViews) . " view mancanti\n");
}
protected function checkModels()
{
$this->info("🔗 Controllo relationship dei model...");
$modelPath = app_path('Models');
$models = File::allFiles($modelPath);
$brokenRelationships = [];
foreach ($models as $model) {
$className = 'App\\Models\\' . $model->getFilenameWithoutExtension();
if (class_exists($className)) {
$content = File::get($model->getPathname());
// Cerca relationship methods
preg_match_all('/public function (\w+)\(\).*?return \$this->(\w+)\(([^)]+)\)/', $content, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$relationMethod = $match[1];
$relationType = $match[2];
$relatedModel = trim($match[3], '"\'');
// Controlla se il model correlato esiste
if (strpos($relatedModel, '::class') === false) {
$relatedClassName = 'App\\Models\\' . $relatedModel;
if (!class_exists($relatedClassName)) {
$brokenRelationships[] = [
'model' => $className,
'method' => $relationMethod,
'type' => $relationType,
'related' => $relatedModel,
'issue' => 'Model non trovato'
];
}
}
}
}
}
foreach ($brokenRelationships as $broken) {
$this->error("💔 {$broken['model']}::{$broken['method']}() -> {$broken['issue']}");
}
$this->brokenRelationships = $brokenRelationships;
$this->info("📈 Trovati " . count($brokenRelationships) . " relationship problematici\n");
}
protected function cleanDuplicates()
{
$this->info("🧹 Pulizia automatica duplicati...");
if (empty($this->duplicates)) {
$this->findDuplicates();
}
$cleaned = 0;
foreach ($this->duplicates as $filename => $files) {
// Mantieni solo il file più recente dalla directory resources/views
$activeFile = null;
$toMove = [];
foreach ($files as $file) {
if (strpos($file['directory'], 'resources/views') === 0 && strpos($file['directory'], '_DUPLICATES_') === false) {
if (!$activeFile || $file['modified'] > $activeFile['modified']) {
if ($activeFile) $toMove[] = $activeFile;
$activeFile = $file;
} else {
$toMove[] = $file;
}
} else {
$toMove[] = $file;
}
}
foreach ($toMove as $file) {
$destination = base_path('_DUPLICATES_MOVED/' . str_replace(base_path(), '', $file['path']));
$destinationDir = dirname($destination);
if (!File::exists($destinationDir)) {
File::makeDirectory($destinationDir, 0755, true);
}
if (File::move($file['path'], $destination)) {
$cleaned++;
$this->line("📦 Spostato: {$filename}");
}
}
}
$this->info("✅ Puliti {$cleaned} file duplicati\n");
}
protected function generateReport()
{
$this->info("📋 Generazione report completo...");
$report = [
'timestamp' => now()->format('Y-m-d H:i:s'),
'system_status' => [
'duplicates_found' => count($this->duplicates),
'missing_views' => count($this->missingViews),
'broken_relationships' => count($this->brokenRelationships)
],
'details' => [
'duplicates' => $this->duplicates,
'missing_views' => $this->missingViews,
'broken_relationships' => $this->brokenRelationships
]
];
$reportPath = storage_path('logs/netgescon_debug_' . date('Y-m-d_H-i-s') . '.json');
File::put($reportPath, json_encode($report, JSON_PRETTY_PRINT));
$this->info("📄 Report salvato: {$reportPath}\n");
}
protected function showSummary()
{
$this->info("📊 RIEPILOGO SISTEMA");
$this->info("====================");
$this->table(
['Categoria', 'Problemi Trovati', 'Stato'],
[
['File Duplicati', count($this->duplicates), count($this->duplicates) > 0 ? '⚠️ Da gestire' : '✅ OK'],
['View Mancanti', count($this->missingViews), count($this->missingViews) > 0 ? '❌ Errori' : '✅ OK'],
['Relationship', count($this->brokenRelationships), count($this->brokenRelationships) > 0 ? '💔 Problemi' : '✅ OK']
]
);
if (count($this->duplicates) > 0 || count($this->missingViews) > 0 || count($this->brokenRelationships) > 0) {
$this->warn("\n💡 Usa --clean per pulizia automatica o --report per report dettagliato");
} else {
$this->info("\n🎉 Sistema pulito e funzionante!");
}
}
protected function hasOptions()
{
return $this->option('scan') || $this->option('duplicates') ||
$this->option('routes') || $this->option('models') ||
$this->option('clean') || $this->option('report');
}
}