From dea0ba28f950867532eae572e7bcda49e81bbcf0 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 18 Nov 2015 17:40:42 +0100 Subject: Fixes #378 - Plugin administration UI. --- application/Config.php | 114 ++++++++++++++++++++++++++++++++++++++++++ application/PluginManager.php | 51 +++++++++++++++++++ application/Router.php | 12 +++++ 3 files changed, 177 insertions(+) (limited to 'application') diff --git a/application/Config.php b/application/Config.php index c71ef68c..9af5a535 100644 --- a/application/Config.php +++ b/application/Config.php @@ -73,6 +73,106 @@ function writeConfig($config, $isLoggedIn) } } +/** + * Process plugin administration form data and save it in an array. + * + * @param array $formData Data sent by the plugin admin form. + * + * @return array New list of enabled plugin, ordered. + * + * @throws PluginConfigOrderException Plugins can't be sorted because their order is invalid. + */ +function save_plugin_config($formData) +{ + // Make sure there are no duplicates in orders. + if (!validate_plugin_order($formData)) { + throw new PluginConfigOrderException(); + } + + $plugins = array(); + $newEnabledPlugins = array(); + foreach ($formData as $key => $data) { + if (startsWith($key, 'order')) { + continue; + } + + // If there is no order, it means a disabled plugin has been enabled. + if (isset($formData['order_' . $key])) { + $plugins[(int) $formData['order_' . $key]] = $key; + } + else { + $newEnabledPlugins[] = $key; + } + } + + // New enabled plugins will be added at the end of order. + $plugins = array_merge($plugins, $newEnabledPlugins); + + // Sort plugins by order. + if (!ksort($plugins)) { + throw new PluginConfigOrderException(); + } + + $finalPlugins = array(); + // Make plugins order continuous. + foreach ($plugins as $plugin) { + $finalPlugins[] = $plugin; + } + + return $finalPlugins; +} + +/** + * Validate plugin array submitted. + * Will fail if there is duplicate orders value. + * + * @param array $formData Data from submitted form. + * + * @return bool true if ok, false otherwise. + */ +function validate_plugin_order($formData) +{ + $orders = array(); + foreach ($formData as $key => $value) { + // No duplicate order allowed. + if (in_array($value, $orders)) { + return false; + } + + if (startsWith($key, 'order')) { + $orders[] = $value; + } + } + + return true; +} + +/** + * Affect plugin parameters values into plugins array. + * + * @param mixed $plugins Plugins array ($plugins[]['parameters']['param_name'] = . + * @param mixed $config Plugins configuration. + * + * @return mixed Updated $plugins array. + */ +function load_plugin_parameter_values($plugins, $config) +{ + $out = $plugins; + foreach ($plugins as $name => $plugin) { + if (empty($plugin['parameters'])) { + continue; + } + + foreach ($plugin['parameters'] as $key => $param) { + if (!empty($config[$key])) { + $out[$name]['parameters'][$key] = $config[$key]; + } + } + } + + return $out; +} + /** * Milestone 0.9 - shaarli/Shaarli#41: options.php is not supported anymore. * ==> if user is loggedIn, merge its content with config.php, then delete options.php. @@ -132,3 +232,17 @@ class UnauthorizedConfigException extends Exception $this->message = 'You are not authorized to alter config.'; } } + +/** + * Exception used if an error occur while saving plugin configuration. + */ +class PluginConfigOrderException extends Exception +{ + /** + * Construct exception. + */ + public function __construct() + { + $this->message = 'An error occurred while trying to save plugins loading order.'; + } +} diff --git a/application/PluginManager.php b/application/PluginManager.php index 803f11b4..787ac6a9 100644 --- a/application/PluginManager.php +++ b/application/PluginManager.php @@ -33,6 +33,12 @@ class PluginManager */ public static $PLUGINS_PATH = 'plugins'; + /** + * Plugins meta files extension. + * @var string $META_EXT + */ + public static $META_EXT = 'meta'; + /** * Private constructor: new instances not allowed. */ @@ -162,6 +168,51 @@ class PluginManager { return 'hook_' . $pluginName . '_' . $hook; } + + /** + * Retrieve plugins metadata from *.meta (INI) files into an array. + * Metadata contains: + * - plugin description [description] + * - parameters split with ';' [parameters] + * + * Respects plugins order from settings. + * + * @return array plugins metadata. + */ + public function getPluginsMeta() + { + $metaData = array(); + $dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR | GLOB_MARK); + + // Browse all plugin directories. + foreach ($dirs as $pluginDir) { + $plugin = basename($pluginDir); + $metaFile = $pluginDir . $plugin . '.' . self::$META_EXT; + if (!is_file($metaFile) || !is_readable($metaFile)) { + continue; + } + + $metaData[$plugin] = parse_ini_file($metaFile); + $metaData[$plugin]['order'] = array_search($plugin, $this->authorizedPlugins); + + // Read parameters and format them into an array. + if (isset($metaData[$plugin]['parameters'])) { + $params = explode(';', $metaData[$plugin]['parameters']); + } else { + $params = array(); + } + $metaData[$plugin]['parameters'] = array(); + foreach ($params as $param) { + if (empty($param)) { + continue; + } + + $metaData[$plugin]['parameters'][$param] = ''; + } + } + + return $metaData; + } } /** diff --git a/application/Router.php b/application/Router.php index 0c813847..6185f08e 100644 --- a/application/Router.php +++ b/application/Router.php @@ -35,6 +35,10 @@ class Router public static $PAGE_LINKLIST = 'linklist'; + public static $PAGE_PLUGINSADMIN = 'pluginadmin'; + + public static $PAGE_SAVE_PLUGINSADMIN = 'save_pluginadmin'; + /** * Reproducing renderPage() if hell, to avoid regression. * @@ -112,6 +116,14 @@ class Router return self::$PAGE_IMPORT; } + if (startswith($query, 'do='. self::$PAGE_PLUGINSADMIN)) { + return self::$PAGE_PLUGINSADMIN; + } + + if (startswith($query, 'do='. self::$PAGE_SAVE_PLUGINSADMIN)) { + return self::$PAGE_SAVE_PLUGINSADMIN; + } + return self::$PAGE_LINKLIST; } } \ No newline at end of file -- cgit v1.2.3