Elgg  Version master
Config.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
7 use Elgg\Traits\Loggable;
8 
141 class Config {
142 
143  use Loggable;
144 
148  private $values;
149 
153  private $initial_values;
154 
158  private $cookies_configured = false;
159 
163  private $cookies = [];
164 
170  protected $locked_values = [
171  'assetroot',
172  'cacheroot',
173  'dataroot',
174  'installed',
175  'plugins_path',
176  'wwwroot',
177  ];
178 
184  protected $deprecated = [
185  ];
186 
192  protected $config_defaults = [
193  'admin_validation_notification' => false,
194  'allow_phpinfo' => false,
195  'authentication_failures_lifetime' => 600,
196  'authentication_failures_limit' => 5,
197  'auto_disable_plugins' => true,
198  'batch_run_time_in_secs' => 4,
199  'boot_cache_ttl' => 3600,
200  'can_change_username' => false,
201  'class_loader_verify_file_existence' => true,
202  'comment_box_collapses' => true,
203  'comments_group_only' => true,
204  'comments_latest_first' => true,
205  'comments_max_depth' => 0,
206  'comments_per_page' => 25,
207  'db_enable_query_logging' => false,
208  'db_query_cache_limit' => 50,
209  'default_limit' => 10,
210  'elgg_maintenance_mode' => false,
211  'email_html_part' => true,
212  'email_html_part_images' => 'no',
213  'email_subject_limit' => 998,
214  'enable_delayed_email' => true,
215  'friendly_time_number_of_days' => 30,
216  'icon_sizes' => [
217  'topbar' => ['w' => 16, 'h' => 16, 'square' => true, 'upscale' => true],
218  'tiny' => ['w' => 25, 'h' => 25, 'square' => true, 'upscale' => true],
219  'small' => ['w' => 40, 'h' => 40, 'square' => true, 'upscale' => true],
220  'medium' => ['w' => 100, 'h' => 100, 'square' => true, 'upscale' => true],
221  'large' => ['w' => 200, 'h' => 200, 'square' => true, 'upscale' => true],
222  'master' => ['w' => 10240, 'h' => 10240, 'square' => false, 'upscale' => false, 'crop' => false],
223  ],
224  'language' => 'en',
225  'language_detect_from_browser' => true,
226  'lastcache' => 0,
227  'mentions_display_format' => 'display_name',
228  'message_delay' => 6,
229  'min_password_length' => 6,
230  'minusername' => 4,
231  'notifications_max_runtime' => 45,
232  'notifications_queue_delay' => 0,
233  'pagination_behaviour' => 'ajax-replace',
234  'require_admin_validation' => false,
235  'security_email_require_confirmation' => true,
236  'security_email_require_password' => true,
237  'security_notify_admins' => true,
238  'security_notify_user_password' => true,
239  'security_protect_upgrade' => true,
240  'session_bound_entity_icons' => false,
241  'simplecache_enabled' => false,
242  'subresource_integrity_enabled' => false,
243  'system_cache_enabled' => false,
244  'testing_mode' => false,
245  'trash_enabled' => false,
246  'trash_retention' => 30,
247  'user_joined_river' => false,
248  'webp_enabled' => true,
249  'who_can_change_language' => 'everyone',
250  ];
251 
257  protected $path_properties = [
258  'assetroot',
259  'cacheroot',
260  'dataroot',
261  'plugins_path',
262  ];
263 
269  const ENTITY_TYPES = ['group', 'object', 'site', 'user'];
270 
276  const SENSITIVE_PROPERTIES = [
277  '__site_secret__',
278  'db',
279  'dbhost',
280  'dbport',
281  'dbuser',
282  'dbpass',
283  'dbname',
284  ];
285 
291  public function __construct(array $values = []) {
292  $this->saveInitialValues($values);
293 
294  $this->values = array_merge($this->config_defaults, $values);
295 
296  // set cookie values for session and remember me
297  $this->getCookieConfig();
298  }
299 
307  protected function saveInitialValues(array $values): void {
308  // Don't keep copies of these in case config gets dumped
309  foreach (self::SENSITIVE_PROPERTIES as $name) {
310  unset($values[$name]);
311  }
312 
313  $this->initial_values = $values;
314  }
315 
323  public static function factory(string $settings_path = ''): static {
324  $settings_path = self::resolvePath($settings_path);
325 
326  return self::fromFile($settings_path);
327  }
328 
337  protected static function fromFile($path): static {
338  if (!is_file($path)) {
339  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not present.");
340  }
341 
342  if (!is_readable($path)) {
343  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not readable.");
344  }
345 
346  // legacy loading. If $CONFIG doesn't exist, remove it after the
347  // settings file is read.
348  if (isset($GLOBALS['CONFIG'])) {
349  // don't overwrite it
350  $global = $GLOBALS['CONFIG'];
351  unset($GLOBALS['CONFIG']);
352  } else {
353  $global = null;
354  }
355 
356  Includer::requireFile($path);
357 
358  if (empty($GLOBALS['CONFIG']->dataroot)) {
359  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->dataroot.');
360  }
361 
362  if (empty($GLOBALS['CONFIG']->wwwroot)) {
363  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->wwwroot.');
364  }
365 
366  $config = new self(get_object_vars($GLOBALS['CONFIG']));
367 
368  if ($global !== null) {
369  // restore
370  $GLOBALS['CONFIG'] = $global;
371  } else {
372  unset($GLOBALS['CONFIG']);
373  }
374 
375  if ($config->{'X-Sendfile-Type'}) {
376  $config->{'x_sendfile_type'} = $config->{'X-Sendfile-Type'};
377  unset($config->{'X-Sendfile-Type'});
378  }
379 
380  if ($config->{'X-Accel-Mapping'}) {
381  $config->{'x_accel_mapping'} = $config->{'X-Accel-Mapping'};
382  unset($config->{'X-Accel-Mapping'});
383  }
384 
385  return $config;
386  }
387 
395  public static function resolvePath(string $settings_path = ''): string {
396  if (empty($settings_path)) {
397  $settings_path = Paths::settingsFile(Paths::SETTINGS_PHP);
398  }
399 
400  return Paths::sanitize($settings_path, false);
401  }
402 
408  public function getValues(): array {
409  return $this->values;
410  }
411 
417  public function getCookieConfig(): array {
418  if ($this->cookies_configured) {
419  return $this->cookies;
420  }
421 
422  $cookies = [];
423  if ($this->hasInitialValue('cookies')) {
424  $cookies = $this->getInitialValue('cookies');
425  }
426 
427  // session cookie config
428  if (!isset($cookies['session'])) {
429  $cookies['session'] = [];
430  }
431 
432  $session_defaults = session_get_cookie_params();
433  $session_defaults['name'] = 'Elgg';
434  $cookies['session'] = array_merge($session_defaults, $cookies['session']);
435 
436  // remember me cookie config
437  if (!isset($cookies['remember_me'])) {
438  $cookies['remember_me'] = [];
439  }
440 
441  $session_defaults['name'] = 'elggperm';
442  $session_defaults['expire'] = strtotime('+30 days');
443  $cookies['remember_me'] = array_merge($session_defaults, $cookies['remember_me']);
444 
445  $this->cookies = $cookies;
446  $this->cookies_configured = true;
447 
448  return $cookies;
449  }
450 
460  public function __get(string $name) {
461 
462  if (array_key_exists($name, $this->deprecated)) {
463  elgg_deprecated_notice("Using '{$name}' from config has been deprecated", $this->deprecated[$name]);
464  }
465 
466  if (!isset($this->values[$name])) {
467  return null;
468  }
469 
470  $value = $this->values[$name];
471  if (in_array($name, $this->path_properties)) {
472  $value = Paths::sanitize($value);
473  }
474 
475  return $value;
476  }
477 
485  public function hasValue(string $name): bool {
486  return isset($this->values[$name]);
487  }
488 
495  public function getInitialValue(string $name) {
496  return $this->initial_values[$name] ?? null;
497  }
498 
506  public function hasInitialValue(string $name): bool {
507  return isset($this->initial_values[$name]);
508  }
509 
517  public function isLocked(string $name): bool {
518  $testing = $this->values['testing_mode'] ?? false;
519  return !$testing && in_array($name, $this->locked_values) && $this->hasValue($name);
520  }
521 
531  public function __set(string $name, $value): void {
532  if ($this->wasWarnedLocked($name)) {
533  return;
534  }
535 
536  if (in_array($name, $this->path_properties)) {
537  $value = Paths::sanitize($value);
538  }
539 
540  $this->values[$name] = $value;
541  }
542 
549  public function __isset(string $name): bool {
550  return $this->__get($name) !== null;
551  }
552 
559  public function __unset(string $name): void {
560  if ($this->wasWarnedLocked($name)) {
561  return;
562  }
563 
564  unset($this->values[$name]);
565  }
566 
575  public function save(string $name, $value): bool {
576  if ($this->wasWarnedLocked($name)) {
577  return false;
578  }
579 
580  if (strlen($name) > 255) {
581  $this->getLogger()->error('The name length for configuration variables cannot be greater than 255');
582  return false;
583  }
584 
585  if ($value === null) {
586  // don't save null values
587  return $this->remove($name);
588  }
589 
590  $result = _elgg_services()->configTable->set($name, $value);
591 
592  $this->__set($name, $value);
593 
594  return $result;
595  }
596 
604  public function remove(string $name): bool {
605  if ($this->wasWarnedLocked($name)) {
606  return false;
607  }
608 
609  $result = _elgg_services()->configTable->remove($name);
610 
611  unset($this->values[$name]);
612 
613  return $result;
614  }
615 
622  protected function wasWarnedLocked(string $name): bool {
623  if (!$this->isLocked($name)) {
624  return false;
625  }
626 
627  $this->getLogger()->warning("The property {$name} is read-only.");
628 
629  return true;
630  }
631 }
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:485
isLocked(string $name)
Is this value locked?
Definition: Config.php:517
static fromFile($path)
Build a config from a file.
Definition: Config.php:337
__construct(array $values=[])
Constructor.
Definition: Config.php:291
getCookieConfig()
Set up and return the cookie configuration array resolved from settings.
Definition: Config.php:417
save(string $name, $value)
Save a configuration setting to the database.
Definition: Config.php:575
hasInitialValue(string $name)
Was a value available at construction time? (From settings.php)
Definition: Config.php:506
getInitialValue(string $name)
Get a value set at construction time.
Definition: Config.php:495
static factory(string $settings_path='')
Build a config from default settings locations.
Definition: Config.php:323
saveInitialValues(array $values)
Stores the inital values.
Definition: Config.php:307
static resolvePath(string $settings_path='')
Resolve settings path.
Definition: Config.php:395
wasWarnedLocked(string $name)
Log a read-only warning if the name is read-only.
Definition: Config.php:622
__set(string $name, $value)
Set an Elgg configuration value.
Definition: Config.php:531
__isset(string $name)
Handle isset()
Definition: Config.php:549
__unset(string $name)
Handle unset()
Definition: Config.php:559
getValues()
Get all values.
Definition: Config.php:408
__get(string $name)
Get an Elgg configuration value if it's been set or loaded during the boot process.
Definition: Config.php:460
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:101
_elgg_services()
Get the global service provider.
Definition: elgglib.php:337
$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.