diff --git a/app/Config/Events.php b/app/Config/Events.php index 0c0ef5b44..26fe93841 100644 --- a/app/Config/Events.php +++ b/app/Config/Events.php @@ -8,7 +8,6 @@ use CodeIgniter\HotReloader\HotReloader; use App\Events\Db_log; use App\Events\Load_config; use App\Events\Method; -use App\Libraries\Plugins\PluginManager; /* * -------------------------------------------------------------------- @@ -57,14 +56,7 @@ Events::on('pre_system', static function (): void { }); Events::on('post_controller_constructor', static function (): void { - $pluginManager = new PluginManager(); - - if ($pluginManager->canLoadPlugins()) { - $pluginManager->discoverPlugins(); - $pluginManager->registerPluginEvents(); - } else { - log_message('debug', 'Plugin loading is disabled until after migration has been run.'); - } + service('pluginManager'); }, 10); $config = new Load_config(); diff --git a/app/Config/Services.php b/app/Config/Services.php index fb4d7bc89..dd06674aa 100644 --- a/app/Config/Services.php +++ b/app/Config/Services.php @@ -3,6 +3,7 @@ namespace Config; use App\Libraries\MY_Language; +use App\Libraries\Plugins\PluginManager; use Locale; use HTMLPurifier; use HTMLPurifier_Config; @@ -61,6 +62,24 @@ class Services extends BaseService return new MY_Language($locale); } + public static function pluginManager(bool $getShared = true): PluginManager + { + if ($getShared) { + return static::getSharedInstance('pluginManager'); + } + + $manager = new PluginManager(); + + if ($manager->canLoadPlugins()) { + $manager->discoverPlugins(); + $manager->registerPluginEvents(); + } else { + log_message('debug', 'PluginManager: skipping init, plugin_config table not found.'); + } + + return $manager; + } + private static HTMLPurifier $htmlPurifier; public static function htmlPurifier($getShared = true): object diff --git a/app/Controllers/Plugins.php b/app/Controllers/Plugins.php index ce133351e..4c7d485f2 100644 --- a/app/Controllers/Plugins.php +++ b/app/Controllers/Plugins.php @@ -12,8 +12,7 @@ class Plugins extends Secure_Controller public function __construct() { parent::__construct('plugins'); - $this->pluginManager = new PluginManager(); - $this->pluginManager->discoverPlugins(); + $this->pluginManager = service('pluginManager'); } public function getIndex(): string diff --git a/app/Libraries/Plugins/BasePlugin.php b/app/Libraries/Plugins/BasePlugin.php index b4c9b097d..c9290dd28 100644 --- a/app/Libraries/Plugins/BasePlugin.php +++ b/app/Libraries/Plugins/BasePlugin.php @@ -25,7 +25,7 @@ abstract class BasePlugin implements PluginInterface public function isEnabled(): bool { - $enabled = $this->configModel->getValue("{$this->getPluginId()}_enabled"); + $enabled = $this->configModel->getValue("{$this->getPluginId()}__enabled"); return $enabled === '1' || $enabled === 'true'; } diff --git a/app/Libraries/Plugins/PluginManager.php b/app/Libraries/Plugins/PluginManager.php index b4cac009a..9fa4a2492 100644 --- a/app/Libraries/Plugins/PluginManager.php +++ b/app/Libraries/Plugins/PluginManager.php @@ -16,6 +16,8 @@ class PluginManager private PluginConfig $configModel; private string $pluginsPath; private bool $eventsRegistered = false; + private static bool $discovered = false; + private static array $registeredNamespaces = []; public function __construct() { @@ -25,6 +27,11 @@ class PluginManager public function discoverPlugins(): void { + if (self::$discovered) { + log_message('debug', 'Plugin discovery already completed, skipping'); + return; + } + if (!is_dir($this->pluginsPath)) { log_message('debug', 'Plugins directory does not exist: ' . $this->pluginsPath); return; @@ -59,15 +66,14 @@ class PluginManager $this->plugins[$plugin->getPluginId()] = $plugin; if ($this->isPluginEnabled($plugin->getPluginId())) { - $loader = Services::autoloader(); - $loader->addNamespace( - "App\\Plugins\\{$plugin->getPluginId()}", - APPPATH . "Plugins/{$plugin->getPluginId()}" - ); + $this->registerNamespace($plugin->getPluginId()); } log_message('debug', "Discovered plugin: {$plugin->getPluginName()}"); } + + self::$discovered = true; + log_message('debug', 'Plugin discovery completed'); } private function getClassNameFromFile(string $pathname): ?string @@ -141,11 +147,7 @@ class PluginManager $this->configModel->setValue($this->getEnabledKey($pluginId), '1'); - $loader = Services::autoloader(); - $loader->addNamespace( - "App\\Plugins\\{$pluginId}", - APPPATH . "Plugins/{$pluginId}" - ); + $this->registerNamespace($pluginId); log_message('info', "Plugin enabled: {$pluginId}"); @@ -193,6 +195,24 @@ class PluginManager return $this->configModel->setValue("{$pluginId}_{$key}", $value); } + public static function resetStatic(): void + { + self::$discovered = false; + self::$registeredNamespaces = []; + } + + private function registerNamespace(string $pluginId): void + { + $namespace = "App\\Plugins\\{$pluginId}"; + + if (!in_array($namespace, self::$registeredNamespaces, true)) { + $loader = Services::autoloader(); + $loader->addNamespace($namespace, APPPATH . "Plugins/{$pluginId}"); + self::$registeredNamespaces[] = $namespace; + log_message('debug', "Registered namespace for plugin: {$pluginId}"); + } + } + private function getEnabledKey(string $pluginId): string { return "{$pluginId}__enabled"; diff --git a/app/Plugins/MailchimpPlugin/MailchimpPlugin.php b/app/Plugins/MailchimpPlugin/MailchimpPlugin.php index 298747ceb..f103f8191 100644 --- a/app/Plugins/MailchimpPlugin/MailchimpPlugin.php +++ b/app/Plugins/MailchimpPlugin/MailchimpPlugin.php @@ -60,7 +60,6 @@ class MailchimpPlugin extends BasePlugin $this->setSetting('api_key', ''); $this->setSetting('list_id', ''); $this->setSetting('sync_on_save', '1'); - $this->setSetting('enabled', '0'); return true; } diff --git a/app/Views/plugins/manage.php b/app/Views/plugins/manage.php index f4928ce04..130bf73d0 100644 --- a/app/Views/plugins/manage.php +++ b/app/Views/plugins/manage.php @@ -55,7 +55,7 @@ - +