Passed
Push — master ( 761e95...f1e6ba )
by Jeroen De
05:40
created

src/ParamDefinitionFactory.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace ParamProcessor;
4
5
use Exception;
6
use OutOfBoundsException;
7
use ValueParsers\NullParser;
8
use ValueValidators\NullValidator;
9
10
/**
11
 * Factory for ParamDefinition implementing objects.
12
 *
13
 * @licence GNU GPL v2+
14
 * @author Jeroen De Dauw < [email protected] >
15
 */
16
class ParamDefinitionFactory {
17
18
	/**
19
	 * Maps parameter type to handling ParameterDefinition implementing class.
20
	 *
21
	 * @since 1.0
22
	 *
23
	 * @var array
24
	 */
25
	private $typeToClass = [];
26
27
	/**
28
	 * Maps parameter type to its associated components.
29
	 *
30
	 * @since 1.0
31
	 *
32
	 * @var array
33
	 */
34
	private $typeToComponent = [];
35
36
	/**
37
	 * Returns a ParamDefinitionFactory that already has the core parameter types (@see ParameterTypes) registered.
38
	 *
39
	 * @since 1.6
40
	 */
41 8
	public static function newDefault(): self {
42 8
		$instance = new self();
43
44 8
		foreach ( ParameterTypes::getCoreTypes() as $type => $data ) {
45 8
			$instance->registerType( $type, $data );
46
		}
47
48 8
		return $instance;
49
	}
50
51
	/**
52
	 * @deprecated since 1.0
53
	 */
54 64
	public static function singleton(): self {
55 64
		static $instance = false;
56
57 64
		if ( $instance === false ) {
58
			$instance = new self();
59
			$instance->registerGlobals();
60
		}
61
62 64
		return $instance;
63
	}
64
65
	/**
66
	 * Registers the parameter types specified in the global $wgParamDefinitions.
67
	 * @deprecated since 1.6
68
	 */
69
	public function registerGlobals() {
70
		if ( array_key_exists( 'wgParamDefinitions', $GLOBALS ) ) {
71
			foreach ( $GLOBALS['wgParamDefinitions'] as $type => $data ) {
72
				if ( is_string( $data ) ) {
73
					$data = [ 'definition' => $data ];
74
				}
75
76
				$this->registerType( $type, $data );
77
			}
78
		}
79
	}
80
81
	/**
82
	 * Registers a parameter type.
83
	 *
84
	 * The type is specified as a string identifier for the type, ie 'boolean',
85
	 * and an array containing further data. This data currently includes:
86
	 *
87
	 * - string-parser:       the parser to use to transform string values
88
	 *                        This class needs to implement ValueParser. Default: NullParser
89
	 * - typed-parser:        DEPRECATED since 1.6 - the parser to use to transform typed PHP values
90
	 *                        This class needs to implement ValueParser. Default: NullParser
91
	 * - validator:           the validation object to use
92
	 *                        This class needs to implement ValueValidator. Default: NullValidator
93
	 * - validation-callback  a callback to use for validation, called before the ValueValidator
94
	 *                        This callback needs to return a boolean indicating validity.
95
	 *
96
	 * @since 1.0
97
	 *
98
	 * @param string $type
99
	 * @param array $data
100
	 *
101
	 * @return boolean DEPRECATED since 1.6 - Indicates if the type was registered
102
	 */
103 8
	public function registerType( $type, array $data ) {
104 8
		if ( array_key_exists( $type, $this->typeToClass ) ) {
105
			return false;
106
		}
107
108 8
		// Deprecated: definition key
109 8
		$class = array_key_exists( 'definition', $data ) ? $data['definition'] : ParamDefinition::class;
110
		$this->typeToClass[$type] = $class;
111
112 8
		$defaults = [
113
			'string-parser' => NullParser::class,
114
			'typed-parser' => NullParser::class,
115
			'validator' => NullValidator::class,
116
			'validation-callback' => null,
117
		];
118 8
119
		$this->typeToComponent[$type] = [];
120 8
121 8
		foreach ( $defaults as $component => $default ) {
122
			$this->typeToComponent[$type][$component] = array_key_exists( $component, $data ) ? $data[$component] : $default;
123
		}
124 8
125
		return true;
126
	}
127
128
	/**
129
	 * Creates a new instance of a ParamDefinition based on the provided type.
130
	 *
131
	 * @param string $type
132
	 * @param string $name
133
	 * @param mixed $default
134
	 * @param string $message
135
	 * @param boolean $isList
136
	 *
137
	 * @return ParamDefinition
138
	 * @throws OutOfBoundsException
139
	 */
140
	public function newDefinition( string $type, string $name, $default, string $message, bool $isList = false ): ParamDefinition {
141 42
		if ( !array_key_exists( $type, $this->typeToClass ) ) {
142 42
			throw new OutOfBoundsException( 'Unknown parameter type "' . $type . '".' );
143
		}
144
145
		$class = $this->typeToClass[$type];
146 42
147
		/**
148
		 * @var ParamDefinition $definition
149
		 */
150
		$definition = new $class(
151 42
			$type,
152 42
			$name,
153
			$default,
154
			$message,
155
			$isList
156
		);
157
158
		$validator = $this->typeToComponent[$type]['validator'];
159 42
160
		if ( $validator !== NullValidator::class ) {
161 42
			$definition->setValueValidator( new $validator() );
162 42
		}
163
164
		$validationCallback = $this->typeToComponent[$type]['validation-callback'];
165 42
166
		if ( $validationCallback !== null ) {
167 42
			$definition->setValidationCallback( $validationCallback );
168 39
		}
169
170
		return $definition;
171 42
	}
172
173
	/**
174
	 * Returns the specified component for the provided parameter type.
175
	 * This method is likely to change in the future in a compat breaking way.
176
	 *
177
	 * @param string $paramType
178
	 * @param string $componentType
179
	 *
180
	 * @throws Exception
181
	 * @return mixed
182
	 */
183
	public function getComponentForType( $paramType, $componentType ) {
184
		if ( !array_key_exists( $paramType, $this->typeToComponent ) ) {
185
			throw new Exception( 'Unknown parameter type "' . $paramType . '".' );
186 66
		}
187 66
188
		if ( !array_key_exists( $componentType, $this->typeToComponent[$paramType] ) ) {
189
			throw new Exception( 'Unknown parameter component type "' . $paramType . '".' );
190
		}
191 66
192
		return $this->typeToComponent[$paramType][$componentType];
193
	}
194
195 66
	/**
196
	 * @param array $param
197
	 * @param bool $getMad DEPRECATED since 1.6
198
	 *
199
	 * @return ParamDefinition|false
200
	 * @throws Exception
201
	 */
202
	public function newDefinitionFromArray( array $param, $getMad = true ) {
203
		foreach ( [ 'name', 'message' ] as $requiredElement ) {
204
			if ( !array_key_exists( $requiredElement, $param ) ) {
205
				if ( $getMad ) {
206
					throw new Exception( 'Could not construct a ParamDefinition from an array without ' . $requiredElement . ' element' );
207
				}
208
209 41
				return false;
210 41
			}
211 41
		}
212
213
		$parameter = $this->newDefinition(
214
			array_key_exists( 'type', $param ) ? $param['type'] : 'string',
215
			$param['name'],
216
			array_key_exists( 'default', $param ) ? $param['default'] : null,
217
			$param['message'],
218
			array_key_exists( 'islist', $param ) ? $param['islist'] : false
219
		);
220 41
221 41
		$parameter->setArrayValues( $param );
0 ignored issues
show
Deprecated Code introduced by
The method ParamProcessor\ParamDefinition::setArrayValues() has been deprecated with message: since 1.7
TODO: provide alternative in ParamDefinitionFactory

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
222 41
223 41
		return $parameter;
224 41
	}
225 41
226
}
227