These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace Elgg; |
||
3 | |||
4 | use Elgg\Config\DatarootSettingMigrator; |
||
5 | use Elgg\Config\SettingsMigrator; |
||
6 | use Elgg\Config\WwwrootSettingMigrator; |
||
7 | use Elgg\Filesystem\Directory; |
||
8 | use Elgg\Database\ConfigTable; |
||
9 | |||
10 | /** |
||
11 | * Access to configuration values |
||
12 | * |
||
13 | * @since 1.10.0 |
||
14 | * |
||
15 | * @property int $action_time_limit |
||
16 | * @property int $action_token_timeout |
||
17 | * @property bool $allow_registration |
||
18 | * @property string $allow_user_default_access |
||
19 | * @property bool $auto_disable_plugins |
||
20 | * @property int $batch_run_time_in_secs |
||
21 | * @property bool $boot_complete |
||
22 | * @property int $boot_cache_ttl |
||
23 | * @property array $breadcrumbs |
||
24 | * @property string $cacheroot Path of cache storage with trailing "/" |
||
25 | * @property string $dataroot Path of data storage with trailing "/" |
||
26 | * @property bool $data_dir_override |
||
27 | * @property array $db |
||
28 | * @property string $dbencoding |
||
29 | * @property string $dbname |
||
30 | * @property string $dbuser |
||
31 | * @property string $dbhost |
||
32 | * @property string $dbpass |
||
33 | * @property string $dbprefix |
||
34 | * @property string $debug |
||
35 | * @property int $default_access |
||
36 | * @property int $default_limit |
||
37 | * @property array $default_widget_info |
||
38 | * @property bool $elgg_config_locks The application will lock some settings (default true) |
||
39 | * @property string[] $elgg_cron_periods |
||
40 | * @property bool $elgg_load_sync_code |
||
41 | * @property bool $elgg_maintenance_mode |
||
42 | * @property string $elgg_settings_file |
||
43 | 196 | * @property bool $enable_profiling |
|
44 | 196 | * @property mixed $embed_tab |
|
45 | * @property string $exception_include |
||
46 | * @property string[] $group |
||
47 | 196 | * @property array $group_tool_options |
|
48 | 196 | * @property bool $i18n_loaded_from_cache |
|
49 | * @property array $icon_sizes |
||
50 | 196 | * @property string $installed |
|
51 | * @property bool $installer_running |
||
52 | * @property string $language Site language code |
||
53 | * @property int $lastcache |
||
54 | * @property \ElggLogCache $log_cache |
||
55 | * @property array $libraries |
||
56 | * @property bool $memcache |
||
57 | * @property array $memcache_servers |
||
58 | * @property array $menus |
||
59 | * @property int $min_password_length |
||
60 | * @property string[] $pages |
||
61 | * @property-read string $path Path of composer install with trailing "/" |
||
62 | * @property-read string $pluginspath Alias of plugins_path |
||
63 | * @property-read string $plugins_path Path of project "mod/" directory |
||
64 | 196 | * @property array $profile_custom_fields |
|
65 | 196 | * @property array $profile_fields |
|
66 | * @property string $profiling_minimum_percentage |
||
67 | 196 | * @property bool $profiling_sql |
|
68 | * @property array $processed_upgrades |
||
69 | * @property string[] $registered_entities |
||
70 | * @property bool $security_disable_password_autocomplete |
||
71 | * @property bool $security_email_require_password |
||
72 | 461 | * @property bool $security_notify_admins |
|
73 | 461 | * @property bool $security_notify_user_admin |
|
74 | * @property bool $security_notify_user_ban |
||
75 | * @property bool $security_protect_cron |
||
76 | * @property bool $security_protect_upgrade |
||
77 | * @property int $simplecache_enabled |
||
78 | * @property int $simplecache_lastupdate |
||
79 | * @property bool $simplecache_minify_css |
||
80 | * @property bool $simplecache_minify_js |
||
81 | * @property \ElggSite $site |
||
82 | * @property string $sitedescription |
||
83 | * @property string $sitename |
||
84 | * @property string[] $site_custom_menu_items |
||
85 | * @property string[] $site_featured_menu_names |
||
86 | * @property-read int $site_guid |
||
87 | * @property bool $system_cache_enabled |
||
88 | 353 | * @property bool $system_cache_loaded |
|
89 | 353 | * @property string $url Alias of "wwwroot" |
|
90 | * @property int $version |
||
91 | 353 | * @property string $view Default viewtype (usually not set) |
|
92 | 157 | * @property bool $walled_garden |
|
93 | * @property string $wwwroot Site URL |
||
94 | * @property bool $_boot_cache_hit |
||
95 | 196 | * @property bool $_elgg_autofeed |
|
96 | */ |
||
97 | class Config implements Services\Config { |
||
98 | 196 | /** |
|
99 | * Configuration storage. Is usually reference to global $CONFIG |
||
100 | * |
||
101 | 196 | * @var \stdClass |
|
102 | */ |
||
103 | private $config; |
||
104 | 196 | ||
105 | 196 | /** |
|
106 | 196 | * @var bool |
|
107 | 196 | */ |
|
108 | private $settings_loaded = false; |
||
109 | |||
110 | 196 | /** |
|
111 | 196 | * @var bool |
|
112 | 196 | */ |
|
113 | private $cookies_configured = false; |
||
114 | 196 | ||
115 | /** |
||
116 | 196 | * @var ConfigTable Do not use directly. Use getConfigTable(). |
|
117 | */ |
||
118 | private $config_table; |
||
119 | |||
120 | /** |
||
121 | * Constructor |
||
122 | 18 | * |
|
123 | 18 | * @internal Access this object via Elgg\Application::$config |
|
124 | 18 | * |
|
125 | * @param \stdClass $config Elgg's $CONFIG object |
||
126 | * @param bool $set_global Copy the config object to global $CONFIG |
||
127 | */ |
||
128 | public function __construct(\stdClass $config = null, $set_global = true) { |
||
129 | if (!$config) { |
||
130 | 2 | $config = new \stdClass(); |
|
131 | 2 | } |
|
132 | 2 | $this->config = $config; |
|
133 | $this->config->path = Directory\Local::root()->getPath('/'); |
||
134 | |||
135 | if ($set_global) { |
||
136 | /** |
||
137 | * Configuration values. |
||
138 | 409 | * |
|
139 | 409 | * The $CONFIG global contains configuration values required |
|
140 | * for running Elgg as defined in the settings.php file. |
||
141 | 409 | * |
|
142 | 309 | * Plugin authors are encouraged to use elgg_get_config() instead of accessing |
|
143 | * the global directly. |
||
144 | * |
||
145 | 255 | * @see elgg_get_config() |
|
146 | 255 | * @see engine/settings.php |
|
147 | * @global \stdClass $CONFIG |
||
148 | */ |
||
149 | global $CONFIG; |
||
150 | $CONFIG = $config; |
||
151 | } |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * {@inheritdoc} |
||
156 | */ |
||
157 | public function getSiteUrl() { |
||
158 | return $this->config->wwwroot; |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * {@inheritdoc} |
||
163 | 211 | */ |
|
164 | 211 | public function getPluginsPath() { |
|
165 | return $this->config->pluginspath; |
||
166 | } |
||
167 | |||
168 | /** |
||
169 | * Set up and return the cookie configuration array resolved from settings.php |
||
170 | 270 | * |
|
171 | 270 | * @return array |
|
172 | 270 | */ |
|
173 | 270 | public function getCookieConfig() { |
|
174 | $c = $this->config; |
||
175 | |||
176 | if ($this->cookies_configured) { |
||
177 | return $c->cookies; |
||
178 | } |
||
179 | |||
180 | $this->loadSettingsFile(); |
||
181 | |||
182 | // set cookie values for session and remember me |
||
183 | if (!isset($c->cookies)) { |
||
184 | $c->cookies = []; |
||
185 | } |
||
186 | if (!isset($c->cookies['session'])) { |
||
187 | $c->cookies['session'] = []; |
||
188 | } |
||
189 | $session_defaults = session_get_cookie_params(); |
||
190 | $session_defaults['name'] = 'Elgg'; |
||
191 | $c->cookies['session'] = array_merge($session_defaults, $c->cookies['session']); |
||
192 | if (!isset($c->cookies['remember_me'])) { |
||
193 | $c->cookies['remember_me'] = []; |
||
194 | } |
||
195 | $session_defaults['name'] = 'elggperm'; |
||
196 | $session_defaults['expire'] = strtotime("+30 days"); |
||
197 | $c->cookies['remember_me'] = array_merge($session_defaults, $c->cookies['remember_me']); |
||
198 | |||
199 | $this->cookies_configured = true; |
||
200 | |||
201 | return $c->cookies; |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * {@inheritdoc} |
||
206 | */ |
||
207 | public function getDataPath() { |
||
208 | $this->loadSettingsFile(); |
||
209 | return $this->config->dataroot; |
||
210 | } |
||
211 | |||
212 | /** |
||
213 | * {@inheritdoc} |
||
214 | */ |
||
215 | public function getCachePath() { |
||
216 | $this->loadSettingsFile(); |
||
217 | return $this->config->cacheroot; |
||
218 | } |
||
219 | |||
220 | /** |
||
221 | * {@inheritdoc} |
||
222 | */ |
||
223 | 216 | public function get($name, $default = null) { |
|
224 | 216 | $name = trim($name); |
|
225 | 216 | ||
226 | if (isset($this->config->$name)) { |
||
227 | return $this->config->$name; |
||
228 | 196 | } |
|
229 | 196 | ||
230 | 196 | if (!empty($this->config->site_config_loaded)) { |
|
231 | 196 | return $default; |
|
232 | } |
||
233 | |||
234 | $value = $this->getConfigTable()->get($name); |
||
235 | |||
236 | if ($value === null) { |
||
237 | return $default; |
||
238 | } |
||
239 | |||
240 | $this->config->$name = $value; |
||
241 | |||
242 | return $value; |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * Use get() to read a property |
||
247 | * |
||
248 | * @param string $name Name |
||
249 | * @return mixed |
||
250 | */ |
||
251 | public function __get($name) { |
||
252 | return $this->get($name); |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * {@inheritdoc} |
||
257 | */ |
||
258 | public function getVolatile($name) { |
||
259 | return isset($this->config->{$name}) ? $this->config->{$name} : null; |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * {@inheritdoc} |
||
264 | */ |
||
265 | public function set($name, $value) { |
||
266 | $name = trim($name); |
||
267 | $this->config->$name = $value; |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * Set an Elgg configuration value |
||
272 | * |
||
273 | * @warning This does not persist the configuration setting. Use elgg_save_config() |
||
274 | * |
||
275 | * @param string $name Name |
||
276 | * @param mixed $value Value |
||
277 | * @return void |
||
278 | */ |
||
279 | public function __set($name, $value) { |
||
280 | $this->set($name, $value); |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Handle isset() |
||
285 | * |
||
286 | * @param string $name Name |
||
287 | * @return bool |
||
288 | */ |
||
289 | public function __isset($name) { |
||
290 | return $this->get($name) !== null; |
||
291 | } |
||
292 | |||
293 | /** |
||
294 | * Handle unset() |
||
295 | * |
||
296 | * @param string $name Name |
||
297 | * @return void |
||
298 | */ |
||
299 | public function __unset($name) { |
||
300 | unset($this->config->{$name}); |
||
301 | } |
||
302 | 200 | ||
303 | 200 | /** |
|
304 | * {@inheritdoc} |
||
305 | */ |
||
306 | public function save($name, $value) { |
||
307 | $name = trim($name); |
||
308 | |||
309 | if (strlen($name) > 255) { |
||
310 | _elgg_services()->logger->error("The name length for configuration variables cannot be greater than 255"); |
||
311 | return false; |
||
312 | } |
||
313 | |||
314 | $result = $this->getConfigTable()->set($name, $value); |
||
315 | |||
316 | $this->set($name, $value); |
||
317 | 196 | ||
318 | 196 | return $result; |
|
319 | 196 | } |
|
320 | |||
321 | /** |
||
322 | * {@inheritdoc} |
||
323 | */ |
||
324 | public function remove($name) { |
||
325 | $name = trim($name); |
||
326 | |||
327 | $result = $this->getConfigTable()->remove($name); |
||
328 | |||
329 | unset($this->config->$name); |
||
330 | |||
331 | return $result; |
||
332 | } |
||
333 | |||
334 | /** |
||
335 | * Get expected settings file paths |
||
336 | * |
||
337 | * @return string[] |
||
338 | * @array private |
||
339 | */ |
||
340 | public function getSettingsPaths() { |
||
341 | $root = Directory\Local::root(); |
||
342 | return [ |
||
343 | $root->getPath('engine/settings.php'), |
||
344 | $root->getPath('elgg-config/settings.php'), |
||
345 | ]; |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * {@inheritdoc} |
||
350 | */ |
||
351 | public function loadSettingsFile() { |
||
0 ignored issues
–
show
|
|||
352 | if ($this->settings_loaded) { |
||
353 | return; |
||
354 | } |
||
355 | |||
356 | if (isset($this->config->Config_file)) { |
||
357 | if ($this->config->Config_file === false) { |
||
358 | $this->settings_loaded = true; |
||
359 | return; |
||
360 | } |
||
361 | $path = $this->config->Config_file; |
||
362 | } else { |
||
363 | foreach ($this->getSettingsPaths() as $path) { |
||
364 | if (is_file($path)) { |
||
365 | break; |
||
366 | } |
||
367 | } |
||
368 | } |
||
369 | |||
370 | // No settings means a fresh install |
||
371 | if (!is_file($path)) { |
||
0 ignored issues
–
show
The variable
$path does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
372 | if ($this->getVolatile('installer_running')) { |
||
373 | $this->settings_loaded = true; |
||
374 | return; |
||
375 | } |
||
376 | |||
377 | header("Location: install.php"); |
||
378 | exit; |
||
379 | } |
||
380 | |||
381 | if (!is_readable($path)) { |
||
382 | throw new \RuntimeException("The Elgg settings file exists but the web server doesn't have read permission to it."); |
||
383 | } |
||
384 | |||
385 | // we assume settings is going to write to CONFIG, but we may need to copy its values |
||
386 | // into our local config |
||
387 | global $CONFIG; |
||
388 | $global_is_bound = (isset($CONFIG) && $CONFIG === $this->config); |
||
389 | |||
390 | require_once $path; |
||
391 | |||
392 | $get_db = function() use ($CONFIG) { |
||
393 | // try to migrate settings to the file |
||
394 | $db_conf = new \Elgg\Database\Config($CONFIG); |
||
395 | return new Database($db_conf); |
||
396 | }; |
||
397 | |||
398 | if (empty($CONFIG->dataroot)) { |
||
399 | $dataroot = (new DatarootSettingMigrator($get_db(), $path))->migrate(); |
||
400 | if (isset($dataroot)) { |
||
401 | $CONFIG->dataroot = $dataroot; |
||
402 | } else { |
||
403 | throw new \RuntimeException('The Elgg settings file is missing $CONFIG->dataroot.'); |
||
404 | } |
||
405 | } |
||
406 | |||
407 | // normalize commonly needed values |
||
408 | $CONFIG->dataroot = rtrim($CONFIG->dataroot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; |
||
409 | |||
410 | if (!isset($CONFIG->wwwroot)) { |
||
411 | $wwwroot = (new WwwrootSettingMigrator($get_db(), $path))->migrate(); |
||
412 | if (isset($wwwroot)) { |
||
413 | $CONFIG->wwwroot = $wwwroot; |
||
414 | } |
||
415 | } |
||
416 | |||
417 | $GLOBALS['_ELGG']->simplecache_enabled_in_settings = isset($CONFIG->simplecache_enabled); |
||
418 | |||
419 | if (empty($CONFIG->cacheroot)) { |
||
420 | $CONFIG->cacheroot = $CONFIG->dataroot; |
||
421 | } else { |
||
422 | $CONFIG->cacheroot = rtrim($CONFIG->cacheroot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; |
||
423 | } |
||
424 | |||
425 | if (!$global_is_bound) { |
||
426 | // must manually copy settings into our storage |
||
427 | foreach ($CONFIG as $key => $value) { |
||
428 | $this->config->{$key} = $value; |
||
429 | } |
||
430 | } |
||
431 | |||
432 | $this->settings_loaded = true; |
||
433 | } |
||
434 | |||
435 | /** |
||
436 | * Get the raw \stdClass object used for storage. |
||
437 | * |
||
438 | * We need this, for now, to construct some services. |
||
439 | * |
||
440 | * @internal Do not use this plugins or new core code! |
||
441 | * @todo Get rid of this. |
||
442 | * |
||
443 | * @return \stdClass |
||
444 | * @access private |
||
445 | */ |
||
446 | public function getStorageObject() { |
||
447 | return $this->config; |
||
448 | } |
||
449 | |||
450 | /** |
||
451 | * Set the config table service (must be set) |
||
452 | * |
||
453 | * This is a necessary evil until we refactor so that the service provider has no dependencies. |
||
454 | * |
||
455 | * @param ConfigTable $table |
||
456 | * @return void |
||
457 | * |
||
458 | * @access private |
||
459 | * @internal |
||
460 | */ |
||
461 | public function setConfigTable(ConfigTable $table) { |
||
462 | $this->config_table = $table; |
||
463 | } |
||
464 | |||
465 | /** |
||
466 | * Get the config table API |
||
467 | * |
||
468 | * @return ConfigTable |
||
469 | */ |
||
470 | private function getConfigTable() { |
||
471 | if (!$this->config_table) { |
||
472 | if (!function_exists('_elgg_services')) { |
||
473 | throw new \RuntimeException('setConfigTable() must be called before using API that' . |
||
474 | ' uses the database.'); |
||
475 | } |
||
476 | |||
477 | $this->config_table = _elgg_services()->configTable; |
||
478 | } |
||
479 | |||
480 | return $this->config_table; |
||
481 | } |
||
482 | } |
||
483 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: