Elgg  Version master
Config.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
8 
137 class Config {
138 
139  use Loggable;
140 
144  private $values;
145 
149  private $initial_values;
150 
154  private $cookies_configured = false;
155 
159  private $cookies = [];
160 
166  protected $locked_values = [
167  'assetroot',
168  'cacheroot',
169  'dataroot',
170  'installed',
171  'plugins_path',
172  'wwwroot',
173  ];
174 
180  protected $deprecated = [
181  ];
182 
188  protected $config_defaults = [
189  'allow_phpinfo' => false,
190  'authentication_failures_lifetime' => 600,
191  'authentication_failures_limit' => 5,
192  'auto_disable_plugins' => true,
193  'batch_run_time_in_secs' => 4,
194  'boot_cache_ttl' => 3600,
195  'can_change_username' => false,
196  'class_loader_verify_file_existence' => true,
197  'comment_box_collapses' => true,
198  'comments_group_only' => true,
199  'comments_latest_first' => true,
200  'comments_max_depth' => 0,
201  'comments_per_page' => 25,
202  'db_query_cache_limit' => 50,
203  'default_limit' => 10,
204  'elgg_maintenance_mode' => false,
205  'email_html_part' => true,
206  'email_html_part_images' => 'no',
207  'email_subject_limit' => 998,
208  'enable_delayed_email' => true,
209  'friendly_time_number_of_days' => 30,
210  'icon_sizes' => [
211  'topbar' => ['w' => 16, 'h' => 16, 'square' => true, 'upscale' => true],
212  'tiny' => ['w' => 25, 'h' => 25, 'square' => true, 'upscale' => true],
213  'small' => ['w' => 40, 'h' => 40, 'square' => true, 'upscale' => true],
214  'medium' => ['w' => 100, 'h' => 100, 'square' => true, 'upscale' => true],
215  'large' => ['w' => 200, 'h' => 200, 'square' => true, 'upscale' => true],
216  'master' => ['w' => 10240, 'h' => 10240, 'square' => false, 'upscale' => false, 'crop' => false],
217  ],
218  'language' => 'en',
219  'language_detect_from_browser' => true,
220  'lastcache' => 0,
221  'mentions_display_format' => 'display_name',
222  'message_delay' => 6,
223  'min_password_length' => 6,
224  'minusername' => 4,
225  'notifications_max_runtime' => 45,
226  'notifications_queue_delay' => 0,
227  'pagination_behaviour' => 'ajax-replace',
228  'security_email_require_confirmation' => true,
229  'security_email_require_password' => true,
230  'security_notify_admins' => true,
231  'security_notify_user_password' => true,
232  'security_protect_upgrade' => true,
233  'session_bound_entity_icons' => false,
234  'simplecache_enabled' => false,
235  'subresource_integrity_enabled' => false,
236  'system_cache_enabled' => false,
237  'testing_mode' => false,
238  'user_joined_river' => false,
239  'webp_enabled' => true,
240  'who_can_change_language' => 'everyone',
241  ];
242 
248  protected $path_properties = [
249  'dataroot',
250  'cacheroot',
251  'assetroot',
252  ];
253 
259  const ENTITY_TYPES = ['group', 'object', 'site', 'user'];
260 
266  const SENSITIVE_PROPERTIES = [
267  '__site_secret__',
268  'db',
269  'dbhost',
270  'dbport',
271  'dbuser',
272  'dbpass',
273  'dbname',
274  ];
275 
281  public function __construct(array $values = []) {
282  $this->saveInitialValues($values);
283 
284  $this->values = array_merge($this->config_defaults, $values);
285 
286  // set cookie values for session and remember me
287  $this->getCookieConfig();
288  }
289 
297  protected function saveInitialValues(array $values): void {
298  // Don't keep copies of these in case config gets dumped
299  foreach (self::SENSITIVE_PROPERTIES as $name) {
300  unset($values[$name]);
301  }
302 
303  $this->initial_values = $values;
304  }
305 
313  public static function factory(string $settings_path = ''): static {
314  $settings_path = self::resolvePath($settings_path);
315 
316  return self::fromFile($settings_path);
317  }
318 
327  protected static function fromFile($path): static {
328  if (!is_file($path)) {
329  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not present.");
330  }
331 
332  if (!is_readable($path)) {
333  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not readable.");
334  }
335 
336  // legacy loading. If $CONFIG doesn't exist, remove it after the
337  // settings file is read.
338  if (isset($GLOBALS['CONFIG'])) {
339  // don't overwrite it
340  $global = $GLOBALS['CONFIG'];
341  unset($GLOBALS['CONFIG']);
342  } else {
343  $global = null;
344  }
345 
346  Includer::requireFile($path);
347 
348  if (empty($GLOBALS['CONFIG']->dataroot)) {
349  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->dataroot.');
350  }
351 
352  if (empty($GLOBALS['CONFIG']->wwwroot)) {
353  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->wwwroot.');
354  }
355 
356  $config = new self(get_object_vars($GLOBALS['CONFIG']));
357 
358  if ($global !== null) {
359  // restore
360  $GLOBALS['CONFIG'] = $global;
361  } else {
362  unset($GLOBALS['CONFIG']);
363  }
364 
365  if ($config->{'X-Sendfile-Type'}) {
366  $config->{'x_sendfile_type'} = $config->{'X-Sendfile-Type'};
367  unset($config->{'X-Sendfile-Type'});
368  }
369 
370  if ($config->{'X-Accel-Mapping'}) {
371  $config->{'x_accel_mapping'} = $config->{'X-Accel-Mapping'};
372  unset($config->{'X-Accel-Mapping'});
373  }
374 
375  return $config;
376  }
377 
385  public static function resolvePath(string $settings_path = ''): string {
386  if (empty($settings_path)) {
387  $settings_path = Paths::settingsFile(Paths::SETTINGS_PHP);
388  }
389 
390  return \Elgg\Project\Paths::sanitize($settings_path, false);
391  }
392 
398  public function getValues(): array {
399  return $this->values;
400  }
401 
407  public function getCookieConfig(): array {
408  if ($this->cookies_configured) {
409  return $this->cookies;
410  }
411 
412  $cookies = [];
413  if ($this->hasInitialValue('cookies')) {
414  $cookies = $this->getInitialValue('cookies');
415  }
416 
417  // session cookie config
418  if (!isset($cookies['session'])) {
419  $cookies['session'] = [];
420  }
421 
422  $session_defaults = session_get_cookie_params();
423  $session_defaults['name'] = 'Elgg';
424  $cookies['session'] = array_merge($session_defaults, $cookies['session']);
425 
426  // remember me cookie config
427  if (!isset($cookies['remember_me'])) {
428  $cookies['remember_me'] = [];
429  }
430 
431  $session_defaults['name'] = 'elggperm';
432  $session_defaults['expire'] = strtotime('+30 days');
433  $cookies['remember_me'] = array_merge($session_defaults, $cookies['remember_me']);
434 
435  $this->cookies = $cookies;
436  $this->cookies_configured = true;
437 
438  return $cookies;
439  }
440 
450  public function __get(string $name) {
451 
452  if (array_key_exists($name, $this->deprecated)) {
453  elgg_deprecated_notice("Using '{$name}' from config has been deprecated", $this->deprecated[$name]);
454  }
455 
456  if (isset($this->values[$name])) {
457  return $this->values[$name];
458  }
459 
460  return null;
461  }
462 
470  public function hasValue(string $name): bool {
471  return isset($this->values[$name]);
472  }
473 
480  public function getInitialValue(string $name) {
481  return $this->initial_values[$name] ?? null;
482  }
483 
491  public function hasInitialValue(string $name): bool {
492  return isset($this->initial_values[$name]);
493  }
494 
502  public function isLocked(string $name): bool {
503  $testing = $this->values['testing_mode'] ?? false;
504  return !$testing && in_array($name, $this->locked_values) && $this->hasValue($name);
505  }
506 
516  public function __set(string $name, $value): void {
517  if ($this->wasWarnedLocked($name)) {
518  return;
519  }
520 
521  if (in_array($name, $this->path_properties)) {
522  $value = Paths::sanitize($value);
523  }
524 
525  $this->values[$name] = $value;
526  }
527 
534  public function __isset(string $name): bool {
535  return $this->__get($name) !== null;
536  }
537 
544  public function __unset(string $name): void {
545  if ($this->wasWarnedLocked($name)) {
546  return;
547  }
548 
549  unset($this->values[$name]);
550  }
551 
560  public function save(string $name, $value): bool {
561  if ($this->wasWarnedLocked($name)) {
562  return false;
563  }
564 
565  if (strlen($name) > 255) {
566  $this->getLogger()->error('The name length for configuration variables cannot be greater than 255');
567  return false;
568  }
569 
570  if ($value === null) {
571  // don't save null values
572  return $this->remove($name);
573  }
574 
575  $result = _elgg_services()->configTable->set($name, $value);
576 
577  $this->__set($name, $value);
578 
579  return $result;
580  }
581 
589  public function remove(string $name): bool {
590  if ($this->wasWarnedLocked($name)) {
591  return false;
592  }
593 
594  $result = _elgg_services()->configTable->remove($name);
595 
596  unset($this->values[$name]);
597 
598  return $result;
599  }
600 
607  protected function wasWarnedLocked(string $name): bool {
608  if (!$this->isLocked($name)) {
609  return false;
610  }
611 
612  $this->getLogger()->warning("The property {$name} is read-only.");
613 
614  return true;
615  }
616 }
hasInitialValue(string $name)
Was a value available at construction time? (From settings.php)
Definition: Config.php:491
static resolvePath(string $settings_path= '')
Resolve settings path.
Definition: Config.php:385
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:297
save(string $name, $value)
Save a configuration setting to the database.
Definition: Config.php:560
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:607
__get(string $name)
Get an Elgg configuration value if it&#39;s been set or loaded during the boot process.
Definition: Config.php:450
hasValue(string $name)
Test if we have a set value.
Definition: Config.php:470
__set(string $name, $value)
Set an Elgg configuration value.
Definition: Config.php:516
$value
Definition: generic.php:51
__construct(array $values=[])
Constructor.
Definition: Config.php:281
$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:327
__unset(string $name)
Handle unset()
Definition: Config.php:544
__isset(string $name)
Handle isset()
Definition: Config.php:534
isLocked(string $name)
Is this value locked?
Definition: Config.php:502
getLogger()
Returns logger.
Definition: Loggable.php:37
getCookieConfig()
Set up and return the cookie configuration array resolved from settings.
Definition: Config.php:407
getValues()
Get all values.
Definition: Config.php:398
getInitialValue(string $name)
Get a value set at construction time.
Definition: Config.php:480
_elgg_services()
Get the global service provider.
Definition: elgglib.php:346
$CONFIG wwwroot
The installation root URL of the site.
static factory(string $settings_path= '')
Build a config from default settings locations.
Definition: Config.php:313