Elgg  Version master
Config.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
8 
128 class Config {
129 
130  use Loggable;
131 
135  private $values;
136 
140  private $initial_values;
141 
145  private $cookies_configured = false;
146 
150  private $cookies = [];
151 
157  protected $locked_values = [
158  'assetroot',
159  'cacheroot',
160  'dataroot',
161  'installed',
162  'plugins_path',
163  'wwwroot',
164  ];
165 
171  protected $deprecated = [
172  ];
173 
179  protected $config_defaults = [
180  'allow_phpinfo' => false,
181  'authentication_failures_lifetime' => 600,
182  'authentication_failures_limit' => 5,
183  'auto_disable_plugins' => true,
184  'batch_run_time_in_secs' => 4,
185  'boot_cache_ttl' => 3600,
186  'can_change_username' => false,
187  'class_loader_verify_file_existence' => true,
188  'comment_box_collapses' => true,
189  'comments_group_only' => true,
190  'comments_latest_first' => true,
191  'comments_max_depth' => 0,
192  'comments_per_page' => 25,
193  'db_query_cache_limit' => 50,
194  'default_limit' => 10,
195  'elgg_maintenance_mode' => false,
196  'email_html_part' => true,
197  'email_html_part_images' => 'no',
198  'email_subject_limit' => 998,
199  'enable_delayed_email' => true,
200  'friendly_time_number_of_days' => 30,
201  'icon_sizes' => [
202  'topbar' => ['w' => 16, 'h' => 16, 'square' => true, 'upscale' => true],
203  'tiny' => ['w' => 25, 'h' => 25, 'square' => true, 'upscale' => true],
204  'small' => ['w' => 40, 'h' => 40, 'square' => true, 'upscale' => true],
205  'medium' => ['w' => 100, 'h' => 100, 'square' => true, 'upscale' => true],
206  'large' => ['w' => 200, 'h' => 200, 'square' => true, 'upscale' => true],
207  'master' => ['w' => 10240, 'h' => 10240, 'square' => false, 'upscale' => false, 'crop' => false],
208  ],
209  'language' => 'en',
210  'language_detect_from_browser' => true,
211  'lastcache' => 0,
212  'message_delay' => 6,
213  'min_password_length' => 6,
214  'minusername' => 4,
215  'notifications_max_runtime' => 45,
216  'notifications_queue_delay' => 0,
217  'pagination_behaviour' => 'ajax-replace',
218  'security_email_require_confirmation' => true,
219  'security_email_require_password' => true,
220  'security_notify_admins' => true,
221  'security_notify_user_password' => true,
222  'security_protect_upgrade' => true,
223  'session_bound_entity_icons' => false,
224  'simplecache_enabled' => false,
225  'subresource_integrity_enabled' => false,
226  'system_cache_enabled' => false,
227  'testing_mode' => false,
228  'user_joined_river' => false,
229  'webp_enabled' => true,
230  'who_can_change_language' => 'everyone',
231  ];
232 
238  protected $path_properties = [
239  'dataroot',
240  'cacheroot',
241  'assetroot',
242  ];
243 
249  const ENTITY_TYPES = ['group', 'object', 'site', 'user'];
250 
256  const SENSITIVE_PROPERTIES = [
257  '__site_secret__',
258  'db',
259  'dbhost',
260  'dbport',
261  'dbuser',
262  'dbpass',
263  'dbname',
264  ];
265 
271  public function __construct(array $values = []) {
272  $this->saveInitialValues($values);
273 
274  $this->values = array_merge($this->config_defaults, $values);
275 
276  // set cookie values for session and remember me
277  $this->getCookieConfig();
278  }
279 
287  protected function saveInitialValues(array $values): void {
288  // Don't keep copies of these in case config gets dumped
289  foreach (self::SENSITIVE_PROPERTIES as $name) {
290  unset($values[$name]);
291  }
292 
293  $this->initial_values = $values;
294  }
295 
303  public static function factory(string $settings_path = ''): static {
304  $settings_path = self::resolvePath($settings_path);
305 
306  return self::fromFile($settings_path);
307  }
308 
317  protected static function fromFile($path): static {
318  if (!is_file($path)) {
319  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not present.");
320  }
321 
322  if (!is_readable($path)) {
323  throw new ConfigurationException(__METHOD__ . ": Reading configs failed: File {$path} not readable.");
324  }
325 
326  // legacy loading. If $CONFIG doesn't exist, remove it after the
327  // settings file is read.
328  if (isset($GLOBALS['CONFIG'])) {
329  // don't overwrite it
330  $global = $GLOBALS['CONFIG'];
331  unset($GLOBALS['CONFIG']);
332  } else {
333  $global = null;
334  }
335 
336  Includer::requireFile($path);
337 
338  if (empty($GLOBALS['CONFIG']->dataroot)) {
339  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->dataroot.');
340  }
341 
342  if (empty($GLOBALS['CONFIG']->wwwroot)) {
343  throw new ConfigurationException(__METHOD__ . ': Reading configs failed: The Elgg settings file is missing $CONFIG->wwwroot.');
344  }
345 
346  $config = new self(get_object_vars($GLOBALS['CONFIG']));
347 
348  if ($global !== null) {
349  // restore
350  $GLOBALS['CONFIG'] = $global;
351  } else {
352  unset($GLOBALS['CONFIG']);
353  }
354 
355  if ($config->{'X-Sendfile-Type'}) {
356  $config->{'x_sendfile_type'} = $config->{'X-Sendfile-Type'};
357  unset($config->{'X-Sendfile-Type'});
358  }
359 
360  if ($config->{'X-Accel-Mapping'}) {
361  $config->{'x_accel_mapping'} = $config->{'X-Accel-Mapping'};
362  unset($config->{'X-Accel-Mapping'});
363  }
364 
365  return $config;
366  }
367 
375  public static function resolvePath(string $settings_path = ''): string {
376  if (empty($settings_path)) {
377  $settings_path = Paths::settingsFile(Paths::SETTINGS_PHP);
378  }
379 
380  return \Elgg\Project\Paths::sanitize($settings_path, false);
381  }
382 
388  public function getValues(): array {
389  return $this->values;
390  }
391 
397  public function getCookieConfig(): array {
398  if ($this->cookies_configured) {
399  return $this->cookies;
400  }
401 
402  $cookies = [];
403  if ($this->hasInitialValue('cookies')) {
404  $cookies = $this->getInitialValue('cookies');
405  }
406 
407  // session cookie config
408  if (!isset($cookies['session'])) {
409  $cookies['session'] = [];
410  }
411 
412  $session_defaults = session_get_cookie_params();
413  $session_defaults['name'] = 'Elgg';
414  $cookies['session'] = array_merge($session_defaults, $cookies['session']);
415 
416  // remember me cookie config
417  if (!isset($cookies['remember_me'])) {
418  $cookies['remember_me'] = [];
419  }
420 
421  $session_defaults['name'] = 'elggperm';
422  $session_defaults['expire'] = strtotime('+30 days');
423  $cookies['remember_me'] = array_merge($session_defaults, $cookies['remember_me']);
424 
425  $this->cookies = $cookies;
426  $this->cookies_configured = true;
427 
428  return $cookies;
429  }
430 
440  public function __get(string $name) {
441 
442  if (array_key_exists($name, $this->deprecated)) {
443  elgg_deprecated_notice("Using '{$name}' from config has been deprecated", $this->deprecated[$name]);
444  }
445 
446  if (isset($this->values[$name])) {
447  return $this->values[$name];
448  }
449 
450  return null;
451  }
452 
460  public function hasValue(string $name): bool {
461  return isset($this->values[$name]);
462  }
463 
470  public function getInitialValue(string $name) {
471  return $this->initial_values[$name] ?? null;
472  }
473 
481  public function hasInitialValue(string $name): bool {
482  return isset($this->initial_values[$name]);
483  }
484 
492  public function isLocked(string $name): bool {
493  $testing = $this->values['testing_mode'] ?? false;
494  return !$testing && in_array($name, $this->locked_values) && $this->hasValue($name);
495  }
496 
506  public function __set(string $name, $value): void {
507  if ($this->wasWarnedLocked($name)) {
508  return;
509  }
510 
511  if (in_array($name, $this->path_properties)) {
512  $value = Paths::sanitize($value);
513  }
514 
515  $this->values[$name] = $value;
516  }
517 
524  public function __isset(string $name): bool {
525  return $this->__get($name) !== null;
526  }
527 
534  public function __unset(string $name): void {
535  if ($this->wasWarnedLocked($name)) {
536  return;
537  }
538 
539  unset($this->values[$name]);
540  }
541 
550  public function save(string $name, $value): bool {
551  if ($this->wasWarnedLocked($name)) {
552  return false;
553  }
554 
555  if (strlen($name) > 255) {
556  $this->getLogger()->error('The name length for configuration variables cannot be greater than 255');
557  return false;
558  }
559 
560  if ($value === null) {
561  // don't save null values
562  return $this->remove($name);
563  }
564 
565  $result = _elgg_services()->configTable->set($name, $value);
566 
567  $this->__set($name, $value);
568 
569  return $result;
570  }
571 
579  public function remove(string $name): bool {
580  if ($this->wasWarnedLocked($name)) {
581  return false;
582  }
583 
584  $result = _elgg_services()->configTable->remove($name);
585 
586  unset($this->values[$name]);
587 
588  return $result;
589  }
590 
597  protected function wasWarnedLocked(string $name): bool {
598  if (!$this->isLocked($name)) {
599  return false;
600  }
601 
602  $this->getLogger()->warning("The property {$name} is read-only.");
603 
604  return true;
605  }
606 }
hasInitialValue(string $name)
Was a value available at construction time? (From settings.php)
Definition: Config.php:481
static resolvePath(string $settings_path= '')
Resolve settings path.
Definition: Config.php:375
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:287
save(string $name, $value)
Save a configuration setting to the database.
Definition: Config.php:550
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:597
__get(string $name)
Get an Elgg configuration value if it&#39;s been set or loaded during the boot process.
Definition: Config.php:440
hasValue(string $name)
Test if we have a set value.
Definition: Config.php:460
__set(string $name, $value)
Set an Elgg configuration value.
Definition: Config.php:506
$value
Definition: generic.php:51
__construct(array $values=[])
Constructor.
Definition: Config.php:271
$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:317
__unset(string $name)
Handle unset()
Definition: Config.php:534
__isset(string $name)
Handle isset()
Definition: Config.php:524
isLocked(string $name)
Is this value locked?
Definition: Config.php:492
getLogger()
Returns logger.
Definition: Loggable.php:37
getCookieConfig()
Set up and return the cookie configuration array resolved from settings.
Definition: Config.php:397
getValues()
Get all values.
Definition: Config.php:388
getInitialValue(string $name)
Get a value set at construction time.
Definition: Config.php:470
_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:303