aboutsummaryrefslogtreecommitdiffhomepage
path: root/application
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2015-11-18 17:40:42 +0100
committerArthurHoaro <arthur@hoa.ro>2016-01-31 18:54:48 +0100
commitdea0ba28f950867532eae572e7bcda49e81bbcf0 (patch)
tree8a9c4f9d7525a2ba249bbaaabe456c2d0941293b /application
parent423e2a8b13dc0069c83f3e540f576aa1b89fe5d5 (diff)
downloadShaarli-dea0ba28f950867532eae572e7bcda49e81bbcf0.tar.gz
Shaarli-dea0ba28f950867532eae572e7bcda49e81bbcf0.tar.zst
Shaarli-dea0ba28f950867532eae572e7bcda49e81bbcf0.zip
Fixes #378 - Plugin administration UI.
Diffstat (limited to 'application')
-rw-r--r--application/Config.php114
-rw-r--r--application/PluginManager.php51
-rw-r--r--application/Router.php12
3 files changed, 177 insertions, 0 deletions
diff --git a/application/Config.php b/application/Config.php
index c71ef68c..9af5a535 100644
--- a/application/Config.php
+++ b/application/Config.php
@@ -74,6 +74,106 @@ function writeConfig($config, $isLoggedIn)
74} 74}
75 75
76/** 76/**
77 * Process plugin administration form data and save it in an array.
78 *
79 * @param array $formData Data sent by the plugin admin form.
80 *
81 * @return array New list of enabled plugin, ordered.
82 *
83 * @throws PluginConfigOrderException Plugins can't be sorted because their order is invalid.
84 */
85function save_plugin_config($formData)
86{
87 // Make sure there are no duplicates in orders.
88 if (!validate_plugin_order($formData)) {
89 throw new PluginConfigOrderException();
90 }
91
92 $plugins = array();
93 $newEnabledPlugins = array();
94 foreach ($formData as $key => $data) {
95 if (startsWith($key, 'order')) {
96 continue;
97 }
98
99 // If there is no order, it means a disabled plugin has been enabled.
100 if (isset($formData['order_' . $key])) {
101 $plugins[(int) $formData['order_' . $key]] = $key;
102 }
103 else {
104 $newEnabledPlugins[] = $key;
105 }
106 }
107
108 // New enabled plugins will be added at the end of order.
109 $plugins = array_merge($plugins, $newEnabledPlugins);
110
111 // Sort plugins by order.
112 if (!ksort($plugins)) {
113 throw new PluginConfigOrderException();
114 }
115
116 $finalPlugins = array();
117 // Make plugins order continuous.
118 foreach ($plugins as $plugin) {
119 $finalPlugins[] = $plugin;
120 }
121
122 return $finalPlugins;
123}
124
125/**
126 * Validate plugin array submitted.
127 * Will fail if there is duplicate orders value.
128 *
129 * @param array $formData Data from submitted form.
130 *
131 * @return bool true if ok, false otherwise.
132 */
133function validate_plugin_order($formData)
134{
135 $orders = array();
136 foreach ($formData as $key => $value) {
137 // No duplicate order allowed.
138 if (in_array($value, $orders)) {
139 return false;
140 }
141
142 if (startsWith($key, 'order')) {
143 $orders[] = $value;
144 }
145 }
146
147 return true;
148}
149
150/**
151 * Affect plugin parameters values into plugins array.
152 *
153 * @param mixed $plugins Plugins array ($plugins[<plugin_name>]['parameters']['param_name'] = <value>.
154 * @param mixed $config Plugins configuration.
155 *
156 * @return mixed Updated $plugins array.
157 */
158function load_plugin_parameter_values($plugins, $config)
159{
160 $out = $plugins;
161 foreach ($plugins as $name => $plugin) {
162 if (empty($plugin['parameters'])) {
163 continue;
164 }
165
166 foreach ($plugin['parameters'] as $key => $param) {
167 if (!empty($config[$key])) {
168 $out[$name]['parameters'][$key] = $config[$key];
169 }
170 }
171 }
172
173 return $out;
174}
175
176/**
77 * Milestone 0.9 - shaarli/Shaarli#41: options.php is not supported anymore. 177 * Milestone 0.9 - shaarli/Shaarli#41: options.php is not supported anymore.
78 * ==> if user is loggedIn, merge its content with config.php, then delete options.php. 178 * ==> if user is loggedIn, merge its content with config.php, then delete options.php.
79 * 179 *
@@ -132,3 +232,17 @@ class UnauthorizedConfigException extends Exception
132 $this->message = 'You are not authorized to alter config.'; 232 $this->message = 'You are not authorized to alter config.';
133 } 233 }
134} 234}
235
236/**
237 * Exception used if an error occur while saving plugin configuration.
238 */
239class PluginConfigOrderException extends Exception
240{
241 /**
242 * Construct exception.
243 */
244 public function __construct()
245 {
246 $this->message = 'An error occurred while trying to save plugins loading order.';
247 }
248}
diff --git a/application/PluginManager.php b/application/PluginManager.php
index 803f11b4..787ac6a9 100644
--- a/application/PluginManager.php
+++ b/application/PluginManager.php
@@ -34,6 +34,12 @@ class PluginManager
34 public static $PLUGINS_PATH = 'plugins'; 34 public static $PLUGINS_PATH = 'plugins';
35 35
36 /** 36 /**
37 * Plugins meta files extension.
38 * @var string $META_EXT
39 */
40 public static $META_EXT = 'meta';
41
42 /**
37 * Private constructor: new instances not allowed. 43 * Private constructor: new instances not allowed.
38 */ 44 */
39 private function __construct() 45 private function __construct()
@@ -162,6 +168,51 @@ class PluginManager
162 { 168 {
163 return 'hook_' . $pluginName . '_' . $hook; 169 return 'hook_' . $pluginName . '_' . $hook;
164 } 170 }
171
172 /**
173 * Retrieve plugins metadata from *.meta (INI) files into an array.
174 * Metadata contains:
175 * - plugin description [description]
176 * - parameters split with ';' [parameters]
177 *
178 * Respects plugins order from settings.
179 *
180 * @return array plugins metadata.
181 */
182 public function getPluginsMeta()
183 {
184 $metaData = array();
185 $dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR | GLOB_MARK);
186
187 // Browse all plugin directories.
188 foreach ($dirs as $pluginDir) {
189 $plugin = basename($pluginDir);
190 $metaFile = $pluginDir . $plugin . '.' . self::$META_EXT;
191 if (!is_file($metaFile) || !is_readable($metaFile)) {
192 continue;
193 }
194
195 $metaData[$plugin] = parse_ini_file($metaFile);
196 $metaData[$plugin]['order'] = array_search($plugin, $this->authorizedPlugins);
197
198 // Read parameters and format them into an array.
199 if (isset($metaData[$plugin]['parameters'])) {
200 $params = explode(';', $metaData[$plugin]['parameters']);
201 } else {
202 $params = array();
203 }
204 $metaData[$plugin]['parameters'] = array();
205 foreach ($params as $param) {
206 if (empty($param)) {
207 continue;
208 }
209
210 $metaData[$plugin]['parameters'][$param] = '';
211 }
212 }
213
214 return $metaData;
215 }
165} 216}
166 217
167/** 218/**
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
35 35
36 public static $PAGE_LINKLIST = 'linklist'; 36 public static $PAGE_LINKLIST = 'linklist';
37 37
38 public static $PAGE_PLUGINSADMIN = 'pluginadmin';
39
40 public static $PAGE_SAVE_PLUGINSADMIN = 'save_pluginadmin';
41
38 /** 42 /**
39 * Reproducing renderPage() if hell, to avoid regression. 43 * Reproducing renderPage() if hell, to avoid regression.
40 * 44 *
@@ -112,6 +116,14 @@ class Router
112 return self::$PAGE_IMPORT; 116 return self::$PAGE_IMPORT;
113 } 117 }
114 118
119 if (startswith($query, 'do='. self::$PAGE_PLUGINSADMIN)) {
120 return self::$PAGE_PLUGINSADMIN;
121 }
122
123 if (startswith($query, 'do='. self::$PAGE_SAVE_PLUGINSADMIN)) {
124 return self::$PAGE_SAVE_PLUGINSADMIN;
125 }
126
115 return self::$PAGE_LINKLIST; 127 return self::$PAGE_LINKLIST;
116 } 128 }
117} \ No newline at end of file 129} \ No newline at end of file