From 292c9dc86204a358896f890a6cb3729af8b72477 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Mon, 3 Aug 2020 20:45:00 +0000 Subject: [PATCH] [COMPOSER][MODULE] Add autoloading rules for components and plugins --- composer.json | 3 +- config/bootstrap.php | 5 +- src/Core/ModuleManager.php | 93 +++++++++++++++++++++++++++++++++++++ src/Core/ModulesManager.php | 65 -------------------------- 4 files changed, 99 insertions(+), 67 deletions(-) create mode 100644 src/Core/ModuleManager.php delete mode 100644 src/Core/ModulesManager.php diff --git a/composer.json b/composer.json index 5787491112..0bd22318c5 100644 --- a/composer.json +++ b/composer.json @@ -65,7 +65,8 @@ "files": ["src/Core/I18n/I18n.php"], "psr-4": { "App\\": "src/", - "Plugin\\": "plugins/enabled/" + "Plugin\\": "plugins/", + "Component\\": "components/" } }, "autoload-dev": { diff --git a/config/bootstrap.php b/config/bootstrap.php index cfb95a0c0c..7527f50148 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -1,8 +1,9 @@ =1.2) @@ -21,3 +22,5 @@ $_SERVER += $_ENV; $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; + +ModuleManager::setLoader($loader); diff --git a/src/Core/ModuleManager.php b/src/Core/ModuleManager.php new file mode 100644 index 0000000000..19b775489b --- /dev/null +++ b/src/Core/ModuleManager.php @@ -0,0 +1,93 @@ +. + +// }}} + +/** + * Module and plugin loader code, one of the main features of GNU social + * + * Loads plugins from `plugins/enabled`, instances them + * and hooks its events + * + * @package GNUsocial + * @category Modules + * + * @author Hugo Sales + * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later + */ + +namespace App\Core; + +use App\Util\Formatting; +use Functional as F; + +class ModuleManager +{ + protected static $loader; + public static function setLoader($l) + { + self::$loader = $l; + } + + protected array $modules = []; + protected array $events = []; + + public function add(string $fqcn, string $path) + { + list($type, $module) = preg_split('/\\\\/', $fqcn, 0, PREG_SPLIT_NO_EMPTY); + self::$loader->addPsr4("\\{$type}\\{$module}\\", dirname($path)); + $id = Formatting::camelCaseToSnakeCase($type . '.' . $module); + $obj = new $fqcn(); + $this->modules[$id] = $obj; + } + + public function preRegisterEvents() + { + foreach ($this->modules as $id => $obj) { + F\map(F\select(get_class_methods($obj), + F\ary(F\partial_right('App\Util\Formatting::startsWith', 'on'), 1)), + function (string $m) use ($obj) { + $ev = Formatting::camelCaseToSnakeCase(substr($m, 2)); + $this->events[$ev] = $this->events[$ev] ?? []; + $this->events[$ev][] = [$obj, $m]; + } + ); + } + } + + public static function __set_state($state) + { + $obj = new self(); + $obj->modules = $state['modules']; + $obj->events = $state['events']; + return $obj; + } + + public function loadModules() + { + $f = INSTALLDIR . '/var/cache/module_manager.php'; + $obj = require $f; + foreach ($obj->events as $event => $callables) { + foreach ($callables as $callable) { + Event::addHandler($event, $callable); + } + } + } +} diff --git a/src/Core/ModulesManager.php b/src/Core/ModulesManager.php deleted file mode 100644 index 457d5ea493..0000000000 --- a/src/Core/ModulesManager.php +++ /dev/null @@ -1,65 +0,0 @@ -. -// }}} - -/** - * Module and plugin loader code, one of the main features of GNU social - * - * Loads plugins from `plugins/enabled`, instances them - * and hooks its events - * - * @package GNUsocial - * @category Modules - * - * @author Hugo Sales - * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org - * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later - */ - -namespace App\Core; - -use Functional as F; - -abstract class ModulesManager -{ - public static array $modules = []; - - public static function loadModules() - { - $plugins_paths = glob(INSTALLDIR . '/plugins/*'); - - foreach ($plugins_paths as $plugin_path) { - $class_name = basename($plugin_path); - $fqcn = "Plugin\\{$class_name}\\{$class_name}"; - $file = "{$plugin_path}/{$class_name}.php"; - if (file_exists($file)) { - require_once $file; - $class = new $fqcn; - self::$modules[] = $class; - - // Register event handlers - $methods = get_class_methods($class); - $events = F\select($methods, F\partial_right('App\Util\Formatting::startsWith', 'on')); - F\map($events, - function (string $m) use ($class) { - Event::addHandler(substr($m, 2), [$class, $m]); - }); - } - } - } -}