Elgg  Version 4.3
Config.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
8 
132 class Config {
133 
134  use Loggable;
135 
139  private $values;
140 
144  private $initial_values;
145 
149  private $cookies_configured = false;
150 
154  private $cookies = [];
155 
161  protected $locked_values = [
162  'assetroot',
163  'cacheroot',
164  'dataroot',
165  'elgg_settings_file',
166  'installed',
167  'path',
168  'plugins_path',
169  'pluginspath',
170  'site_guid',
171  'url',
172  'wwwroot',
173  ];
174 
178  protected $deprecated = [
179  'elgg_settings_file' => '4.3',
180  'path' => '4.3',
181  'pluginspath' => '4.3',
182  'site_guid' => '4.3',
183  'sitedescription' => '4.3',
184  'sitename' => '4.3',
185  'url' => '4.3',
186  ];
187 
193  protected $config_defaults = [
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  'bootdata_plugin_settings_limit' => 40,
201  'can_change_username' => false,
202  'class_loader_verify_file_existence' => true,
203  'comment_box_collapses' => true,
204  'comments_group_only' => true,
205  'comments_latest_first' => true,
206  'comments_max_depth' => 0,
207  'comments_per_page' => 25,
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  'message_delay' => 6,
228  'min_password_length' => 6,
229  'minusername' => 4,
230  'notifications_max_runtime' => 45,
231  'notifications_queue_delay' => 0,
232  'pagination_behaviour' => 'ajax-replace',
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  'site_guid' => 1, // deprecated
241  'subresource_integrity_enabled' => false,
242  'system_cache_enabled' => false,
243  'testing_mode' => false,
244  'webp_enabled' => true,
245  'who_can_change_language' => 'everyone',
246  ];
247 
253  protected $path_properties = [
254  'dataroot',
255  'cacheroot',
256  'assetroot',
257  ];
258 
264  const ENTITY_TYPES = ['group', 'object', 'site', 'user'];
265 
271  const SENSITIVE_PROPERTIES = [
272  '__site_secret__',
273  'db',
274  'dbhost',
275  'dbport',
276  'dbuser',
277  'dbpass',
278  'dbname',
279  ];
280 
286  public function __construct(array $values = []) {
287  $this->saveInitialValues($values);
288 
289  $this->values = array_merge($this->config_defaults, $values);
290 
291  // set cookie values for session and remember me
292  $this->getCookieConfig();
293  }
294 
302  protected function saveInitialValues(array $values): void {
303  // Don't keep copies of these in case config gets dumped
304  foreach (self::SENSITIVE_PROPERTIES as $name) {
305  unset($values[$name]);
306  }
307 
308  $this->initial_values = $values;
309  }
310 
320  public static function factory($settings_path = '', $try_env = true) {
321  $reason1 = '';
322 
323  $settings_path = self::resolvePath($settings_path, $try_env);
324 
325  $config = self::fromFile($settings_path, $reason1);
326 
327  if (!$config) {
328  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: $reason1");
329  }
330 
331  return $config;
332  }
333 
342  public static function fromFile($path, &$reason = '') {
343  if (!is_file($path)) {
344  $reason = "File $path not present.";
345  return false;
346  }
347 
348  if (!is_readable($path)) {
349  $reason = "File $path not readable.";
350  return false;
351  }
352 
353  // legacy loading. If $CONFIG doesn't exist, remove it after the
354  // settings file is read.
355  if (isset($GLOBALS['CONFIG'])) {
356  // don't overwrite it
357  $global = $GLOBALS['CONFIG'];
358  unset($GLOBALS['CONFIG']);
359  } else {
360  $global = null;
361  }
362 
363  Includer::requireFile($path);
364 
365  if (empty($GLOBALS['CONFIG']->dataroot)) {
366  $reason = 'The Elgg settings file is missing $CONFIG->dataroot.';
367  return false;
368  }
369 
370  if (empty($GLOBALS['CONFIG']->wwwroot)) {
371  $reason = 'The Elgg settings file is missing $CONFIG->wwwroot.';
372  return false;
373  }
374 
375  $config = new self(get_object_vars($GLOBALS['CONFIG']));
376 
377  if ($global !== null) {
378  // restore
379  $GLOBALS['CONFIG'] = $global;
380  } else {
381  unset($GLOBALS['CONFIG']);
382  }
383 
384  if ($config->{'X-Sendfile-Type'}) {
385  $config->{'x_sendfile_type'} = $config->{'X-Sendfile-Type'};
386  unset($config->{'X-Sendfile-Type'});
387  }
388  if ($config->{'X-Accel-Mapping'}) {
389  $config->{'x_accel_mapping'} = $config->{'X-Accel-Mapping'};
390  unset($config->{'X-Accel-Mapping'});
391  }
392 
393  $config->elgg_settings_file = $path;
394 
395  return $config;
396  }
397 
405  public static function resolvePath($settings_path = '', $try_env = true) {
406  if (!$settings_path) {
407  if ($try_env && !empty($_ENV['ELGG_SETTINGS_FILE'])) {
408  $settings_path = $_ENV['ELGG_SETTINGS_FILE'];
409  } else if (!$settings_path) {
410  $settings_path = Paths::settingsFile(Paths::SETTINGS_PHP);
411  }
412  }
413 
414  return \Elgg\Project\Paths::sanitize($settings_path, false);
415  }
416 
425  public function mergeValues(array $values) {
426  foreach ($values as $name => $value) {
427  $this->__set($name, $value);
428  }
429  }
430 
436  public function getValues() {
437  return $this->values;
438  }
439 
445  public function getCookieConfig() {
446  if ($this->cookies_configured) {
447  return $this->cookies;
448  }
449 
450  $cookies = [];
451  if ($this->hasInitialValue('cookies')) {
452  $cookies = $this->getInitialValue('cookies');
453  }
454 
455  // session cookie config
456  if (!isset($cookies['session'])) {
457  $cookies['session'] = [];
458  }
459  $session_defaults = session_get_cookie_params();
460  $session_defaults['name'] = 'Elgg';
461  $cookies['session'] = array_merge($session_defaults, $cookies['session']);
462 
463  // remember me cookie config
464  if (!isset($cookies['remember_me'])) {
465  $cookies['remember_me'] = [];
466  }
467  $session_defaults['name'] = 'elggperm';
468  $session_defaults['expire'] = strtotime("+30 days");
469  $cookies['remember_me'] = array_merge($session_defaults, $cookies['remember_me']);
470 
471  $this->cookies = $cookies;
472  $this->cookies_configured = true;
473 
474  return $cookies;
475  }
476 
486  public function __get($name) {
487 
488  if (array_key_exists($name, $this->deprecated)) {
489  elgg_deprecated_notice("Using '{$name}' from config has been deprecated", $this->deprecated[$name]);
490  }
491 
492  if (isset($this->values[$name])) {
493  return $this->values[$name];
494  }
495 
496  return null;
497  }
498 
506  public function hasValue($name) {
507  return isset($this->values[$name]);
508  }
509 
516  public function getInitialValue($name) {
517  return $this->initial_values[$name] ?? null;
518  }
519 
527  public function hasInitialValue($name) {
528  return isset($this->initial_values[$name]);
529  }
530 
538  public function lock($name) {
539  elgg_deprecated_notice(__METHOD__ . 'has been deprecated. It is no longer possible to lock config values.', '4.3');
540  }
541 
549  public function isLocked($name) {
550  $testing = $this->values['testing_mode'] ?? false;
551  return !$testing && in_array($name, $this->locked_values) && $this->hasValue($name);
552  }
553 
563  public function __set($name, $value) {
564  if ($this->wasWarnedLocked($name)) {
565  return;
566  }
567 
568  if (in_array($name, $this->path_properties)) {
569  $value = Paths::sanitize($value);
570  }
571 
572  $this->values[$name] = $value;
573  }
574 
581  public function __isset($name) {
582  return $this->__get($name) !== null;
583  }
584 
591  public function __unset($name) {
592  if ($this->wasWarnedLocked($name)) {
593  return;
594  }
595 
596  unset($this->values[$name]);
597  }
598 
607  public function save($name, $value) {
608  if ($this->wasWarnedLocked($name)) {
609  return false;
610  }
611 
612  if (strlen($name) > 255) {
613  $this->getLogger()->error("The name length for configuration variables cannot be greater than 255");
614  return false;
615  }
616 
617  if ($value === null) {
618  // don't save null values
619  return $this->remove($name);
620  }
621 
622  $result = _elgg_services()->configTable->set($name, $value);
623 
624  $this->__set($name, $value);
625 
626  return $result;
627  }
628 
636  public function remove($name) {
637  if ($this->wasWarnedLocked($name)) {
638  return false;
639  }
640 
641  $result = _elgg_services()->configTable->remove($name);
642 
643  unset($this->values[$name]);
644 
645  return $result;
646  }
647 
654  protected function wasWarnedLocked($name): bool {
655  if (!$this->isLocked($name)) {
656  return false;
657  }
658 
659  $this->getLogger()->warning("The property {$name} is read-only.");
660 
661  return true;
662  }
663 }
wasWarnedLocked($name)
Log a read-only warning if the name is read-only.
Definition: Config.php:654
__isset($name)
Handle isset()
Definition: Config.php:581
A generic parent class for Configuration exceptions.
isLocked($name)
Is this value locked?
Definition: Config.php:549
if(!isset($CONFIG)) $CONFIG dataroot
The full file path for Elgg data storage.
getInitialValue($name)
Get a value set at construction time.
Definition: Config.php:516
saveInitialValues(array $values)
Stores the inital values.
Definition: Config.php:302
__get($name)
Get an Elgg configuration value if it&#39;s been set or loaded during the boot process.
Definition: Config.php:486
elgg_deprecated_notice(string $msg, string $dep_version)
Log a notice about deprecated use of a function, view, etc.
Definition: deprecation.php:52
if(!$user||!$user->canDelete()) $name
Definition: delete.php:22
mergeValues(array $values)
Set an array of values.
Definition: Config.php:425
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
hasInitialValue($name)
Was a value available at construction time? (From settings.php)
Definition: Config.php:527
$value
Definition: generic.php:51
__construct(array $values=[])
Constructor.
Definition: Config.php:286
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
$path
Definition: details.php:68
trait Loggable
Enables adding a logger.
Definition: Loggable.php:14
hasValue($name)
Test if we have a set value.
Definition: Config.php:506
lock($name)
Make a value read-only.
Definition: Config.php:538
__set($name, $value)
Set an Elgg configuration value.
Definition: Config.php:563
static resolvePath($settings_path= '', $try_env=true)
Resolve settings path.
Definition: Config.php:405
__unset($name)
Handle unset()
Definition: Config.php:591
static factory($settings_path= '', $try_env=true)
Build a config from default settings locations.
Definition: Config.php:320
getLogger()
Returns logger.
Definition: Loggable.php:37
getCookieConfig()
Set up and return the cookie configuration array resolved from settings.
Definition: Config.php:445
static fromFile($path, &$reason= '')
Build a config from a file.
Definition: Config.php:342
getValues()
Get all values.
Definition: Config.php:436
_elgg_services()
Get the global service provider.
Definition: elgglib.php:638
$CONFIG wwwroot
The installation root URL of the site.
save($name, $value)
Save a configuration setting to the database.
Definition: Config.php:607