/** * Loads state by plugin's name. * * @param string $name Name of the plugin which state should be loaded. * @return State|boolean An instance of state or boolean false on failure. */ public static function loadByName($name) { if (!Utils::isValidPluginName($name)) { return false; } // Load plugin state $info = Database::getInstance()->query('SELECT * FROM {plugin} WHERE name = :name', array(':name' => $name), array('return_rows' => Database::RETURN_ONE_ROW)); // There is no such record in database if (!$info) { return false; } // Create and populate object $state = new self(); $state->populateFromDbFields($info); return $state; }
/** * Retrieves info about plugins available in the system. * * @return array Associative array of plugins info. Each key of the array is * fully qualified plugin's name and each value is an array with the * fillowing keys: * - "version": string, version of the plugin which presents in the system. * - "installed": boolean, indicates if the plugin is installed. * - "enabled": boolean, indicates if the plugin is enabled. */ protected function getPluginsInfo() { if (is_null($this->pluginsInfo)) { $this->pluginsInfo = []; $names = PluginUtils::discoverPlugins(); foreach ($names as $plugin_name) { $info = new PluginInfo($plugin_name); $this->pluginsInfo[$plugin_name] = array('version' => $info->getVersion(), 'installed' => $info->getState()->installed, 'enabled' => $info->getState()->enabled); } } return $this->pluginsInfo; }
/** * Builds plugins list that will be passed to templates engine. * * @return array */ protected function buildPluginsList() { $plugins = array(); foreach (PluginUtils::discoverPlugins() as $plugin_name) { $plugin = new PluginInfo($plugin_name); $plugins[] = array('name' => $plugin_name, 'version' => $plugin->isInstalled() ? $plugin->getInstalledVersion() : $plugin->getVersion(), 'dependencies' => array_merge($plugin->getSystemRequirements(), $plugin->getDependencies()), 'enabled' => $plugin->isEnabled(), 'installed' => $plugin->isInstalled(), 'needsUpdate' => $plugin->needsUpdate(), 'canBeEnabled' => $plugin->canBeEnabled(), 'canBeDisabled' => $plugin->canBeDisabled(), 'canBeUninstalled' => $plugin->canBeUninstalled(), 'canBeUpdated' => $plugin->canBeUpdated(), 'state' => $this->getPluginState($plugin)); } return $plugins; }
/** * Checks if the plugin can be enabled. * * @return boolean */ public function canBeEnabled() { if ($this->isEnabled()) { // The plugin cannot be enabled twice return false; } if ($this->hasUnsatisfiedSystemRequirements()) { return false; } // Make sure all plugin's dependencies exist, are enabled and have // appropriate versions foreach ($this->getDependencies() as $plugin_name => $required_version) { if (!Utils::pluginExists($plugin_name)) { return false; } $plugin = new PluginInfo($plugin_name); if (!$plugin->isInstalled() || !$plugin->isEnabled()) { return false; } $version_constrain = new VersionExpression($required_version); if (!$version_constrain->satisfiedBy(new Version($plugin->getInstalledVersion()))) { return false; } } return true; }
/** * Loads plugins. * * The method checks dependences and plugin availability before loading and * invokes PluginInterface::run() after loading. * * @param array $configs List of plugins' configurations. Each key is a * plugin name and each value is a configurations array. * * @see \Mibew\Plugin\PluginInterface::run() */ public function loadPlugins($configs) { // Builds Dependency graph with available plugins. $graph = new DependencyGraph(); foreach (State::loadAllEnabled() as $plugin_state) { if (!PluginUtils::pluginExists($plugin_state->pluginName)) { trigger_error(sprintf('Plugin "%s" exists in database base but is not found in file system!', $plugin_state->pluginName), E_USER_WARNING); continue; } $plugin_info = PluginInfo::fromState($plugin_state); if ($plugin_info->needsUpdate()) { trigger_error(sprintf('Update "%s" plugin before use it!', $plugin_info->getName()), E_USER_WARNING); continue; } if ($plugin_info->hasUnsatisfiedSystemRequirements()) { trigger_error(sprintf('Plugin "%s" has unsatisfied system requirements!', $plugin_info->getName()), E_USER_WARNING); continue; } $graph->addPlugin($plugin_info); } $offset = 0; $running_queue = array(); foreach ($graph->getLoadingQueue() as $plugin_info) { // Make sure all depedendencies are loaded foreach (array_keys($plugin_info->getDependencies()) as $dependency) { if (!isset($this->loadedPlugins[$dependency])) { trigger_error(sprintf('Plugin "%s" was not loaded yet, but exists in "%s" dependencies list!', $dependency, $plugin_info->getName()), E_USER_WARNING); continue 2; } } // Try to load the plugin. $name = $plugin_info->getName(); $config = isset($configs[$name]) ? $configs[$name] : array(); $instance = $plugin_info->getInstance($config); if ($instance->initialized()) { // Store the plugin and add it to running queue $this->loadedPlugins[$name] = $instance; $running_queue[$instance->getWeight() . "_" . $offset] = $instance; $offset++; } else { // The plugin cannot be loaded. Just skip it. trigger_error("Plugin '{$name}' was not initialized correctly!", E_USER_WARNING); } } // Sort queue in order to plugins' weights and run plugins one by one uksort($running_queue, 'strnatcmp'); foreach ($running_queue as $plugin) { $plugin->run(); } }