Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ConstraintParameterParser often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ConstraintParameterParser, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
41 | class ConstraintParameterParser { |
||
42 | |||
43 | /** |
||
44 | * @var Config |
||
45 | */ |
||
46 | private $config; |
||
47 | |||
48 | /** |
||
49 | * @var SnakDeserializer |
||
50 | */ |
||
51 | private $snakDeserializer; |
||
52 | |||
53 | /** |
||
54 | * @var ConstraintParameterRenderer |
||
55 | */ |
||
56 | private $constraintParameterRenderer; |
||
57 | |||
58 | /** |
||
59 | * @var string[] |
||
60 | */ |
||
61 | private $conceptBaseUris; |
||
62 | |||
63 | /** |
||
64 | * @param Config $config |
||
65 | * contains entity IDs used in constraint parameters (constraint statement qualifiers) |
||
66 | * @param DeserializerFactory $factory |
||
67 | * used to parse constraint statement qualifiers into constraint parameters |
||
68 | * @param ConstraintParameterRenderer $constraintParameterRenderer |
||
69 | * used to render incorrect parameters for error messages |
||
70 | * @param string[] $conceptBaseUris |
||
71 | * mapping from repository names to base URIs of concept URIs, |
||
72 | * used to obtain the full unit string from an entity ID given in constraint parameters |
||
73 | */ |
||
74 | public function __construct( |
||
75 | Config $config, |
||
76 | DeserializerFactory $factory, |
||
77 | ConstraintParameterRenderer $constraintParameterRenderer, |
||
78 | array $conceptBaseUris |
||
79 | ) { |
||
80 | $this->config = $config; |
||
81 | $this->snakDeserializer = $factory->newSnakDeserializer(); |
||
82 | $this->constraintParameterRenderer = $constraintParameterRenderer; |
||
83 | $this->conceptBaseUris = $conceptBaseUris; |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * Check if any errors are recorded in the constraint parameters. |
||
88 | * @param array $parameters |
||
89 | * @throws ConstraintParameterException |
||
90 | */ |
||
91 | public function checkError( array $parameters ) { |
||
92 | if ( array_key_exists( '@error', $parameters ) ) { |
||
93 | $error = $parameters['@error']; |
||
94 | if ( array_key_exists( 'toolong', $error ) && $error['toolong'] ) { |
||
95 | $msg = 'wbqc-violation-message-parameters-error-toolong'; |
||
96 | } else { |
||
97 | $msg = 'wbqc-violation-message-parameters-error-unknown'; |
||
98 | } |
||
99 | throw new ConstraintParameterException( new ViolationMessage( $msg ) ); |
||
100 | } |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * Require that $parameters contains exactly one $parameterId parameter. |
||
105 | * @param array $parameters |
||
106 | * @param string $parameterId |
||
107 | * @throws ConstraintParameterException |
||
108 | */ |
||
109 | View Code Duplication | private function requireSingleParameter( array $parameters, $parameterId ) { |
|
|
|||
110 | if ( count( $parameters[$parameterId] ) !== 1 ) { |
||
111 | throw new ConstraintParameterException( |
||
112 | ( new ViolationMessage( 'wbqc-violation-message-parameter-single' ) ) |
||
113 | ->withEntityId( new PropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
114 | ); |
||
115 | } |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Require that $snak is a {@link PropertyValueSnak}. |
||
120 | * @param Snak $snak |
||
121 | * @param string $parameterId |
||
122 | * @return void |
||
123 | * @throws ConstraintParameterException |
||
124 | */ |
||
125 | View Code Duplication | private function requireValueParameter( Snak $snak, $parameterId ) { |
|
126 | if ( !( $snak instanceof PropertyValueSnak ) ) { |
||
127 | throw new ConstraintParameterException( |
||
128 | ( new ViolationMessage( 'wbqc-violation-message-parameter-value' ) ) |
||
129 | ->withEntityId( new PropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
130 | ); |
||
131 | } |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * Parse a single entity ID parameter. |
||
136 | * @param array $snakSerialization |
||
137 | * @param string $parameterId |
||
138 | * @throws ConstraintParameterException |
||
139 | * @return EntityId |
||
140 | */ |
||
141 | View Code Duplication | private function parseEntityIdParameter( array $snakSerialization, $parameterId ) { |
|
142 | $snak = $this->snakDeserializer->deserialize( $snakSerialization ); |
||
143 | $this->requireValueParameter( $snak, $parameterId ); |
||
144 | $value = $snak->getDataValue(); |
||
145 | if ( $value instanceof EntityIdValue ) { |
||
146 | return $value->getEntityId(); |
||
147 | } else { |
||
148 | throw new ConstraintParameterException( |
||
149 | ( new ViolationMessage( 'wbqc-violation-message-parameter-entity' ) ) |
||
150 | ->withEntityId( new PropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
151 | ->withDataValue( $value, Role::CONSTRAINT_PARAMETER_VALUE ) |
||
152 | ); |
||
153 | } |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
158 | * @param string $constraintTypeItemId used in error messages |
||
159 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
160 | * @return string[] class entity ID serializations |
||
161 | */ |
||
162 | public function parseClassParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
163 | $this->checkError( $constraintParameters ); |
||
164 | $classId = $this->config->get( 'WBQualityConstraintsClassId' ); |
||
165 | if ( !array_key_exists( $classId, $constraintParameters ) ) { |
||
166 | throw new ConstraintParameterException( |
||
167 | ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) |
||
168 | ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) |
||
169 | ->withEntityId( new PropertyId( $classId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
170 | ); |
||
171 | } |
||
172 | |||
173 | $classes = []; |
||
174 | foreach ( $constraintParameters[$classId] as $class ) { |
||
175 | $classes[] = $this->parseEntityIdParameter( $class, $classId )->getSerialization(); |
||
176 | } |
||
177 | return $classes; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
182 | * @param string $constraintTypeItemId used in error messages |
||
183 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
184 | * @return string 'instance', 'subclass', or 'instanceOrSubclass' |
||
185 | */ |
||
186 | public function parseRelationParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
187 | $this->checkError( $constraintParameters ); |
||
188 | $relationId = $this->config->get( 'WBQualityConstraintsRelationId' ); |
||
189 | if ( !array_key_exists( $relationId, $constraintParameters ) ) { |
||
190 | throw new ConstraintParameterException( |
||
191 | ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) |
||
192 | ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) |
||
193 | ->withEntityId( new PropertyId( $relationId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
194 | ); |
||
195 | } |
||
196 | |||
197 | $this->requireSingleParameter( $constraintParameters, $relationId ); |
||
198 | $relationEntityId = $this->parseEntityIdParameter( $constraintParameters[$relationId][0], $relationId ); |
||
199 | $instanceId = $this->config->get( 'WBQualityConstraintsInstanceOfRelationId' ); |
||
200 | $subclassId = $this->config->get( 'WBQualityConstraintsSubclassOfRelationId' ); |
||
201 | $instanceOrSubclassId = $this->config->get( 'WBQualityConstraintsInstanceOrSubclassOfRelationId' ); |
||
202 | switch ( $relationEntityId ) { |
||
203 | case $instanceId: |
||
204 | return 'instance'; |
||
205 | case $subclassId: |
||
206 | return 'subclass'; |
||
207 | case $instanceOrSubclassId: |
||
208 | return 'instanceOrSubclass'; |
||
209 | View Code Duplication | default: |
|
210 | throw new ConstraintParameterException( |
||
211 | ( new ViolationMessage( 'wbqc-violation-message-parameter-oneof' ) ) |
||
212 | ->withEntityId( new PropertyId( $relationId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
213 | ->withEntityIdList( |
||
214 | [ |
||
215 | new ItemId( $instanceId ), |
||
216 | new ItemId( $subclassId ), |
||
217 | new ItemId( $instanceOrSubclassId ), |
||
218 | ], |
||
219 | Role::CONSTRAINT_PARAMETER_VALUE |
||
220 | ) |
||
221 | ); |
||
222 | } |
||
223 | } |
||
224 | |||
225 | /** |
||
226 | * Parse a single property ID parameter. |
||
227 | * @param array $snakSerialization |
||
228 | * @param string $parameterId used in error messages |
||
229 | * @throws ConstraintParameterException |
||
230 | * @return PropertyId |
||
231 | */ |
||
232 | private function parsePropertyIdParameter( array $snakSerialization, $parameterId ) { |
||
233 | $snak = $this->snakDeserializer->deserialize( $snakSerialization ); |
||
234 | $this->requireValueParameter( $snak, $parameterId ); |
||
235 | $value = $snak->getDataValue(); |
||
236 | if ( $value instanceof EntityIdValue ) { |
||
237 | $id = $value->getEntityId(); |
||
238 | if ( $id instanceof PropertyId ) { |
||
239 | return $id; |
||
240 | } |
||
241 | } |
||
242 | throw new ConstraintParameterException( |
||
243 | ( new ViolationMessage( 'wbqc-violation-message-parameter-property' ) ) |
||
244 | ->withEntityId( new PropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
245 | ->withDataValue( $value, Role::CONSTRAINT_PARAMETER_VALUE ) |
||
246 | ); |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
251 | * @param string $constraintTypeItemId used in error messages |
||
252 | * |
||
253 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
254 | * @return PropertyId |
||
255 | */ |
||
256 | View Code Duplication | public function parsePropertyParameter( array $constraintParameters, $constraintTypeItemId ) { |
|
257 | $this->checkError( $constraintParameters ); |
||
258 | $propertyId = $this->config->get( 'WBQualityConstraintsPropertyId' ); |
||
259 | if ( !array_key_exists( $propertyId, $constraintParameters ) ) { |
||
260 | throw new ConstraintParameterException( |
||
261 | ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) |
||
262 | ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) |
||
263 | ->withEntityId( new PropertyId( $propertyId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
264 | ); |
||
265 | } |
||
266 | |||
267 | $this->requireSingleParameter( $constraintParameters, $propertyId ); |
||
268 | return $this->parsePropertyIdParameter( $constraintParameters[$propertyId][0], $propertyId ); |
||
269 | } |
||
270 | |||
271 | private function parseItemIdParameter( PropertyValueSnak $snak, $parameterId ) { |
||
272 | $dataValue = $snak->getDataValue(); |
||
273 | if ( $dataValue instanceof EntityIdValue && |
||
274 | $dataValue->getEntityId() instanceof ItemId |
||
275 | ) { |
||
276 | return ItemIdSnakValue::fromItemId( $dataValue->getEntityId() ); |
||
277 | } else { |
||
278 | throw new ConstraintParameterException( |
||
279 | ( new ViolationMessage( 'wbqc-violation-message-parameter-item' ) ) |
||
280 | ->withEntityId( new PropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
281 | ->withDataValue( $dataValue, Role::CONSTRAINT_PARAMETER_VALUE ) |
||
282 | ); |
||
283 | } |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
288 | * @param string $constraintTypeItemId used in error messages |
||
289 | * @param bool $required whether the parameter is required (error if absent) or not ([] if absent) |
||
290 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
291 | * @return ItemIdSnakValue[] array of values |
||
292 | */ |
||
293 | public function parseItemsParameter( array $constraintParameters, $constraintTypeItemId, $required ) { |
||
294 | $this->checkError( $constraintParameters ); |
||
295 | $qualifierId = $this->config->get( 'WBQualityConstraintsQualifierOfPropertyConstraintId' ); |
||
296 | if ( !array_key_exists( $qualifierId, $constraintParameters ) ) { |
||
297 | if ( $required ) { |
||
298 | throw new ConstraintParameterException( |
||
299 | ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) |
||
300 | ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) |
||
301 | ->withEntityId( new PropertyId( $qualifierId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
302 | ); |
||
303 | } else { |
||
304 | return []; |
||
305 | } |
||
306 | } |
||
307 | |||
308 | $values = []; |
||
309 | foreach ( $constraintParameters[$qualifierId] as $parameter ) { |
||
310 | $snak = $this->snakDeserializer->deserialize( $parameter ); |
||
311 | switch ( true ) { |
||
312 | case $snak instanceof PropertyValueSnak: |
||
313 | $values[] = $this->parseItemIdParameter( $snak, $qualifierId ); |
||
314 | break; |
||
315 | case $snak instanceof PropertySomeValueSnak: |
||
316 | $values[] = ItemIdSnakValue::someValue(); |
||
317 | break; |
||
318 | case $snak instanceof PropertyNoValueSnak: |
||
319 | $values[] = ItemIdSnakValue::noValue(); |
||
320 | break; |
||
321 | } |
||
322 | } |
||
323 | return $values; |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
328 | * @param string $constraintTypeItemId used in error messages |
||
329 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
330 | * @return PropertyId[] |
||
331 | */ |
||
332 | public function parsePropertiesParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
333 | $this->checkError( $constraintParameters ); |
||
334 | $propertyId = $this->config->get( 'WBQualityConstraintsPropertyId' ); |
||
335 | if ( !array_key_exists( $propertyId, $constraintParameters ) ) { |
||
336 | throw new ConstraintParameterException( |
||
337 | ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) |
||
338 | ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) |
||
339 | ->withEntityId( new PropertyId( $propertyId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
340 | ); |
||
341 | } |
||
342 | |||
343 | $parameters = $constraintParameters[$propertyId]; |
||
344 | if ( count( $parameters ) === 1 && |
||
345 | $this->snakDeserializer->deserialize( $parameters[0] ) instanceof PropertyNoValueSnak |
||
346 | ) { |
||
347 | return []; |
||
348 | } |
||
349 | |||
350 | $properties = []; |
||
351 | foreach ( $parameters as $parameter ) { |
||
352 | $properties[] = $this->parsePropertyIdParameter( $parameter, $propertyId ); |
||
353 | } |
||
354 | return $properties; |
||
355 | } |
||
356 | |||
357 | /** |
||
358 | * @param array $snakSerialization |
||
359 | * @param string $parameterId |
||
360 | * @throws ConstraintParameterException |
||
361 | * @return DataValue|null |
||
362 | */ |
||
363 | private function parseValueOrNoValueParameter( array $snakSerialization, $parameterId ) { |
||
364 | $snak = $this->snakDeserializer->deserialize( $snakSerialization ); |
||
365 | if ( $snak instanceof PropertyValueSnak ) { |
||
366 | return $snak->getDataValue(); |
||
367 | } elseif ( $snak instanceof PropertyNoValueSnak ) { |
||
368 | return null; |
||
369 | } else { |
||
370 | throw new ConstraintParameterException( |
||
371 | ( new ViolationMessage( 'wbqc-violation-message-parameter-value-or-novalue' ) ) |
||
372 | ->withEntityId( new PropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
373 | ); |
||
374 | } |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * @param array $snakSerialization |
||
379 | * @param string $parameterId |
||
380 | * @return DataValue|null |
||
381 | */ |
||
382 | private function parseValueOrNoValueOrNowParameter( array $snakSerialization, $parameterId ) { |
||
383 | try { |
||
384 | return $this->parseValueOrNoValueParameter( $snakSerialization, $parameterId ); |
||
385 | } catch ( ConstraintParameterException $e ) { |
||
386 | // unknown value means “now” |
||
387 | return new NowValue(); |
||
388 | } |
||
389 | } |
||
390 | |||
391 | /** |
||
392 | * Checks whether there is exactly one non-null quantity with the given unit. |
||
393 | * @param DataValue|null $min |
||
394 | * @param DataValue|null $max |
||
395 | * @param string $unit |
||
396 | * @return bool |
||
397 | */ |
||
398 | private function exactlyOneQuantityWithUnit( DataValue $min = null, DataValue $max = null, $unit ) { |
||
399 | if ( !( $min instanceof UnboundedQuantityValue ) || |
||
400 | !( $max instanceof UnboundedQuantityValue ) |
||
401 | ) { |
||
402 | return false; |
||
403 | } |
||
404 | |||
405 | return ( $min->getUnit() === $unit ) !== ( $max->getUnit() === $unit ); |
||
406 | } |
||
407 | |||
408 | /** |
||
409 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
410 | * @param string $minimumId |
||
411 | * @param string $maximumId |
||
412 | * @param string $constraintTypeItemId used in error messages |
||
413 | * @param string $type 'quantity' or 'time' (can be data type or data value type) |
||
414 | * |
||
415 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
416 | * @return DataValue[] if the parameter is invalid or missing |
||
417 | */ |
||
418 | private function parseRangeParameter( array $constraintParameters, $minimumId, $maximumId, $constraintTypeItemId, $type ) { |
||
419 | $this->checkError( $constraintParameters ); |
||
420 | if ( !array_key_exists( $minimumId, $constraintParameters ) || |
||
421 | !array_key_exists( $maximumId, $constraintParameters ) |
||
422 | ) { |
||
423 | throw new ConstraintParameterException( |
||
424 | ( new ViolationMessage( 'wbqc-violation-message-range-parameters-needed' ) ) |
||
425 | ->withDataValueType( $type ) |
||
426 | ->withEntityId( new PropertyId( $minimumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
427 | ->withEntityId( new PropertyId( $maximumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
428 | ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) |
||
429 | ); |
||
430 | } |
||
431 | |||
432 | $this->requireSingleParameter( $constraintParameters, $minimumId ); |
||
433 | $this->requireSingleParameter( $constraintParameters, $maximumId ); |
||
434 | $parseFunction = $type === 'time' ? 'parseValueOrNoValueOrNowParameter' : 'parseValueOrNoValueParameter'; |
||
435 | $min = $this->$parseFunction( $constraintParameters[$minimumId][0], $minimumId ); |
||
436 | $max = $this->$parseFunction( $constraintParameters[$maximumId][0], $maximumId ); |
||
437 | |||
438 | $yearUnit = $this->config->get( 'WBQualityConstraintsYearUnit' ); |
||
439 | if ( $this->exactlyOneQuantityWithUnit( $min, $max, $yearUnit ) ) { |
||
440 | throw new ConstraintParameterException( |
||
441 | new ViolationMessage( 'wbqc-violation-message-range-parameters-one-year' ) |
||
442 | ); |
||
443 | } |
||
444 | if ( $min === null && $max === null || |
||
445 | $min !== null && $max !== null && $min->equals( $max ) ) { |
||
446 | throw new ConstraintParameterException( |
||
447 | ( new ViolationMessage( 'wbqc-violation-message-range-parameters-same' ) ) |
||
448 | ->withEntityId( new PropertyId( $minimumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
449 | ->withEntityId( new PropertyId( $maximumId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
450 | ); |
||
451 | } |
||
452 | |||
453 | return [ $min, $max ]; |
||
454 | } |
||
455 | |||
456 | /** |
||
457 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
458 | * @param string $constraintTypeItemId used in error messages |
||
459 | * |
||
460 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
461 | * @return DataValue[] a pair of two data values, either of which may be null to signify an open range |
||
462 | */ |
||
463 | public function parseQuantityRangeParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
464 | return $this->parseRangeParameter( |
||
465 | $constraintParameters, |
||
466 | $this->config->get( 'WBQualityConstraintsMinimumQuantityId' ), |
||
467 | $this->config->get( 'WBQualityConstraintsMaximumQuantityId' ), |
||
468 | $constraintTypeItemId, |
||
469 | 'quantity' |
||
470 | ); |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
475 | * @param string $constraintTypeItemId used in error messages |
||
476 | * |
||
477 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
478 | * @return DataValue[] a pair of two data values, either of which may be null to signify an open range |
||
479 | */ |
||
480 | public function parseTimeRangeParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
481 | return $this->parseRangeParameter( |
||
482 | $constraintParameters, |
||
483 | $this->config->get( 'WBQualityConstraintsMinimumDateId' ), |
||
484 | $this->config->get( 'WBQualityConstraintsMaximumDateId' ), |
||
485 | $constraintTypeItemId, |
||
486 | 'time' |
||
487 | ); |
||
488 | } |
||
489 | |||
490 | /** |
||
491 | * Parse a single string parameter. |
||
492 | * @param array $snakSerialization |
||
493 | * @param string $parameterId |
||
494 | * @throws ConstraintParameterException |
||
495 | * @return string |
||
496 | */ |
||
497 | View Code Duplication | private function parseStringParameter( array $snakSerialization, $parameterId ) { |
|
498 | $snak = $this->snakDeserializer->deserialize( $snakSerialization ); |
||
499 | $this->requireValueParameter( $snak, $parameterId ); |
||
500 | $value = $snak->getDataValue(); |
||
501 | if ( $value instanceof StringValue ) { |
||
502 | return $value->getValue(); |
||
503 | } else { |
||
504 | throw new ConstraintParameterException( |
||
505 | ( new ViolationMessage( 'wbqc-violation-message-parameter-string' ) ) |
||
506 | ->withEntityId( new PropertyId( $parameterId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
507 | ->withDataValue( $value, Role::CONSTRAINT_PARAMETER_VALUE ) |
||
508 | ); |
||
509 | } |
||
510 | } |
||
511 | |||
512 | /** |
||
513 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
514 | * @param string $constraintTypeItemId used in error messages |
||
515 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
516 | * @return string |
||
517 | */ |
||
518 | public function parseNamespaceParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
528 | |||
529 | /** |
||
530 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
531 | * @param string $constraintTypeItemId used in error messages |
||
532 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
533 | * @return string |
||
534 | */ |
||
535 | View Code Duplication | public function parseFormatParameter( array $constraintParameters, $constraintTypeItemId ) { |
|
536 | $this->checkError( $constraintParameters ); |
||
537 | $formatId = $this->config->get( 'WBQualityConstraintsFormatAsARegularExpressionId' ); |
||
538 | if ( !array_key_exists( $formatId, $constraintParameters ) ) { |
||
539 | throw new ConstraintParameterException( |
||
540 | ( new ViolationMessage( 'wbqc-violation-message-parameter-needed' ) ) |
||
541 | ->withEntityId( new ItemId( $constraintTypeItemId ), Role::CONSTRAINT_TYPE_ITEM ) |
||
542 | ->withEntityId( new PropertyId( $formatId ), Role::CONSTRAINT_PARAMETER_PROPERTY ) |
||
543 | ); |
||
544 | } |
||
545 | |||
546 | $this->requireSingleParameter( $constraintParameters, $formatId ); |
||
547 | return $this->parseStringParameter( $constraintParameters[$formatId][0], $formatId ); |
||
549 | |||
550 | /** |
||
551 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
552 | * @throws ConstraintParameterException if the parameter is invalid |
||
553 | * @return EntityId[] |
||
554 | */ |
||
555 | public function parseExceptionParameter( array $constraintParameters ) { |
||
569 | |||
570 | /** |
||
571 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
572 | * @throws ConstraintParameterException if the parameter is invalid |
||
573 | * @return string|null 'mandatory' or null |
||
574 | */ |
||
575 | public function parseConstraintStatusParameter( array $constraintParameters ) { |
||
598 | |||
599 | /** |
||
600 | * Require that $dataValue is a {@link MonolingualTextValue}. |
||
601 | * @param DataValue $dataValue |
||
602 | * @param string $parameterId |
||
603 | * @return void |
||
604 | * @throws ConstraintParameterException |
||
605 | */ |
||
606 | private function requireMonolingualTextParameter( DataValue $dataValue, $parameterId ) { |
||
615 | |||
616 | /** |
||
617 | * Parse a series of monolingual text snaks (serialized) into a map from language code to string. |
||
618 | * |
||
619 | * @param array $snakSerializations |
||
620 | * @param string $parameterId |
||
621 | * @throws ConstraintParameterException if invalid snaks are found or a language has multiple texts |
||
622 | * @return MultilingualTextValue |
||
623 | */ |
||
624 | private function parseMultilingualTextParameter( array $snakSerializations, $parameterId ) { |
||
649 | |||
650 | /** |
||
651 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
652 | * @throws ConstraintParameterException if the parameter is invalid |
||
653 | * @return MultilingualTextValue |
||
654 | */ |
||
655 | public function parseSyntaxClarificationParameter( array $constraintParameters ) { |
||
669 | |||
670 | /** |
||
671 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
672 | * @param string $constraintTypeItemId used in error messages |
||
673 | * @param string[]|null $validScopes a list of Context::TYPE_* constants which are valid where this parameter appears. |
||
674 | * If this is not null and one of the specified scopes is not in this list, a ConstraintParameterException is thrown. |
||
675 | * @throws ConstraintParameterException if the parameter is invalid |
||
676 | * @return string[]|null Context::TYPE_* constants |
||
677 | */ |
||
678 | public function parseConstraintScopeParameter( array $constraintParameters, $constraintTypeItemId, array $validScopes = null ) { |
||
732 | |||
733 | /** |
||
734 | * Turn an item ID into a full unit string (using the concept URI). |
||
735 | * |
||
736 | * @param ItemId $unitId |
||
737 | * @return string unit |
||
738 | */ |
||
739 | private function parseUnitParameter( ItemId $unitId ) { |
||
749 | |||
750 | /** |
||
751 | * Turn an ItemIdSnakValue into a single unit parameter. |
||
752 | * |
||
753 | * @param ItemIdSnakValue $item |
||
754 | * @return UnitsParameter |
||
755 | * @throws ConstraintParameterException |
||
756 | */ |
||
757 | private function parseUnitItem( ItemIdSnakValue $item ) { |
||
776 | |||
777 | /** |
||
778 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
779 | * @param string $constraintTypeItemId used in error messages |
||
780 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
781 | * @return UnitsParameter |
||
782 | */ |
||
783 | public function parseUnitsParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
804 | |||
805 | /** |
||
806 | * Turn an ItemIdSnakValue into a single entity type parameter. |
||
807 | * |
||
808 | * @param ItemIdSnakValue $item |
||
809 | * @return EntityTypesParameter |
||
810 | * @throws ConstraintParameterException |
||
811 | */ |
||
812 | private function parseEntityTypeItem( ItemIdSnakValue $item ) { |
||
848 | |||
849 | /** |
||
850 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
851 | * @param string $constraintTypeItemId used in error messages |
||
852 | * @throws ConstraintParameterException if the parameter is invalid or missing |
||
853 | * @return EntityTypesParameter |
||
854 | */ |
||
855 | public function parseEntityTypesParameter( array $constraintParameters, $constraintTypeItemId ) { |
||
877 | |||
878 | /** |
||
879 | * @param array $constraintParameters see {@link \WikibaseQuality\Constraint::getConstraintParameters()} |
||
880 | * @throws ConstraintParameterException if the parameter is invalid |
||
881 | * @return PropertyId[] |
||
882 | */ |
||
883 | public function parseSeparatorsParameter( array $constraintParameters ) { |
||
899 | |||
900 | } |
||
901 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.