]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - application/Config.php
9af5a535a5b9181e0c02457fa206a49c7b26e60e
[github/shaarli/Shaarli.git] / application / Config.php
1 <?php
2 /**
3 * Functions related to configuration management.
4 */
5
6 /**
7 * Re-write configuration file according to given array.
8 * Requires mandatory fields listed in $MANDATORY_FIELDS.
9 *
10 * @param array $config contains all configuration fields.
11 * @param bool $isLoggedIn true if user is logged in.
12 *
13 * @return void
14 *
15 * @throws MissingFieldConfigException: a mandatory field has not been provided in $config.
16 * @throws UnauthorizedConfigException: user is not authorize to change configuration.
17 * @throws Exception: an error occured while writing the new config file.
18 */
19 function writeConfig($config, $isLoggedIn)
20 {
21 // These fields are required in configuration.
22 $MANDATORY_FIELDS = array(
23 'login', 'hash', 'salt', 'timezone', 'title', 'titleLink',
24 'redirector', 'disablesessionprotection', 'privateLinkByDefault'
25 );
26
27 if (!isset($config['config']['CONFIG_FILE'])) {
28 throw new MissingFieldConfigException('CONFIG_FILE');
29 }
30
31 // Only logged in user can alter config.
32 if (is_file($config['config']['CONFIG_FILE']) && !$isLoggedIn) {
33 throw new UnauthorizedConfigException();
34 }
35
36 // Check that all mandatory fields are provided in $config.
37 foreach ($MANDATORY_FIELDS as $field) {
38 if (!isset($config[$field])) {
39 throw new MissingFieldConfigException($field);
40 }
41 }
42
43 $configStr = '<?php '. PHP_EOL;
44 $configStr .= '$GLOBALS[\'login\'] = '.var_export($config['login'], true).';'. PHP_EOL;
45 $configStr .= '$GLOBALS[\'hash\'] = '.var_export($config['hash'], true).';'. PHP_EOL;
46 $configStr .= '$GLOBALS[\'salt\'] = '.var_export($config['salt'], true).'; '. PHP_EOL;
47 $configStr .= '$GLOBALS[\'timezone\'] = '.var_export($config['timezone'], true).';'. PHP_EOL;
48 $configStr .= 'date_default_timezone_set('.var_export($config['timezone'], true).');'. PHP_EOL;
49 $configStr .= '$GLOBALS[\'title\'] = '.var_export($config['title'], true).';'. PHP_EOL;
50 $configStr .= '$GLOBALS[\'titleLink\'] = '.var_export($config['titleLink'], true).'; '. PHP_EOL;
51 $configStr .= '$GLOBALS[\'redirector\'] = '.var_export($config['redirector'], true).'; '. PHP_EOL;
52 $configStr .= '$GLOBALS[\'disablesessionprotection\'] = '.var_export($config['disablesessionprotection'], true).'; '. PHP_EOL;
53 $configStr .= '$GLOBALS[\'privateLinkByDefault\'] = '.var_export($config['privateLinkByDefault'], true).'; '. PHP_EOL;
54
55 // Store all $config['config']
56 foreach ($config['config'] as $key => $value) {
57 $configStr .= '$GLOBALS[\'config\'][\''. $key .'\'] = '.var_export($config['config'][$key], true).';'. PHP_EOL;
58 }
59
60 if (isset($config['plugins'])) {
61 foreach ($config['plugins'] as $key => $value) {
62 $configStr .= '$GLOBALS[\'plugins\'][\''. $key .'\'] = '.var_export($config['plugins'][$key], true).';'. PHP_EOL;
63 }
64 }
65
66 if (!file_put_contents($config['config']['CONFIG_FILE'], $configStr)
67 || strcmp(file_get_contents($config['config']['CONFIG_FILE']), $configStr) != 0
68 ) {
69 throw new Exception(
70 'Shaarli could not create the config file.
71 Please make sure Shaarli has the right to write in the folder is it installed in.'
72 );
73 }
74 }
75
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 */
85 function 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 */
133 function 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 */
158 function 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 /**
177 * Milestone 0.9 - shaarli/Shaarli#41: options.php is not supported anymore.
178 * ==> if user is loggedIn, merge its content with config.php, then delete options.php.
179 *
180 * @param array $config contains all configuration fields.
181 * @param bool $isLoggedIn true if user is logged in.
182 *
183 * @return void
184 */
185 function mergeDeprecatedConfig($config, $isLoggedIn)
186 {
187 $config_file = $config['config']['CONFIG_FILE'];
188
189 if (is_file($config['config']['DATADIR'].'/options.php') && $isLoggedIn) {
190 include $config['config']['DATADIR'].'/options.php';
191
192 // Load GLOBALS into config
193 foreach ($GLOBALS as $key => $value) {
194 $config[$key] = $value;
195 }
196 $config['config']['CONFIG_FILE'] = $config_file;
197 writeConfig($config, $isLoggedIn);
198
199 unlink($config['config']['DATADIR'].'/options.php');
200 }
201 }
202
203 /**
204 * Exception used if a mandatory field is missing in given configuration.
205 */
206 class MissingFieldConfigException extends Exception
207 {
208 public $field;
209
210 /**
211 * Construct exception.
212 *
213 * @param string $field field name missing.
214 */
215 public function __construct($field)
216 {
217 $this->field = $field;
218 $this->message = 'Configuration value is required for '. $this->field;
219 }
220 }
221
222 /**
223 * Exception used if an unauthorized attempt to edit configuration has been made.
224 */
225 class UnauthorizedConfigException extends Exception
226 {
227 /**
228 * Construct exception.
229 */
230 public function __construct()
231 {
232 $this->message = 'You are not authorized to alter config.';
233 }
234 }
235
236 /**
237 * Exception used if an error occur while saving plugin configuration.
238 */
239 class 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 }