aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2016-05-18 21:43:59 +0200
committerArthurHoaro <arthur@hoa.ro>2016-06-11 09:30:56 +0200
commit59404d7909b21682ec0782778452a8a70e38b25e (patch)
tree52bbe0b390ecd37f80128d1f8b4f80c3834734a8
parent823a363c3b2e10008a607c8b69c1a3d4e9b44ea1 (diff)
downloadShaarli-59404d7909b21682ec0782778452a8a70e38b25e.tar.gz
Shaarli-59404d7909b21682ec0782778452a8a70e38b25e.tar.zst
Shaarli-59404d7909b21682ec0782778452a8a70e38b25e.zip
Introduce a configuration manager (not plugged yet)
-rw-r--r--application/config/ConfigIO.php33
-rw-r--r--application/config/ConfigManager.php363
-rw-r--r--application/config/ConfigPhp.php93
-rw-r--r--application/config/ConfigPlugin.php118
-rw-r--r--tests/config/ConfigManagerTest.php48
-rw-r--r--tests/config/ConfigPhpTest.php82
-rw-r--r--tests/config/ConfigPluginTest.php121
-rw-r--r--tests/config/php/configOK.php14
8 files changed, 872 insertions, 0 deletions
diff --git a/application/config/ConfigIO.php b/application/config/ConfigIO.php
new file mode 100644
index 00000000..2b68fe6a
--- /dev/null
+++ b/application/config/ConfigIO.php
@@ -0,0 +1,33 @@
1<?php
2
3/**
4 * Interface ConfigIO
5 *
6 * This describes how Config types should store their configuration.
7 */
8interface ConfigIO
9{
10 /**
11 * Read configuration.
12 *
13 * @param string $filepath Config file absolute path.
14 *
15 * @return array All configuration in an array.
16 */
17 function read($filepath);
18
19 /**
20 * Write configuration.
21 *
22 * @param string $filepath Config file absolute path.
23 * @param array $conf All configuration in an array.
24 */
25 function write($filepath, $conf);
26
27 /**
28 * Get config file extension according to config type.
29 *
30 * @return string Config file extension.
31 */
32 function getExtension();
33}
diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php
new file mode 100644
index 00000000..dfe9eeb9
--- /dev/null
+++ b/application/config/ConfigManager.php
@@ -0,0 +1,363 @@
1<?php
2
3// FIXME! Namespaces...
4require_once 'ConfigIO.php';
5require_once 'ConfigPhp.php';
6#require_once 'ConfigJson.php';
7
8/**
9 * Class ConfigManager
10 *
11 * Singleton, manages all Shaarli's settings.
12 */
13class ConfigManager
14{
15 /**
16 * @var ConfigManager instance.
17 */
18 protected static $instance = null;
19
20 /**
21 * @var string Config folder.
22 */
23 public static $CONFIG_FILE = 'data/config';
24
25 /**
26 * @var string Flag telling a setting is not found.
27 */
28 protected static $NOT_FOUND = 'NOT_FOUND';
29
30 /**
31 * @var array Loaded config array.
32 */
33 protected $loadedConfig;
34
35 /**
36 * @var ConfigIO implementation instance.
37 */
38 protected $configIO;
39
40 /**
41 * Private constructor: new instances not allowed.
42 */
43 private function __construct() {}
44
45 /**
46 * Cloning isn't allowed either.
47 */
48 private function __clone() {}
49
50 /**
51 * Return existing instance of PluginManager, or create it.
52 *
53 * @return ConfigManager instance.
54 */
55 public static function getInstance()
56 {
57 if (!(self::$instance instanceof self)) {
58 self::$instance = new self();
59 self::$instance->initialize();
60 }
61
62 return self::$instance;
63 }
64
65 /**
66 * Rebuild the loaded config array from config files.
67 */
68 public function reload()
69 {
70 $this->initialize();
71 }
72
73 /**
74 * Initialize loaded conf in ConfigManager.
75 */
76 protected function initialize()
77 {
78 /*if (! file_exists(self::$CONFIG_FILE .'.php')) {
79 $this->configIO = new ConfigJson();
80 } else {
81 $this->configIO = new ConfigPhp();
82 }*/
83 $this->configIO = new ConfigPhp();
84 $this->loadedConfig = $this->configIO->read(self::$CONFIG_FILE);
85 $this->setDefaultValues();
86 }
87
88 /**
89 * Get a setting.
90 *
91 * Supports nested settings with dot separated keys.
92 * Eg. 'config.stuff.option' will find $conf[config][stuff][option],
93 * or in JSON:
94 * { "config": { "stuff": {"option": "mysetting" } } } }
95 *
96 * @param string $setting Asked setting, keys separated with dots.
97 * @param string $default Default value if not found.
98 *
99 * @return mixed Found setting, or the default value.
100 */
101 public function get($setting, $default = '')
102 {
103 $settings = explode('.', $setting);
104 $value = self::getConfig($settings, $this->loadedConfig);
105 if ($value === self::$NOT_FOUND) {
106 return $default;
107 }
108 return $value;
109 }
110
111 /**
112 * Set a setting, and eventually write it.
113 *
114 * Supports nested settings with dot separated keys.
115 *
116 * @param string $setting Asked setting, keys separated with dots.
117 * @param string $value Value to set.
118 * @param bool $write Write the new setting in the config file, default false.
119 * @param bool $isLoggedIn User login state, default false.
120 */
121 public function set($setting, $value, $write = false, $isLoggedIn = false)
122 {
123 $settings = explode('.', $setting);
124 self::setConfig($settings, $value, $this->loadedConfig);
125 if ($write) {
126 $this->write($isLoggedIn);
127 }
128 }
129
130 /**
131 * Check if a settings exists.
132 *
133 * Supports nested settings with dot separated keys.
134 *
135 * @param string $setting Asked setting, keys separated with dots.
136 *
137 * @return bool true if the setting exists, false otherwise.
138 */
139 public function exists($setting)
140 {
141 $settings = explode('.', $setting);
142 $value = self::getConfig($settings, $this->loadedConfig);
143 if ($value === self::$NOT_FOUND) {
144 return false;
145 }
146 return true;
147 }
148
149 /**
150 * Call the config writer.
151 *
152 * @param bool $isLoggedIn User login state.
153 *
154 * @throws MissingFieldConfigException: a mandatory field has not been provided in $conf.
155 * @throws UnauthorizedConfigException: user is not authorize to change configuration.
156 * @throws IOException: an error occurred while writing the new config file.
157 */
158 public function write($isLoggedIn)
159 {
160 // These fields are required in configuration.
161 $mandatoryFields = array(
162 'login', 'hash', 'salt', 'timezone', 'title', 'titleLink',
163 'redirector', 'disablesessionprotection', 'privateLinkByDefault'
164 );
165
166 // Only logged in user can alter config.
167 if (is_file(self::$CONFIG_FILE) && !$isLoggedIn) {
168 throw new UnauthorizedConfigException();
169 }
170
171 // Check that all mandatory fields are provided in $conf.
172 foreach ($mandatoryFields as $field) {
173 if (! $this->exists($field)) {
174 throw new MissingFieldConfigException($field);
175 }
176 }
177
178 $this->configIO->write(self::$CONFIG_FILE, $this->loadedConfig);
179 }
180
181 /**
182 * Get the configuration file path.
183 *
184 * @return string Config file path.
185 */
186 public function getConfigFile()
187 {
188 return self::$CONFIG_FILE . $this->configIO->getExtension();
189 }
190
191 /**
192 * Recursive function which find asked setting in the loaded config.
193 *
194 * @param array $settings Ordered array which contains keys to find.
195 * @param array $conf Loaded settings, then sub-array.
196 *
197 * @return mixed Found setting or NOT_FOUND flag.
198 */
199 protected static function getConfig($settings, $conf)
200 {
201 if (!is_array($settings) || count($settings) == 0) {
202 return self::$NOT_FOUND;
203 }
204
205 $setting = array_shift($settings);
206 if (!isset($conf[$setting])) {
207 return self::$NOT_FOUND;
208 }
209
210 if (count($settings) > 0) {
211 return self::getConfig($settings, $conf[$setting]);
212 }
213 return $conf[$setting];
214 }
215
216 /**
217 * Recursive function which find asked setting in the loaded config.
218 *
219 * @param array $settings Ordered array which contains keys to find.
220 * @param mixed $value
221 * @param array $conf Loaded settings, then sub-array.
222 *
223 * @return mixed Found setting or NOT_FOUND flag.
224 */
225 protected static function setConfig($settings, $value, &$conf)
226 {
227 if (!is_array($settings) || count($settings) == 0) {
228 return self::$NOT_FOUND;
229 }
230
231 $setting = array_shift($settings);
232 if (count($settings) > 0) {
233 return self::setConfig($settings, $value, $conf[$setting]);
234 }
235 $conf[$setting] = $value;
236 }
237
238 /**
239 * Set a bunch of default values allowing Shaarli to start without a config file.
240 */
241 protected function setDefaultValues()
242 {
243 // Data subdirectory
244 $this->setEmpty('config.DATADIR', 'data');
245
246 // Main configuration file
247 $this->setEmpty('config.CONFIG_FILE', 'data/config.php');
248
249 // Link datastore
250 $this->setEmpty('config.DATASTORE', 'data/datastore.php');
251
252 // Banned IPs
253 $this->setEmpty('config.IPBANS_FILENAME', 'data/ipbans.php');
254
255 // Processed updates file.
256 $this->setEmpty('config.UPDATES_FILE', 'data/updates.txt');
257
258 // Access log
259 $this->setEmpty('config.LOG_FILE', 'data/log.txt');
260
261 // For updates check of Shaarli
262 $this->setEmpty('config.UPDATECHECK_FILENAME', 'data/lastupdatecheck.txt');
263
264 // Set ENABLE_UPDATECHECK to disabled by default.
265 $this->setEmpty('config.ENABLE_UPDATECHECK', false);
266
267 // RainTPL cache directory (keep the trailing slash!)
268 $this->setEmpty('config.RAINTPL_TMP', 'tmp/');
269 // Raintpl template directory (keep the trailing slash!)
270 $this->setEmpty('config.RAINTPL_TPL', 'tpl/');
271
272 // Thumbnail cache directory
273 $this->setEmpty('config.CACHEDIR', 'cache');
274
275 // Atom & RSS feed cache directory
276 $this->setEmpty('config.PAGECACHE', 'pagecache');
277
278 // Ban IP after this many failures
279 $this->setEmpty('config.BAN_AFTER', 4);
280 // Ban duration for IP address after login failures (in seconds)
281 $this->setEmpty('config.BAN_DURATION', 1800);
282
283 // Feed options
284 // Enable RSS permalinks by default.
285 // This corresponds to the default behavior of shaarli before this was added as an option.
286 $this->setEmpty('config.ENABLE_RSS_PERMALINKS', true);
287 // If true, an extra "ATOM feed" button will be displayed in the toolbar
288 $this->setEmpty('config.SHOW_ATOM', false);
289
290 // Link display options
291 $this->setEmpty('config.HIDE_PUBLIC_LINKS', false);
292 $this->setEmpty('config.HIDE_TIMESTAMPS', false);
293 $this->setEmpty('config.LINKS_PER_PAGE', 20);
294
295 // Open Shaarli (true): anyone can add/edit/delete links without having to login
296 $this->setEmpty('config.OPEN_SHAARLI', false);
297
298 // Thumbnails
299 // Display thumbnails in links
300 $this->setEmpty('config.ENABLE_THUMBNAILS', true);
301 // Store thumbnails in a local cache
302 $this->setEmpty('config.ENABLE_LOCALCACHE', true);
303
304 // Update check frequency for Shaarli. 86400 seconds=24 hours
305 $this->setEmpty('config.UPDATECHECK_BRANCH', 'stable');
306 $this->setEmpty('config.UPDATECHECK_INTERVAL', 86400);
307
308 $this->setEmpty('redirector', '');
309 $this->setEmpty('config.REDIRECTOR_URLENCODE', true);
310
311 // Enabled plugins.
312 $this->setEmpty('config.ENABLED_PLUGINS', array('qrcode'));
313
314 // Initialize plugin parameters array.
315 $this->setEmpty('plugins', array());
316 }
317
318 /**
319 * Set only if the setting does not exists.
320 *
321 * @param string $key Setting key.
322 * @param mixed $value Setting value.
323 */
324 protected function setEmpty($key, $value)
325 {
326 if (! $this->exists($key)) {
327 $this->set($key, $value);
328 }
329 }
330}
331
332/**
333 * Exception used if a mandatory field is missing in given configuration.
334 */
335class MissingFieldConfigException extends Exception
336{
337 public $field;
338
339 /**
340 * Construct exception.
341 *
342 * @param string $field field name missing.
343 */
344 public function __construct($field)
345 {
346 $this->field = $field;
347 $this->message = 'Configuration value is required for '. $this->field;
348 }
349}
350
351/**
352 * Exception used if an unauthorized attempt to edit configuration has been made.
353 */
354class UnauthorizedConfigException extends Exception
355{
356 /**
357 * Construct exception.
358 */
359 public function __construct()
360 {
361 $this->message = 'You are not authorized to alter config.';
362 }
363}
diff --git a/application/config/ConfigPhp.php b/application/config/ConfigPhp.php
new file mode 100644
index 00000000..311aeb81
--- /dev/null
+++ b/application/config/ConfigPhp.php
@@ -0,0 +1,93 @@
1<?php
2
3/**
4 * Class ConfigPhp (ConfigIO implementation)
5 *
6 * Handle Shaarli's legacy PHP configuration file.
7 * Note: this is only designed to support the transition to JSON configuration.
8 */
9class ConfigPhp implements ConfigIO
10{
11 /**
12 * @var array List of config key without group.
13 */
14 public static $ROOT_KEYS = array(
15 'login',
16 'hash',
17 'salt',
18 'timezone',
19 'title',
20 'titleLink',
21 'redirector',
22 'disablesessionprotection',
23 'privateLinkByDefault',
24 );
25
26 /**
27 * @inheritdoc
28 */
29 function read($filepath)
30 {
31 $filepath .= $this->getExtension();
32 if (! file_exists($filepath) || ! is_readable($filepath)) {
33 return array();
34 }
35
36 include $filepath;
37
38 $out = array();
39 foreach (self::$ROOT_KEYS as $key) {
40 $out[$key] = $GLOBALS[$key];
41 }
42 $out['config'] = $GLOBALS['config'];
43 $out['plugins'] = !empty($GLOBALS['plugins']) ? $GLOBALS['plugins'] : array();
44 return $out;
45 }
46
47 /**
48 * @inheritdoc
49 */
50 function write($filepath, $conf)
51 {
52 $filepath .= $this->getExtension();
53
54 $configStr = '<?php '. PHP_EOL;
55 foreach (self::$ROOT_KEYS as $key) {
56 if (isset($conf[$key])) {
57 $configStr .= '$GLOBALS[\'' . $key . '\'] = ' . var_export($conf[$key], true) . ';' . PHP_EOL;
58 }
59 }
60
61 // Store all $conf['config']
62 foreach ($conf['config'] as $key => $value) {
63 $configStr .= '$GLOBALS[\'config\'][\''. $key .'\'] = '.var_export($conf['config'][$key], true).';'. PHP_EOL;
64 }
65
66 if (isset($conf['plugins'])) {
67 foreach ($conf['plugins'] as $key => $value) {
68 $configStr .= '$GLOBALS[\'plugins\'][\''. $key .'\'] = '.var_export($conf['plugins'][$key], true).';'. PHP_EOL;
69 }
70 }
71
72 // FIXME!
73 //$configStr .= 'date_default_timezone_set('.var_export($conf['timezone'], true).');'. PHP_EOL;
74
75 if (!file_put_contents($filepath, $configStr)
76 || strcmp(file_get_contents($filepath), $configStr) != 0
77 ) {
78 throw new IOException(
79 $filepath,
80 'Shaarli could not create the config file.
81 Please make sure Shaarli has the right to write in the folder is it installed in.'
82 );
83 }
84 }
85
86 /**
87 * @inheritdoc
88 */
89 function getExtension()
90 {
91 return '.php';
92 }
93}
diff --git a/application/config/ConfigPlugin.php b/application/config/ConfigPlugin.php
new file mode 100644
index 00000000..8af89d04
--- /dev/null
+++ b/application/config/ConfigPlugin.php
@@ -0,0 +1,118 @@
1<?php
2/**
3 * Functions related to configuration management.
4 */
5
6/**
7 * Process plugin administration form data and save it in an array.
8 *
9 * @param array $formData Data sent by the plugin admin form.
10 *
11 * @return array New list of enabled plugin, ordered.
12 *
13 * @throws PluginConfigOrderException Plugins can't be sorted because their order is invalid.
14 */
15function save_plugin_config($formData)
16{
17 // Make sure there are no duplicates in orders.
18 if (!validate_plugin_order($formData)) {
19 throw new PluginConfigOrderException();
20 }
21
22 $plugins = array();
23 $newEnabledPlugins = array();
24 foreach ($formData as $key => $data) {
25 if (startsWith($key, 'order')) {
26 continue;
27 }
28
29 // If there is no order, it means a disabled plugin has been enabled.
30 if (isset($formData['order_' . $key])) {
31 $plugins[(int) $formData['order_' . $key]] = $key;
32 }
33 else {
34 $newEnabledPlugins[] = $key;
35 }
36 }
37
38 // New enabled plugins will be added at the end of order.
39 $plugins = array_merge($plugins, $newEnabledPlugins);
40
41 // Sort plugins by order.
42 if (!ksort($plugins)) {
43 throw new PluginConfigOrderException();
44 }
45
46 $finalPlugins = array();
47 // Make plugins order continuous.
48 foreach ($plugins as $plugin) {
49 $finalPlugins[] = $plugin;
50 }
51
52 return $finalPlugins;
53}
54
55/**
56 * Validate plugin array submitted.
57 * Will fail if there is duplicate orders value.
58 *
59 * @param array $formData Data from submitted form.
60 *
61 * @return bool true if ok, false otherwise.
62 */
63function validate_plugin_order($formData)
64{
65 $orders = array();
66 foreach ($formData as $key => $value) {
67 // No duplicate order allowed.
68 if (in_array($value, $orders)) {
69 return false;
70 }
71
72 if (startsWith($key, 'order')) {
73 $orders[] = $value;
74 }
75 }
76
77 return true;
78}
79
80/**
81 * Affect plugin parameters values into plugins array.
82 *
83 * @param mixed $plugins Plugins array ($plugins[<plugin_name>]['parameters']['param_name'] = <value>.
84 * @param mixed $conf Plugins configuration.
85 *
86 * @return mixed Updated $plugins array.
87 */
88function load_plugin_parameter_values($plugins, $conf)
89{
90 $out = $plugins;
91 foreach ($plugins as $name => $plugin) {
92 if (empty($plugin['parameters'])) {
93 continue;
94 }
95
96 foreach ($plugin['parameters'] as $key => $param) {
97 if (!empty($conf[$key])) {
98 $out[$name]['parameters'][$key] = $conf[$key];
99 }
100 }
101 }
102
103 return $out;
104}
105
106/**
107 * Exception used if an error occur while saving plugin configuration.
108 */
109class PluginConfigOrderException extends Exception
110{
111 /**
112 * Construct exception.
113 */
114 public function __construct()
115 {
116 $this->message = 'An error occurred while trying to save plugins loading order.';
117 }
118}
diff --git a/tests/config/ConfigManagerTest.php b/tests/config/ConfigManagerTest.php
new file mode 100644
index 00000000..1b6358f3
--- /dev/null
+++ b/tests/config/ConfigManagerTest.php
@@ -0,0 +1,48 @@
1<?php
2
3/**
4 * Unit tests for Class ConfigManagerTest
5 *
6 * Note: it only test the manager with ConfigJson,
7 * ConfigPhp is only a workaround to handle the transition to JSON type.
8 */
9class ConfigManagerTest extends \PHPUnit_Framework_TestCase
10{
11 /**
12 * @var ConfigManager
13 */
14 protected $conf;
15
16 public function setUp()
17 {
18 ConfigManager::$CONFIG_FILE = 'tests/config/config';
19 $this->conf = ConfigManager::getInstance();
20 }
21
22 public function tearDown()
23 {
24 @unlink($this->conf->getConfigFile());
25 }
26
27 public function testSetWriteGet()
28 {
29 // This won't work with ConfigPhp.
30 $this->markTestIncomplete();
31
32 $this->conf->set('paramInt', 42);
33 $this->conf->set('paramString', 'value1');
34 $this->conf->set('paramBool', false);
35 $this->conf->set('paramArray', array('foo' => 'bar'));
36 $this->conf->set('paramNull', null);
37
38 $this->conf->write(true);
39 $this->conf->reload();
40
41 $this->assertEquals(42, $this->conf->get('paramInt'));
42 $this->assertEquals('value1', $this->conf->get('paramString'));
43 $this->assertFalse($this->conf->get('paramBool'));
44 $this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray'));
45 $this->assertEquals(null, $this->conf->get('paramNull'));
46 }
47
48} \ No newline at end of file
diff --git a/tests/config/ConfigPhpTest.php b/tests/config/ConfigPhpTest.php
new file mode 100644
index 00000000..0f849bd5
--- /dev/null
+++ b/tests/config/ConfigPhpTest.php
@@ -0,0 +1,82 @@
1<?php
2
3require_once 'application/config/ConfigPhp.php';
4
5/**
6 * Class ConfigPhpTest
7 */
8class ConfigPhpTest extends PHPUnit_Framework_TestCase
9{
10 /**
11 * @var ConfigPhp
12 */
13 protected $configIO;
14
15 public function setUp()
16 {
17 $this->configIO = new ConfigPhp();
18 }
19
20 /**
21 * Read a simple existing config file.
22 */
23 public function testRead()
24 {
25 $conf = $this->configIO->read('tests/config/php/configOK');
26 $this->assertEquals('root', $conf['login']);
27 $this->assertEquals('lala', $conf['redirector']);
28 $this->assertEquals('data/datastore.php', $conf['config']['DATASTORE']);
29 $this->assertEquals('1', $conf['plugins']['WALLABAG_VERSION']);
30 }
31
32 /**
33 * Read a non existent config file -> empty array.
34 */
35 public function testReadNonExistent()
36 {
37 $this->assertEquals(array(), $this->configIO->read('nope'));
38 }
39
40 /**
41 * Write a new config file.
42 */
43 public function testWriteNew()
44 {
45 $dataFile = 'tests/config/php/configWrite';
46 $data = array(
47 'login' => 'root',
48 'redirector' => 'lala',
49 'config' => array(
50 'DATASTORE' => 'data/datastore.php',
51 ),
52 'plugins' => array(
53 'WALLABAG_VERSION' => '1',
54 )
55 );
56 $this->configIO->write($dataFile, $data);
57 $expected = '<?php
58$GLOBALS[\'login\'] = \'root\';
59$GLOBALS[\'redirector\'] = \'lala\';
60$GLOBALS[\'config\'][\'DATASTORE\'] = \'data/datastore.php\';
61$GLOBALS[\'plugins\'][\'WALLABAG_VERSION\'] = \'1\';
62';
63 $this->assertEquals($expected, file_get_contents($dataFile .'.php'));
64 unlink($dataFile .'.php');
65 }
66
67 /**
68 * Overwrite an existing setting.
69 */
70 public function testOverwrite()
71 {
72 $source = 'tests/config/php/configOK.php';
73 $dest = 'tests/config/php/configOverwrite';
74 copy($source, $dest . '.php');
75 $conf = $this->configIO->read($dest);
76 $conf['redirector'] = 'blabla';
77 $this->configIO->write($dest, $conf);
78 $conf = $this->configIO->read($dest);
79 $this->assertEquals('blabla', $conf['redirector']);
80 unlink($dest .'.php');
81 }
82}
diff --git a/tests/config/ConfigPluginTest.php b/tests/config/ConfigPluginTest.php
new file mode 100644
index 00000000..716631b0
--- /dev/null
+++ b/tests/config/ConfigPluginTest.php
@@ -0,0 +1,121 @@
1<?php
2/**
3 * Config' tests
4 */
5
6require_once 'application/config/ConfigPlugin.php';
7
8/**
9 * Unitary tests for Shaarli config related functions
10 */
11class ConfigPluginTest extends PHPUnit_Framework_TestCase
12{
13 /**
14 * Test save_plugin_config with valid data.
15 *
16 * @throws PluginConfigOrderException
17 */
18 public function testSavePluginConfigValid()
19 {
20 $data = array(
21 'order_plugin1' => 2, // no plugin related
22 'plugin2' => 0, // new - at the end
23 'plugin3' => 0, // 2nd
24 'order_plugin3' => 8,
25 'plugin4' => 0, // 1st
26 'order_plugin4' => 5,
27 );
28
29 $expected = array(
30 'plugin3',
31 'plugin4',
32 'plugin2',
33 );
34
35 $out = save_plugin_config($data);
36 $this->assertEquals($expected, $out);
37 }
38
39 /**
40 * Test save_plugin_config with invalid data.
41 *
42 * @expectedException PluginConfigOrderException
43 */
44 public function testSavePluginConfigInvalid()
45 {
46 $data = array(
47 'plugin2' => 0,
48 'plugin3' => 0,
49 'order_plugin3' => 0,
50 'plugin4' => 0,
51 'order_plugin4' => 0,
52 );
53
54 save_plugin_config($data);
55 }
56
57 /**
58 * Test save_plugin_config without data.
59 */
60 public function testSavePluginConfigEmpty()
61 {
62 $this->assertEquals(array(), save_plugin_config(array()));
63 }
64
65 /**
66 * Test validate_plugin_order with valid data.
67 */
68 public function testValidatePluginOrderValid()
69 {
70 $data = array(
71 'order_plugin1' => 2,
72 'plugin2' => 0,
73 'plugin3' => 0,
74 'order_plugin3' => 1,
75 'plugin4' => 0,
76 'order_plugin4' => 5,
77 );
78
79 $this->assertTrue(validate_plugin_order($data));
80 }
81
82 /**
83 * Test validate_plugin_order with invalid data.
84 */
85 public function testValidatePluginOrderInvalid()
86 {
87 $data = array(
88 'order_plugin1' => 2,
89 'order_plugin3' => 1,
90 'order_plugin4' => 1,
91 );
92
93 $this->assertFalse(validate_plugin_order($data));
94 }
95
96 /**
97 * Test load_plugin_parameter_values.
98 */
99 public function testLoadPluginParameterValues()
100 {
101 $plugins = array(
102 'plugin_name' => array(
103 'parameters' => array(
104 'param1' => true,
105 'param2' => false,
106 'param3' => '',
107 )
108 )
109 );
110
111 $parameters = array(
112 'param1' => 'value1',
113 'param2' => 'value2',
114 );
115
116 $result = load_plugin_parameter_values($plugins, $parameters);
117 $this->assertEquals('value1', $result['plugin_name']['parameters']['param1']);
118 $this->assertEquals('value2', $result['plugin_name']['parameters']['param2']);
119 $this->assertEquals('', $result['plugin_name']['parameters']['param3']);
120 }
121}
diff --git a/tests/config/php/configOK.php b/tests/config/php/configOK.php
new file mode 100644
index 00000000..b91ad293
--- /dev/null
+++ b/tests/config/php/configOK.php
@@ -0,0 +1,14 @@
1<?php
2$GLOBALS['login'] = 'root';
3$GLOBALS['hash'] = 'hash';
4$GLOBALS['salt'] = 'salt';
5$GLOBALS['timezone'] = 'Europe/Paris';
6$GLOBALS['title'] = 'BIGBANG';
7$GLOBALS['titleLink'] = '?';
8$GLOBALS['redirector'] = 'lala';
9$GLOBALS['disablesessionprotection'] = false;
10$GLOBALS['privateLinkByDefault'] = true;
11$GLOBALS['config']['DATADIR'] = 'data';
12$GLOBALS['config']['DATASTORE'] = 'data/datastore.php';
13$GLOBALS['plugins']['WALLABAG_URL'] = 'ghf';
14$GLOBALS['plugins']['WALLABAG_VERSION'] = '1'; \ No newline at end of file