File: DynamicDefaultValues.php

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (96 lines) | stat: -rw-r--r-- 2,483 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php

namespace MediaWiki\Settings;

use LogicException;
use MediaWiki\Settings\Config\ConfigBuilder;
use MediaWiki\Settings\Config\ConfigSchema;

class DynamicDefaultValues {

	private ConfigSchema $configSchema;

	/**
	 * @var array
	 */
	private $declarations;

	/**
	 * @param ConfigSchema $configSchema
	 */
	public function __construct( ConfigSchema $configSchema ) {
		$this->configSchema = $configSchema;
		$this->declarations = $this->configSchema->getDynamicDefaults();
	}

	/**
	 * Compute dynamic defaults for settings that have them defined.
	 *
	 * @param ConfigBuilder $configBuilder
	 *
	 * @return void
	 */
	public function applyDynamicDefaults( ConfigBuilder $configBuilder ): void {
		$alreadyComputed = [];

		foreach ( $this->declarations as $key => $unused ) {
			$this->computeDefaultFor( $key, $configBuilder, $alreadyComputed );
		}
	}

	/**
	 * Compute dynamic default for a setting, recursively computing any dependencies.
	 *
	 * @param string $key Name of setting
	 * @param ConfigBuilder $configBuilder
	 * @param array &$alreadyComputed Map whose keys are the names of settings whose dynamic
	 *   defaults have already been computed
	 * @param array $currentlyComputing Ordered map whose keys are the names of settings whose
	 *   dynamic defaults are currently being computed, for cycle detection.
	 */
	private function computeDefaultFor(
		string $key,
		ConfigBuilder $configBuilder,
		array &$alreadyComputed = [],
		array $currentlyComputing = []
	): void {
		if ( !isset( $this->declarations[ $key ] ) || isset( $alreadyComputed[ $key ] ) ) {
			return;
		}
		if ( isset( $currentlyComputing[ $key ] ) ) {
			throw new LogicException(
				'Cyclic dependency when computing dynamic default: ' .
				implode( ' -> ', array_keys( $currentlyComputing ) ) . " -> $key"
			);
		}
		if (
			$configBuilder->get( $key ) !==
			$this->configSchema->getDefaultFor( $key )
		) {
			// Default was already overridden, nothing more to do
			$alreadyComputed[ $key ] = true;

			return;
		}

		$currentlyComputing[ $key ] = true;

		$callback = $this->declarations[ $key ]['callback'];
		$argNames = $this->declarations[ $key ]['use'] ?? [];
		$args = [];

		foreach ( $argNames as $argName ) {
			$this->computeDefaultFor(
				$argName,
				$configBuilder,
				$alreadyComputed,
				$currentlyComputing
			);
			$args[] = $configBuilder->get( $argName );
		}

		$configBuilder->set( $key, $callback( ...$args ) );

		$alreadyComputed[ $key ] = true;
	}
}