Elgg  Version master
Config.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
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 }
hasInitialValue(string $name)
Was a value available at construction time? (From settings.php)
Definition: Config.php:504
static resolvePath(string $settings_path= '')
Resolve settings path.
Definition: Config.php:393
A generic parent class for Configuration exceptions.
if(!isset($CONFIG)) $CONFIG dataroot
The full file path for Elgg data storage.
elgg_deprecated_notice(string $msg, string $dep_version)
Log a notice about deprecated use of a function, view, etc.
Definition: elgglib.php:115
saveInitialValues(array $values)
Stores the inital values.
Definition: Config.php:305
save(string $name, $value)
Save a configuration setting to the database.
Definition: Config.php:573
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
Definition: LICENSE.txt:215
wasWarnedLocked(string $name)
Log a read-only warning if the name is read-only.
Definition: Config.php:620
__get(string $name)
Get an Elgg configuration value if it&#39;s been set or loaded during the boot process.
Definition: Config.php:458
hasValue(string $name)
Test if we have a set value.
Definition: Config.php:483
__set(string $name, $value)
Set an Elgg configuration value.
Definition: Config.php:529
$value
Definition: generic.php:51
__construct(array $values=[])
Constructor.
Definition: Config.php:289
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
$path
Definition: details.php:70
trait Loggable
Enables adding a logger.
Definition: Loggable.php:14
static fromFile($path)
Build a config from a file.
Definition: Config.php:335
__unset(string $name)
Handle unset()
Definition: Config.php:557
__isset(string $name)
Handle isset()
Definition: Config.php:547
isLocked(string $name)
Is this value locked?
Definition: Config.php:515
getLogger()
Returns logger.
Definition: Loggable.php:37
getCookieConfig()
Set up and return the cookie configuration array resolved from settings.
Definition: Config.php:415
getValues()
Get all values.
Definition: Config.php:406
getInitialValue(string $name)
Get a value set at construction time.
Definition: Config.php:493
_elgg_services()
Get the global service provider.
Definition: elgglib.php:351
$CONFIG wwwroot
The installation root URL of the site.
static factory(string $settings_path= '')
Build a config from default settings locations.
Definition: Config.php:321