From 2437239337774c56fc0f011ae1a83f99c34bf3b4 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 4 Dec 2024 11:21:05 -0500 Subject: [PATCH 1/6] helper class to find models --- modules/system/helpers/ModelFinder.php | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 modules/system/helpers/ModelFinder.php diff --git a/modules/system/helpers/ModelFinder.php b/modules/system/helpers/ModelFinder.php new file mode 100644 index 0000000000..51f05a5efd --- /dev/null +++ b/modules/system/helpers/ModelFinder.php @@ -0,0 +1,57 @@ +flatten()->all(); + } + + public static function findCoreModels(): array + { + $modulesPath = base_path() . '/modules'; + + $models = collect(Finder::create()->in($modulesPath)->notPath('/tests/')->files()->name('/^[A-Z]{1}.+\.php$/')) + ->map(function ($model) use ($modulesPath) { + $modelPath = str_replace(['/', '.php'], ['\\', ''], Str::after($model->getRealPath(), realpath($modulesPath).DIRECTORY_SEPARATOR)); + return ucwords($modelPath, '\\'); + }); + + return $models->values()->all(); + } + + public static function findActivePluginsModels(): array + { + $models = []; + $pm = \System\Classes\PluginManager::instance(); + + $pluginsPaths = collect($pm->getPlugins())->map(function ($plugin) use ($pm) { + return $pm->getPluginPath($plugin); + })->filter(function ($path) { + return File::exists($path . '/models'); + })->each(function ($path) use (&$models) { + $modelPaths = Finder::create()->in($path . '/models')->files()->name('/^[A-Z]{1}.+\.php$/'); + $models[] = collect($modelPaths)->map(function ($model) { + $modelPath = str_replace(['/', '.php'], ['\\', ''], Str::after($model->getRealPath(), plugins_path().DIRECTORY_SEPARATOR)); + return ucwords($modelPath, '\\'); + })->all(); + }); + + return collect($models)->flatten()->all(); + } +} From 51b197d5cf907db0842a205e7b52b4335ca99172 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 4 Dec 2024 11:21:32 -0500 Subject: [PATCH 2/6] override Laravel PruneCommand --- modules/system/console/PruneCommand.php | 77 +++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 modules/system/console/PruneCommand.php diff --git a/modules/system/console/PruneCommand.php b/modules/system/console/PruneCommand.php new file mode 100644 index 0000000000..ebc511bebf --- /dev/null +++ b/modules/system/console/PruneCommand.php @@ -0,0 +1,77 @@ +option('model'))) { + return collect($models)->filter(function ($model) { + return class_exists($model); + })->values(); + } + + $except = $this->option('except'); + + return collect($this->findModels()) + ->when(! empty($except), function ($models) use ($except) { + return $models->reject(function ($model) use ($except) { + return in_array($model, $except); + }); + })->filter(function ($model) { + return $this->isPrunable($model); + })->filter(function ($model) { + return class_exists($model); + })->values(); + } + + /** + * {@inheritDoc} + */ + protected function isPrunable($model): bool + { + try { + $uses = class_uses_recursive($model); + } catch (Exception $e) { + return false; + } + + return in_array(Prunable::class, $uses) || in_array(MassPrunable::class, $uses); + } + + /** + * Find all models. + */ + protected function findModels(): array + { + /** + * @event system.console.model.prune.findModels + * Give the opportunity to return an array of Models to prune. + * + * Example usage: + * + * Event::listen('system.console.model.prune.findModels', function () { + * return collect(['example model' => '\System\Models\File']); + * }); + * + */ + $models = Event::fire('system.console.model.prune.findModels', [$this], true); + if (is_array($models)) { + return $models; + } + + return ModelFinder::findModels(); + } +} From 0676dcb474ec9557d76c8b8a1d2656d698c132c9 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 4 Dec 2024 11:21:57 -0500 Subject: [PATCH 3/6] enable model:prune console command --- modules/system/ServiceProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/system/ServiceProvider.php b/modules/system/ServiceProvider.php index 3a8b58f301..da08fe3485 100644 --- a/modules/system/ServiceProvider.php +++ b/modules/system/ServiceProvider.php @@ -301,6 +301,8 @@ protected function registerConsole() $this->registerConsoleCommand('create.settings', \System\Console\CreateSettings::class); $this->registerConsoleCommand('create.test', \System\Console\CreateTest::class); + $this->registerConsoleCommand('model.prune', Console\PruneCommand::class); + $this->registerConsoleCommand('winter.up', \System\Console\WinterUp::class); $this->registerConsoleCommand('winter.down', \System\Console\WinterDown::class); $this->registerConsoleCommand('winter.update', \System\Console\WinterUpdate::class); From 05d5f6f15f933123fea05f28b7b92c51912731e1 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 4 Dec 2024 12:28:18 -0500 Subject: [PATCH 4/6] event example must return array, not collection --- modules/system/console/PruneCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/system/console/PruneCommand.php b/modules/system/console/PruneCommand.php index ebc511bebf..006da99749 100644 --- a/modules/system/console/PruneCommand.php +++ b/modules/system/console/PruneCommand.php @@ -63,7 +63,7 @@ protected function findModels(): array * Example usage: * * Event::listen('system.console.model.prune.findModels', function () { - * return collect(['example model' => '\System\Models\File']); + * return ['example model' => '\System\Models\File']; * }); * */ From b9257368cb104e00945d1a1b7e822949b99f498e Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 4 Dec 2024 16:17:23 -0500 Subject: [PATCH 5/6] combine both filters --- modules/system/console/PruneCommand.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/system/console/PruneCommand.php b/modules/system/console/PruneCommand.php index 006da99749..2454941259 100644 --- a/modules/system/console/PruneCommand.php +++ b/modules/system/console/PruneCommand.php @@ -31,9 +31,7 @@ protected function models(): Collection return in_array($model, $except); }); })->filter(function ($model) { - return $this->isPrunable($model); - })->filter(function ($model) { - return class_exists($model); + return class_exists($model) && $this->isPrunable($model); })->values(); } From 7ee9cd115e6f671a55a367356883a646050a8f82 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 4 Dec 2024 16:19:45 -0500 Subject: [PATCH 6/6] apply review suggestion --- modules/system/helpers/ModelFinder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/system/helpers/ModelFinder.php b/modules/system/helpers/ModelFinder.php index 51f05a5efd..a3643f0f04 100644 --- a/modules/system/helpers/ModelFinder.php +++ b/modules/system/helpers/ModelFinder.php @@ -16,13 +16,13 @@ class ModelFinder public static function findModels(): array { $models = []; - $models[] = static::findCoreModels(); + $models[] = static::findModuleModels(); $models[] = static::findActivePluginsModels(); return collect($models)->flatten()->all(); } - public static function findCoreModels(): array + public static function findModuleModels(): array { $modulesPath = base_path() . '/modules';