Elgg  Version 6.3
Config.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
7 use Elgg\Traits\Loggable;
8 
144 class Config {
145 
146  use Loggable;
147 
151  private $values;
152 
156  private $initial_values;
157 
161  private $cookies_configured = false;
162 
166  private $cookies = [];
167 
173  protected $locked_values = [
174  'assetroot',
175  'cacheroot',
176  'dataroot',
177  'installed',
178  'plugins_path',
179  'wwwroot',
180  ];
181 
187  protected $deprecated = [
188  ];
189 
195  protected $config_defaults = [
196  'admin_validation_notification' => false,
197  'allow_phpinfo' => false,
198  'authentication_failures_lifetime' => 600,
199  'authentication_failures_limit' => 5,
200  'auto_disable_plugins' => true,
201  'batch_run_time_in_secs' => 4,
202  'boot_cache_ttl' => 3600,
203  'can_change_username' => false,
204  'class_loader_verify_file_existence' => true,
205  'comment_box_collapses' => true,
206  'comments_group_only' => true,
207  'comments_latest_first' => true,
208  'comments_max_depth' => 0,
209  'comments_per_page' => 25,
210  'db_enable_query_logging' => false,
211  'db_query_cache_limit' => 50,
212  'default_limit' => 10,
213  'elgg_maintenance_mode' => false,
214  'email_html_part' => true,
215  'email_html_part_images' => 'no',
216  'email_subject_limit' => 998,
217  'enable_delayed_email' => true,
218  'friendly_time_number_of_days' => 30,
219  'icon_sizes' => [
220  'topbar' => ['w' => 16, 'h' => 16, 'square' => true, 'upscale' => true],
221  'tiny' => ['w' => 25, 'h' => 25, 'square' => true, 'upscale' => true],
222  'small' => ['w' => 40, 'h' => 40, 'square' => true, 'upscale' => true],
223  'medium' => ['w' => 100, 'h' => 100, 'square' => true, 'upscale' => true],
224  'large' => ['w' => 200, 'h' => 200, 'square' => true, 'upscale' => true],
225  'master' => ['w' => 10240, 'h' => 10240, 'square' => false, 'upscale' => false, 'crop' => false],
226  ],
227  'image_resize_max_height' => 10000,
228  'image_resize_max_resolution' => 16777216, // 16MP
229  'image_resize_max_width' => 10000,
230  'language' => 'en',
231  'language_detect_from_browser' => true,
232  'lastcache' => 0,
233  'mentions_display_format' => 'display_name',
234  'message_delay' => 6,
235  'min_password_length' => 6,
236  'minusername' => 4,
237  'notifications_max_runtime' => 45,
238  'notifications_queue_delay' => 0,
239  'pagination_behaviour' => 'ajax-replace',
240  'require_admin_validation' => false,
241  'security_email_require_confirmation' => true,
242  'security_email_require_password' => true,
243  'security_notify_admins' => true,
244  'security_notify_user_password' => true,
245  'security_protect_upgrade' => true,
246  'session_bound_entity_icons' => false,
247  'simplecache_enabled' => false,
248  'subresource_integrity_enabled' => false,
249  'system_cache_enabled' => false,
250  'testing_mode' => false,
251  'trash_enabled' => false,
252  'trash_retention' => 30,
253  'user_joined_river' => false,
254  'webp_enabled' => true,
255  'who_can_change_language' => 'everyone',
256  ];
257 
263  protected $path_properties = [
264  'assetroot',
265  'cacheroot',
266  'dataroot',
267  'plugins_path',
268  ];
269 
275  const ENTITY_TYPES = ['group', 'object', 'site', 'user'];
276 
282  const SENSITIVE_PROPERTIES = [
283  '__site_secret__',
284  'db',
285  'dbhost',
286  'dbport',
287  'dbuser',
288  'dbpass',
289  'dbname',
290  ];
291 
297  public function __construct(array $values = []) {
298  $this->saveInitialValues($values);
299 
300  $this->values = array_merge($this->config_defaults, $values);
301 
302  // set cookie values for session and remember me
303  $this->getCookieConfig();
304  }
305 
313  protected function saveInitialValues(array $values): void {
314  // Don't keep copies of these in case config gets dumped
315  foreach (self::SENSITIVE_PROPERTIES as $name) {
316  unset($values[$name]);
317  }
318 
319  $this->initial_values = $values;
320  }
321 
329  public static function factory(string $settings_path = ''): static {
330  $settings_path = self::resolvePath($settings_path);
331 
332  return self::fromFile($settings_path);
333  }
334 
343  protected static function fromFile($path): static {
344  if (!is_file($path)) {
345  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not present.");
346  }
347 
348  if (!is_readable($path)) {
349  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not readable.");
350  }
351 
352  // legacy loading. If $CONFIG doesn't exist, remove it after the
353  // settings file is read.
354  if (isset($GLOBALS['CONFIG'])) {
355  // don't overwrite it
356  $global = $GLOBALS['CONFIG'];
357  unset($GLOBALS['CONFIG']);
358  } else {
359  $global = null;
360  }
361 
362  Includer::requireFile($path);
363 
364  if (empty($GLOBALS['CONFIG']->dataroot)) {
365  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->dataroot.');
366  }
367 
368  if (empty($GLOBALS['CONFIG']->wwwroot)) {
369  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->wwwroot.');
370  }
371 
372  $config = new self(get_object_vars($GLOBALS['CONFIG']));
373 
374  if ($global !== null) {
375  // restore
376  $GLOBALS['CONFIG'] = $global;
377  } else {
378  unset($GLOBALS['CONFIG']);
379  }
380 
381  if ($config->{'X-Sendfile-Type'}) {
382  $config->{'x_sendfile_type'} = $config->{'X-Sendfile-Type'};
383  unset($config->{'X-Sendfile-Type'});
384  }
385 
386  if ($config->{'X-Accel-Mapping'}) {
387  $config->{'x_accel_mapping'} = $config->{'X-Accel-Mapping'};
388  unset($config->{'X-Accel-Mapping'});
389  }
390 
391  return $config;
392  }
393 
401  public static function resolvePath(string $settings_path = ''): string {
402  if (empty($settings_path)) {
403  $settings_path = Paths::settingsFile(Paths::SETTINGS_PHP);
404  }
405 
406  return Paths::sanitize($settings_path, false);
407  }
408 
414  public function getValues(): array {
415  return $this->values;
416  }
417 
423  public function getCookieConfig(): array {
424  if ($this->cookies_configured) {
425  return $this->cookies;
426  }
427 
428  $cookies = [];
429  if ($this->hasInitialValue('cookies')) {
430  $cookies = $this->getInitialValue('cookies');
431  }
432 
433  // session cookie config
434  if (!isset($cookies['session'])) {
435  $cookies['session'] = [];
436  }
437 
438  $session_defaults = session_get_cookie_params();
439  $session_defaults['name'] = 'Elgg';
440  $cookies['session'] = array_merge($session_defaults, $cookies['session']);
441 
442  // remember me cookie config
443  if (!isset($cookies['remember_me'])) {
444  $cookies['remember_me'] = [];
445  }
446 
447  $session_defaults['name'] = 'elggperm';
448  $session_defaults['expire'] = strtotime('+30 days');
449  $cookies['remember_me'] = array_merge($session_defaults, $cookies['remember_me']);
450 
451  $this->cookies = $cookies;
452  $this->cookies_configured = true;
453 
454  return $cookies;
455  }
456 
466  public function __get(string $name) {
467 
468  if (array_key_exists($name, $this->deprecated)) {
469  elgg_deprecated_notice("Using '{$name}' from config has been deprecated", $this->deprecated[$name]);
470  }
471 
472  if (!isset($this->values[$name])) {
473  return null;
474  }
475 
476  $value = $this->values[$name];
477  if (in_array($name, $this->path_properties)) {
478  $value = Paths::sanitize($value);
479  }
480 
481  return $value;
482  }
483 
491  public function hasValue(string $name): bool {
492  return isset($this->values[$name]);
493  }
494 
501  public function getInitialValue(string $name) {
502  return $this->initial_values[$name] ?? null;
503  }
504 
512  public function hasInitialValue(string $name): bool {
513  return isset($this->initial_values[$name]);
514  }
515 
523  public function isLocked(string $name): bool {
524  $testing = $this->values['testing_mode'] ?? false;
525  return !$testing && in_array($name, $this->locked_values) && $this->hasValue($name);
526  }
527 
537  public function __set(string $name, $value): void {
538  if ($this->wasWarnedLocked($name)) {
539  return;
540  }
541 
542  if (in_array($name, $this->path_properties)) {
543  $value = Paths::sanitize($value);
544  }
545 
546  $this->values[$name] = $value;
547  }
548 
555  public function __isset(string $name): bool {
556  return $this->__get($name) !== null;
557  }
558 
565  public function __unset(string $name): void {
566  if ($this->wasWarnedLocked($name)) {
567  return;
568  }
569 
570  unset($this->values[$name]);
571  }
572 
581  public function save(string $name, $value): bool {
582  if ($this->wasWarnedLocked($name)) {
583  return false;
584  }
585 
586  if (strlen($name) > 255) {
587  $this->getLogger()->error('The name length for configuration variables cannot be greater than 255');
588  return false;
589  }
590 
591  if ($value === null) {
592  // don't save null values
593  return $this->remove($name);
594  }
595 
596  $result = _elgg_services()->configTable->set($name, $value);
597 
598  $this->__set($name, $value);
599 
600  return $result;
601  }
602 
610  public function remove(string $name): bool {
611  if ($this->wasWarnedLocked($name)) {
612  return false;
613  }
614 
615  $result = _elgg_services()->configTable->remove($name);
616 
617  unset($this->values[$name]);
618 
619  return $result;
620  }
621 
628  protected function wasWarnedLocked(string $name): bool {
629  if (!$this->isLocked($name)) {
630  return false;
631  }
632 
633  $this->getLogger()->warning("The property {$name} is read-only.");
634 
635  return true;
636  }
637 }
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:491
isLocked(string $name)
Is this value locked?
Definition: Config.php:523
static fromFile($path)
Build a config from a file.
Definition: Config.php:343
__construct(array $values=[])
Constructor.
Definition: Config.php:297
getCookieConfig()
Set up and return the cookie configuration array resolved from settings.
Definition: Config.php:423
save(string $name, $value)
Save a configuration setting to the database.
Definition: Config.php:581
hasInitialValue(string $name)
Was a value available at construction time? (From settings.php)
Definition: Config.php:512
getInitialValue(string $name)
Get a value set at construction time.
Definition: Config.php:501
static factory(string $settings_path='')
Build a config from default settings locations.
Definition: Config.php:329
saveInitialValues(array $values)
Stores the inital values.
Definition: Config.php:313
static resolvePath(string $settings_path='')
Resolve settings path.
Definition: Config.php:401
wasWarnedLocked(string $name)
Log a read-only warning if the name is read-only.
Definition: Config.php:628
__set(string $name, $value)
Set an Elgg configuration value.
Definition: Config.php:537
__isset(string $name)
Handle isset()
Definition: Config.php:555
__unset(string $name)
Handle unset()
Definition: Config.php:565
getValues()
Get all values.
Definition: Config.php:414
__get(string $name)
Get an Elgg configuration value if it's been set or loaded during the boot process.
Definition: Config.php:466
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.