Elgg  Version 6.2
Config.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
7 use Elgg\Traits\Loggable;
8 
140 class Config {
141 
142  use Loggable;
143 
147  private $values;
148 
152  private $initial_values;
153 
157  private $cookies_configured = false;
158 
162  private $cookies = [];
163 
169  protected $locked_values = [
170  'assetroot',
171  'cacheroot',
172  'dataroot',
173  'installed',
174  'plugins_path',
175  'wwwroot',
176  ];
177 
183  protected $deprecated = [
184  ];
185 
191  protected $config_defaults = [
192  'admin_validation_notification' => false,
193  'allow_phpinfo' => false,
194  'authentication_failures_lifetime' => 600,
195  'authentication_failures_limit' => 5,
196  'auto_disable_plugins' => true,
197  'batch_run_time_in_secs' => 4,
198  'boot_cache_ttl' => 3600,
199  'can_change_username' => false,
200  'class_loader_verify_file_existence' => true,
201  'comment_box_collapses' => true,
202  'comments_group_only' => true,
203  'comments_latest_first' => true,
204  'comments_max_depth' => 0,
205  'comments_per_page' => 25,
206  'db_query_cache_limit' => 50,
207  'default_limit' => 10,
208  'elgg_maintenance_mode' => false,
209  'email_html_part' => true,
210  'email_html_part_images' => 'no',
211  'email_subject_limit' => 998,
212  'enable_delayed_email' => true,
213  'friendly_time_number_of_days' => 30,
214  'icon_sizes' => [
215  'topbar' => ['w' => 16, 'h' => 16, 'square' => true, 'upscale' => true],
216  'tiny' => ['w' => 25, 'h' => 25, 'square' => true, 'upscale' => true],
217  'small' => ['w' => 40, 'h' => 40, 'square' => true, 'upscale' => true],
218  'medium' => ['w' => 100, 'h' => 100, 'square' => true, 'upscale' => true],
219  'large' => ['w' => 200, 'h' => 200, 'square' => true, 'upscale' => true],
220  'master' => ['w' => 10240, 'h' => 10240, 'square' => false, 'upscale' => false, 'crop' => false],
221  ],
222  'language' => 'en',
223  'language_detect_from_browser' => true,
224  'lastcache' => 0,
225  'mentions_display_format' => 'display_name',
226  'message_delay' => 6,
227  'min_password_length' => 6,
228  'minusername' => 4,
229  'notifications_max_runtime' => 45,
230  'notifications_queue_delay' => 0,
231  'pagination_behaviour' => 'ajax-replace',
232  'require_admin_validation' => false,
233  'security_email_require_confirmation' => true,
234  'security_email_require_password' => true,
235  'security_notify_admins' => true,
236  'security_notify_user_password' => true,
237  'security_protect_upgrade' => true,
238  'session_bound_entity_icons' => false,
239  'simplecache_enabled' => false,
240  'subresource_integrity_enabled' => false,
241  'system_cache_enabled' => false,
242  'testing_mode' => false,
243  'trash_enabled' => false,
244  'trash_retention' => 30,
245  'user_joined_river' => false,
246  'webp_enabled' => true,
247  'who_can_change_language' => 'everyone',
248  ];
249 
255  protected $path_properties = [
256  'assetroot',
257  'cacheroot',
258  'dataroot',
259  'plugins_path',
260  ];
261 
267  const ENTITY_TYPES = ['group', 'object', 'site', 'user'];
268 
274  const SENSITIVE_PROPERTIES = [
275  '__site_secret__',
276  'db',
277  'dbhost',
278  'dbport',
279  'dbuser',
280  'dbpass',
281  'dbname',
282  ];
283 
289  public function __construct(array $values = []) {
290  $this->saveInitialValues($values);
291 
292  $this->values = array_merge($this->config_defaults, $values);
293 
294  // set cookie values for session and remember me
295  $this->getCookieConfig();
296  }
297 
305  protected function saveInitialValues(array $values): void {
306  // Don't keep copies of these in case config gets dumped
307  foreach (self::SENSITIVE_PROPERTIES as $name) {
308  unset($values[$name]);
309  }
310 
311  $this->initial_values = $values;
312  }
313 
321  public static function factory(string $settings_path = ''): static {
322  $settings_path = self::resolvePath($settings_path);
323 
324  return self::fromFile($settings_path);
325  }
326 
335  protected static function fromFile($path): static {
336  if (!is_file($path)) {
337  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not present.");
338  }
339 
340  if (!is_readable($path)) {
341  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not readable.");
342  }
343 
344  // legacy loading. If $CONFIG doesn't exist, remove it after the
345  // settings file is read.
346  if (isset($GLOBALS['CONFIG'])) {
347  // don't overwrite it
348  $global = $GLOBALS['CONFIG'];
349  unset($GLOBALS['CONFIG']);
350  } else {
351  $global = null;
352  }
353 
354  Includer::requireFile($path);
355 
356  if (empty($GLOBALS['CONFIG']->dataroot)) {
357  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->dataroot.');
358  }
359 
360  if (empty($GLOBALS['CONFIG']->wwwroot)) {
361  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->wwwroot.');
362  }
363 
364  $config = new self(get_object_vars($GLOBALS['CONFIG']));
365 
366  if ($global !== null) {
367  // restore
368  $GLOBALS['CONFIG'] = $global;
369  } else {
370  unset($GLOBALS['CONFIG']);
371  }
372 
373  if ($config->{'X-Sendfile-Type'}) {
374  $config->{'x_sendfile_type'} = $config->{'X-Sendfile-Type'};
375  unset($config->{'X-Sendfile-Type'});
376  }
377 
378  if ($config->{'X-Accel-Mapping'}) {
379  $config->{'x_accel_mapping'} = $config->{'X-Accel-Mapping'};
380  unset($config->{'X-Accel-Mapping'});
381  }
382 
383  return $config;
384  }
385 
393  public static function resolvePath(string $settings_path = ''): string {
394  if (empty($settings_path)) {
395  $settings_path = Paths::settingsFile(Paths::SETTINGS_PHP);
396  }
397 
398  return Paths::sanitize($settings_path, false);
399  }
400 
406  public function getValues(): array {
407  return $this->values;
408  }
409 
415  public function getCookieConfig(): array {
416  if ($this->cookies_configured) {
417  return $this->cookies;
418  }
419 
420  $cookies = [];
421  if ($this->hasInitialValue('cookies')) {
422  $cookies = $this->getInitialValue('cookies');
423  }
424 
425  // session cookie config
426  if (!isset($cookies['session'])) {
427  $cookies['session'] = [];
428  }
429 
430  $session_defaults = session_get_cookie_params();
431  $session_defaults['name'] = 'Elgg';
432  $cookies['session'] = array_merge($session_defaults, $cookies['session']);
433 
434  // remember me cookie config
435  if (!isset($cookies['remember_me'])) {
436  $cookies['remember_me'] = [];
437  }
438 
439  $session_defaults['name'] = 'elggperm';
440  $session_defaults['expire'] = strtotime('+30 days');
441  $cookies['remember_me'] = array_merge($session_defaults, $cookies['remember_me']);
442 
443  $this->cookies = $cookies;
444  $this->cookies_configured = true;
445 
446  return $cookies;
447  }
448 
458  public function __get(string $name) {
459 
460  if (array_key_exists($name, $this->deprecated)) {
461  elgg_deprecated_notice("Using '{$name}' from config has been deprecated", $this->deprecated[$name]);
462  }
463 
464  if (!isset($this->values[$name])) {
465  return null;
466  }
467 
468  $value = $this->values[$name];
469  if (in_array($name, $this->path_properties)) {
470  $value = Paths::sanitize($value);
471  }
472 
473  return $value;
474  }
475 
483  public function hasValue(string $name): bool {
484  return isset($this->values[$name]);
485  }
486 
493  public function getInitialValue(string $name) {
494  return $this->initial_values[$name] ?? null;
495  }
496 
504  public function hasInitialValue(string $name): bool {
505  return isset($this->initial_values[$name]);
506  }
507 
515  public function isLocked(string $name): bool {
516  $testing = $this->values['testing_mode'] ?? false;
517  return !$testing && in_array($name, $this->locked_values) && $this->hasValue($name);
518  }
519 
529  public function __set(string $name, $value): void {
530  if ($this->wasWarnedLocked($name)) {
531  return;
532  }
533 
534  if (in_array($name, $this->path_properties)) {
535  $value = Paths::sanitize($value);
536  }
537 
538  $this->values[$name] = $value;
539  }
540 
547  public function __isset(string $name): bool {
548  return $this->__get($name) !== null;
549  }
550 
557  public function __unset(string $name): void {
558  if ($this->wasWarnedLocked($name)) {
559  return;
560  }
561 
562  unset($this->values[$name]);
563  }
564 
573  public function save(string $name, $value): bool {
574  if ($this->wasWarnedLocked($name)) {
575  return false;
576  }
577 
578  if (strlen($name) > 255) {
579  $this->getLogger()->error('The name length for configuration variables cannot be greater than 255');
580  return false;
581  }
582 
583  if ($value === null) {
584  // don't save null values
585  return $this->remove($name);
586  }
587 
588  $result = _elgg_services()->configTable->set($name, $value);
589 
590  $this->__set($name, $value);
591 
592  return $result;
593  }
594 
602  public function remove(string $name): bool {
603  if ($this->wasWarnedLocked($name)) {
604  return false;
605  }
606 
607  $result = _elgg_services()->configTable->remove($name);
608 
609  unset($this->values[$name]);
610 
611  return $result;
612  }
613 
620  protected function wasWarnedLocked(string $name): bool {
621  if (!$this->isLocked($name)) {
622  return false;
623  }
624 
625  $this->getLogger()->warning("The property {$name} is read-only.");
626 
627  return true;
628  }
629 }
if(! $user||! $user->canDelete()) $name
Definition: delete.php:22
return[ 'admin/delete_admin_notices'=>['access'=> 'admin'], 'admin/menu/save'=>['access'=> 'admin'], 'admin/plugins/activate'=>['access'=> 'admin'], 'admin/plugins/activate_all'=>['access'=> 'admin'], 'admin/plugins/deactivate'=>['access'=> 'admin'], 'admin/plugins/deactivate_all'=>['access'=> 'admin'], 'admin/plugins/set_priority'=>['access'=> 'admin'], 'admin/security/security_txt'=>['access'=> 'admin'], 'admin/security/settings'=>['access'=> 'admin'], 'admin/security/regenerate_site_secret'=>['access'=> 'admin'], 'admin/site/cache/invalidate'=>['access'=> 'admin'], 'admin/site/flush_cache'=>['access'=> 'admin'], 'admin/site/icons'=>['access'=> 'admin'], 'admin/site/set_maintenance_mode'=>['access'=> 'admin'], 'admin/site/set_robots'=>['access'=> 'admin'], 'admin/site/theme'=>['access'=> 'admin'], 'admin/site/unlock_upgrade'=>['access'=> 'admin'], 'admin/site/settings'=>['access'=> 'admin'], 'admin/upgrade'=>['access'=> 'admin'], 'admin/upgrade/reset'=>['access'=> 'admin'], 'admin/user/ban'=>['access'=> 'admin'], 'admin/user/bulk/ban'=>['access'=> 'admin'], 'admin/user/bulk/delete'=>['access'=> 'admin'], 'admin/user/bulk/unban'=>['access'=> 'admin'], 'admin/user/bulk/validate'=>['access'=> 'admin'], 'admin/user/change_email'=>['access'=> 'admin'], 'admin/user/delete'=>['access'=> 'admin'], 'admin/user/login_as'=>['access'=> 'admin'], 'admin/user/logout_as'=>[], 'admin/user/makeadmin'=>['access'=> 'admin'], 'admin/user/resetpassword'=>['access'=> 'admin'], 'admin/user/removeadmin'=>['access'=> 'admin'], 'admin/user/unban'=>['access'=> 'admin'], 'admin/user/validate'=>['access'=> 'admin'], 'annotation/delete'=>[], 'avatar/upload'=>[], 'comment/save'=>[], 'diagnostics/download'=>['access'=> 'admin'], 'entity/chooserestoredestination'=>[], 'entity/delete'=>[], 'entity/mute'=>[], 'entity/restore'=>[], 'entity/subscribe'=>[], 'entity/trash'=>[], 'entity/unmute'=>[], 'entity/unsubscribe'=>[], 'login'=>['access'=> 'logged_out'], 'logout'=>[], 'notifications/mute'=>['access'=> 'public'], 'plugins/settings/remove'=>['access'=> 'admin'], 'plugins/settings/save'=>['access'=> 'admin'], 'plugins/usersettings/save'=>[], 'register'=>['access'=> 'logged_out', 'middleware'=>[\Elgg\Router\Middleware\RegistrationAllowedGatekeeper::class,],], 'river/delete'=>[], 'settings/notifications'=>[], 'settings/notifications/subscriptions'=>[], 'user/changepassword'=>['access'=> 'public'], 'user/requestnewpassword'=>['access'=> 'public'], 'useradd'=>['access'=> 'admin'], 'usersettings/save'=>[], 'widgets/add'=>[], 'widgets/delete'=>[], 'widgets/move'=>[], 'widgets/save'=>[],]
Definition: actions.php:73
foreach( $paths as $path)
Definition: autoloader.php:12
hasValue(string $name)
Test if we have a set value.
Definition: Config.php:483
isLocked(string $name)
Is this value locked?
Definition: Config.php:515
static fromFile($path)
Build a config from a file.
Definition: Config.php:335
__construct(array $values=[])
Constructor.
Definition: Config.php:289
getCookieConfig()
Set up and return the cookie configuration array resolved from settings.
Definition: Config.php:415
save(string $name, $value)
Save a configuration setting to the database.
Definition: Config.php:573
hasInitialValue(string $name)
Was a value available at construction time? (From settings.php)
Definition: Config.php:504
getInitialValue(string $name)
Get a value set at construction time.
Definition: Config.php:493
static factory(string $settings_path='')
Build a config from default settings locations.
Definition: Config.php:321
saveInitialValues(array $values)
Stores the inital values.
Definition: Config.php:305
static resolvePath(string $settings_path='')
Resolve settings path.
Definition: Config.php:393
wasWarnedLocked(string $name)
Log a read-only warning if the name is read-only.
Definition: Config.php:620
__set(string $name, $value)
Set an Elgg configuration value.
Definition: Config.php:529
__isset(string $name)
Handle isset()
Definition: Config.php:547
__unset(string $name)
Handle unset()
Definition: Config.php:557
getValues()
Get all values.
Definition: Config.php:406
__get(string $name)
Get an Elgg configuration value if it's been set or loaded during the boot process.
Definition: Config.php:458
A generic parent class for Configuration exceptions.
Find Elgg and project paths.
Definition: Paths.php:8
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
elgg_deprecated_notice(string $msg, string $dep_version)
Log a notice about deprecated use of a function, view, etc.
Definition: elgglib.php:117
_elgg_services()
Get the global service provider.
Definition: elgglib.php:353
$value
Definition: generic.php:51
$path
Definition: details.php:70
if(parse_url(elgg_get_site_url(), PHP_URL_PATH) !=='/') if(file_exists(elgg_get_root_path() . 'robots.txt'))
Set robots.txt.
Definition: robots.php:10
$CONFIG wwwroot
The installation root URL of the site.
if(!isset($CONFIG)) $CONFIG dataroot
The full file path for Elgg data storage.