123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <?php
- /**
- * Class PluginManager
- *
- * Use to manage, load and execute plugins.
- *
- * Using Singleton design pattern.
- */
- class PluginManager
- {
- /**
- * PluginManager singleton instance.
- * @var PluginManager $instance
- */
- private static $instance;
- /**
- * List of authorized plugins from configuration file.
- * @var array $authorizedPlugins
- */
- private $authorizedPlugins;
- /**
- * List of loaded plugins.
- * @var array $loadedPlugins
- */
- private $loadedPlugins = array();
- /**
- * Plugins subdirectory.
- * @var string $PLUGINS_PATH
- */
- public static $PLUGINS_PATH = 'plugins';
- /**
- * Private constructor: new instances not allowed.
- */
- private function __construct()
- {
- }
- /**
- * Cloning isn't allowed either.
- *
- * @return void
- */
- private function __clone()
- {
- }
- /**
- * Return existing instance of PluginManager, or create it.
- *
- * @return PluginManager instance.
- */
- public static function getInstance()
- {
- if (!(self::$instance instanceof self)) {
- self::$instance = new self();
- }
- return self::$instance;
- }
- /**
- * Load plugins listed in $authorizedPlugins.
- *
- * @param array $authorizedPlugins Names of plugin authorized to be loaded.
- *
- * @return void
- */
- public function load($authorizedPlugins)
- {
- $this->authorizedPlugins = $authorizedPlugins;
- $dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR);
- $dirnames = array_map('basename', $dirs);
- foreach ($this->authorizedPlugins as $plugin) {
- $index = array_search($plugin, $dirnames);
- // plugin authorized, but its folder isn't listed
- if ($index === false) {
- continue;
- }
- try {
- $this->loadPlugin($dirs[$index], $plugin);
- }
- catch (PluginFileNotFoundException $e) {
- error_log($e->getMessage());
- }
- }
- }
- /**
- * Execute all plugins registered hook.
- *
- * @param string $hook name of the hook to trigger.
- * @param array $data list of data to manipulate passed by reference.
- * @param array $params additional parameters such as page target.
- *
- * @return void
- */
- public function executeHooks($hook, &$data, $params = array())
- {
- if (!empty($params['target'])) {
- $data['_PAGE_'] = $params['target'];
- }
- if (isset($params['loggedin'])) {
- $data['_LOGGEDIN_'] = $params['loggedin'];
- }
- foreach ($this->loadedPlugins as $plugin) {
- $hookFunction = $this->buildHookName($hook, $plugin);
- if (function_exists($hookFunction)) {
- $data = call_user_func($hookFunction, $data);
- }
- }
- }
- /**
- * Load a single plugin from its files.
- * Add them in $loadedPlugins if successful.
- *
- * @param string $dir plugin's directory.
- * @param string $pluginName plugin's name.
- *
- * @return void
- * @throws PluginFileNotFoundException - plugin files not found.
- */
- private function loadPlugin($dir, $pluginName)
- {
- if (!is_dir($dir)) {
- throw new PluginFileNotFoundException($pluginName);
- }
- $pluginFilePath = $dir . '/' . $pluginName . '.php';
- if (!is_file($pluginFilePath)) {
- throw new PluginFileNotFoundException($pluginName);
- }
- include_once $pluginFilePath;
- $this->loadedPlugins[] = $pluginName;
- }
- /**
- * Construct normalize hook name for a specific plugin.
- *
- * Format:
- * hook_<plugin_name>_<hook_name>
- *
- * @param string $hook hook name.
- * @param string $pluginName plugin name.
- *
- * @return string - plugin's hook name.
- */
- public function buildHookName($hook, $pluginName)
- {
- return 'hook_' . $pluginName . '_' . $hook;
- }
- }
- /**
- * Class PluginFileNotFoundException
- *
- * Raise when plugin files can't be found.
- */
- class PluginFileNotFoundException extends Exception
- {
- /**
- * Construct exception with plugin name.
- * Generate message.
- *
- * @param string $pluginName name of the plugin not found
- */
- public function __construct($pluginName)
- {
- $this->message = 'Plugin "'. $pluginName .'" files not found.';
- }
- }
|