. // }}} /** * 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); } } } }