Completed
Push — master ( ef46bd...45441d )
by Jeroen De
02:58
created

ParamDefinitionFactory::newDefinitionsFromArrays()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6.027

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 10
cts 11
cp 0.9091
rs 8.9617
c 0
b 0
f 0
cc 6
nc 7
nop 1
crap 6.027
1
<?php
2
3
namespace ParamProcessor;
4
5
use Exception;
6
use OutOfBoundsException;
7
use ParamProcessor\PackagePrivate\ParamType;
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
	private $types;
19
20
	/**
21
	 * @since 1.8
22
	 */
23 24
	public function __construct( ParameterTypes $types = null ) {
24 24
		$this->types = $types ?? new ParameterTypes();
25 24
	}
26
27
	/**
28
	 * Returns a ParamDefinitionFactory that already has the core parameter types (@see ParameterTypes) registered.
29
	 *
30
	 * @since 1.6
31
	 */
32 24
	public static function newDefault(): self {
33 24
		return new self( ParameterTypes::newCoreTypes() );
34
	}
35
36
	/**
37
	 * @deprecated since 1.0
38
	 */
39 78
	public static function singleton(): self {
40 78
		static $instance = false;
41
42 78
		if ( $instance === false ) {
43
			$instance = new self();
44
			$instance->registerGlobals();
0 ignored issues
show
Deprecated Code introduced by
The method ParamProcessor\ParamDefi...tory::registerGlobals() has been deprecated with message: since 1.6

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...
45
		}
46
47 78
		return $instance;
48
	}
49
50
	/**
51
	 * Registers the parameter types specified in the global $wgParamDefinitions.
52
	 * @deprecated since 1.6
53
	 */
54
	public function registerGlobals() {
55
		if ( array_key_exists( 'wgParamDefinitions', $GLOBALS ) ) {
56
			foreach ( $GLOBALS['wgParamDefinitions'] as $type => $data ) {
57
				if ( is_string( $data ) ) {
58
					$data = [ 'definition' => $data ];
59
				}
60
61
				$this->registerType( $type, $data );
62
			}
63
		}
64
	}
65
66
	/**
67
	 * Registers a parameter type.
68
	 *
69
	 * The type is specified as a string identifier for the type, ie 'boolean',
70
	 * and an array containing further data. This data currently includes:
71
	 *
72
	 * - string-parser:       the parser to use to transform string values
73
	 *                        This class needs to implement ValueParser. Default: NullParser
74
	 * - typed-parser:        DEPRECATED since 1.6 - the parser to use to transform typed PHP values
75
	 *                        This class needs to implement ValueParser. Default: NullParser
76
	 * - validator:           the validation object to use
77
	 *                        This class needs to implement ValueValidator. Default: NullValidator
78
	 * - validation-callback  a callback to use for validation, called before the ValueValidator
79
	 *                        This callback needs to return a boolean indicating validity.
80
	 *
81
	 * @since 1.0
82
	 *
83
	 * @param string $type
84
	 * @param array $data
85
	 *
86
	 * @return boolean DEPRECATED since 1.6 - Indicates if the type was registered
87
	 */
88
	public function registerType( $type, array $data ) {
89
		if ( $this->types->hasType( $type ) ) {
90
			return false;
91
		}
92
93
		$this->types->addType( $type, $data );
94
95
		return true;
96
	}
97
98
	/**
99
	 * Creates a new instance of a ParamDefinition based on the provided type.
100
	 *
101
	 * @param string $typeName
102
	 * @param string $name
103
	 * @param mixed $default
104
	 * @param string $message
105
	 * @param boolean $isList
106
	 *
107
	 * @return ParamDefinition
108
	 * @throws OutOfBoundsException
109
	 */
110 58
	public function newDefinition( string $typeName, string $name, $default, string $message, bool $isList = false ): ParamDefinition {
111 58
		if ( !$this->types->hasType( $typeName ) ) {
112
			throw new OutOfBoundsException( 'Unknown parameter type "' . $typeName . '".' );
113
		}
114
115 58
		$type = $this->types->getType( $typeName );
116 58
		$class = $type->getClassName();
117
118
		/**
119
		 * @var ParamDefinition $definition
120
		 */
121 58
		$definition = new $class(
122 58
			$typeName,
123
			$name,
124
			$default,
125
			$message,
126
			$isList
127
		);
128
129 58
		$validator = $type->getValidatorClass();
130
131 58
		if ( $validator !== NullValidator::class ) {
132 58
			$definition->setValueValidator( new $validator() );
133
		}
134
135 58
		$validationCallback = $type->getValidationCallback();
136
137 58
		if ( $validationCallback !== null ) {
138 39
			$definition->setValidationCallback( $validationCallback );
139
		}
140
141 58
		return $definition;
142
	}
143
144
	/**
145
	 * Package private
146
	 */
147 78
	public function getType( string $typeName ): ParamType {
148 78
		return $this->types->getType( $typeName );
149
	}
150
151
	/**
152
	 * @param array $definitionArray
153
	 * @param bool $getMad DEPRECATED since 1.6
154
	 *
155
	 * @return ParamDefinition|false
156
	 * @throws Exception
157
	 */
158 58
	public function newDefinitionFromArray( array $definitionArray, $getMad = true ) {
159 58
		foreach ( [ 'name', 'message' ] as $requiredElement ) {
160 58
			if ( !array_key_exists( $requiredElement, $definitionArray ) ) {
161 1
				if ( $getMad ) {
162 1
					throw new Exception( 'Could not construct a ParamDefinition from an array without ' . $requiredElement . ' element' );
163
				}
164
165
				return false;
166
			}
167
		}
168
169 57
		$definition = $this->newDefinition(
170 57
			array_key_exists( 'type', $definitionArray ) ? $definitionArray['type'] : 'string',
171 57
			$definitionArray['name'],
172 57
			array_key_exists( 'default', $definitionArray ) ? $definitionArray['default'] : null,
173 57
			$definitionArray['message'],
174 57
			array_key_exists( 'islist', $definitionArray ) ? $definitionArray['islist'] : false
175
		);
176
177 57
		$definition->setArrayValues( $definitionArray );
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...
178
179 57
		return $definition;
180
	}
181
182
	/**
183
	 * @since 1.9
184
	 *
185
	 * @param array $definitionArrays Each element must either be
186
	 * - A definition array with "name" key
187
	 * - A name key pointing to a definition array
188
	 * - A ParamDefinition instance (discouraged)
189
	 *
190
	 * @return ParamDefinition[]
191
	 * @throws Exception
192
	 */
193 74
	public function newDefinitionsFromArrays( array $definitionArrays ): array {
194 74
		$cleanList = [];
195
196 74
		foreach ( $definitionArrays as $key => $definitionArray ) {
197 18
			if ( is_array( $definitionArray ) ) {
198 17
				if ( !array_key_exists( 'name', $definitionArray ) && is_string( $key ) ) {
199 15
					$definitionArray['name'] = $key;
200
				}
201
202 17
				$definitionArray = $this->newDefinitionFromArray( $definitionArray );
203
			}
204
205 17
			if ( !( $definitionArray instanceof IParamDefinition ) ) {
206
				throw new Exception( 'Parameter definition not an instance of IParamDefinition' );
207
			}
208
209 17
			$cleanList[$definitionArray->getName()] = $definitionArray;
210
		}
211
212 73
		return $cleanList;
213
	}
214
215
}
216