Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
15 / 15 |
|
100.00% |
4 / 4 |
CRAP | |
100.00% |
1 / 1 |
| MaxOccursRule | |
100.00% |
15 / 15 |
|
100.00% |
4 / 4 |
12 | |
100.00% |
1 / 1 |
| name | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| symbol | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| testConditions | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
7 | |||
| exceptionMessageOnTestFailure | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace WsdlToPhp\PackageGenerator\File\Validation; |
| 6 | |
| 7 | /** |
| 8 | * @see https://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#p-max_occurs |
| 9 | * Validation Rule: Element Sequence Locally Valid (Particle) |
| 10 | * For a sequence (possibly empty) of element information items to be locally ·valid· with respect to a particle the appropriate case among the following must be true: |
| 11 | * - 1 If the {term} is a wildcard, then all of the following must be true: |
| 12 | * - 1.1 The length of the sequence must be greater than or equal to the {min occurs}. |
| 13 | * - 1.2 If {max occurs} is a number, the length of the sequence must be less than or equal to the {max occurs}. |
| 14 | * - 1.3 Each element information item in the sequence must be ·valid· with respect to the wildcard as defined by Item Valid (Wildcard) (§3.10.4). |
| 15 | * - 2 If the {term} is an element declaration, then all of the following must be true: |
| 16 | * - 2.1 The length of the sequence must be greater than or equal to the {min occurs}. |
| 17 | * - 2.2 If {max occurs} is a number, the length of the sequence must be less than or equal to the {max occurs}. |
| 18 | * - 2.3 For each element information item in the sequence one of the following must be true: |
| 19 | * - 2.3.1 The element declaration is local (i.e. its {scope} must not be global), its {abstract} is false, the element information item's [namespace name] is identical to the element declaration's {target namespace} (where an ·absent· {target namespace} is taken to be identical to a [namespace name] with no value) and the element information item's [local name] matches the element declaration's {name}. |
| 20 | * In this case the element declaration is the ·context-determined declaration· for the element information item with respect to Schema-Validity Assessment (Element) (§3.3.4) and Assessment Outcome (Element) (§3.3.5). |
| 21 | * - 2.3.2 The element declaration is top-level (i.e. its {scope} is global), {abstract} is false, the element information item's [namespace name] is identical to the element declaration's {target namespace} (where an ·absent· {target namespace} is taken to be identical to a [namespace name] with no value) and the element information item's [local name] matches the element declaration's {name}. |
| 22 | * In this case the element declaration is the ·context-determined declaration· for the element information item with respect to Schema-Validity Assessment (Element) (§3.3.4) and Assessment Outcome (Element) (§3.3.5). |
| 23 | * - 2.3.3 The element declaration is top-level (i.e. its {scope} is global), its {disallowed substitutions} does not contain substitution, the [local ] and [namespace name] of the element information item resolve to an element declaration, as defined in QName resolution (Instance) (§3.15.4) -- [Definition:] call this declaration the substituting declaration and the ·substituting declaration· together with the particle's element declaration's {disallowed substitutions} is validly substitutable for the particle's element declaration as defined in Substitution Group OK (Transitive) (§3.3.6). |
| 24 | * In this case the ·substituting declaration· is the ·context-determined declaration· for the element information item with respect to Schema-Validity Assessment (Element) (§3.3.4) and Assessment Outcome (Element) (§3.3.5). |
| 25 | * - 3 If the {term} is a model group, then all of the following must be true: |
| 26 | * - 3.1 There is a ·partition· of the sequence into n sub-sequences such that n is greater than or equal to {min occurs}. |
| 27 | * - 3.2 If {max occurs} is a number, n must be less than or equal to {max occurs}. |
| 28 | * - 3.3 Each sub-sequence in the ·partition· is ·valid· with respect to that model group as defined in Element Sequence Valid (§3.8.4). |
| 29 | * Note: Clauses clause 1 and clause 2.3.3 do not interact: an element information item validatable by a declaration with a substitution group head in a different namespace is not validatable by a wildcard which accepts the head's namespace but not its own. |
| 30 | */ |
| 31 | class MaxOccursRule extends AbstractMinMaxRule |
| 32 | { |
| 33 | public function name(): string |
| 34 | { |
| 35 | return 'maxOccurs'; |
| 36 | } |
| 37 | |
| 38 | public function symbol(): string |
| 39 | { |
| 40 | return self::SYMBOL_MAX_INCLUSIVE; |
| 41 | } |
| 42 | |
| 43 | /** |
| 44 | * If maxOccurs is 'unbounded', no need to check occurrences count. |
| 45 | * |
| 46 | * @param mixed $value |
| 47 | */ |
| 48 | final public function testConditions(string $parameterName, $value, bool $itemType = false): string |
| 49 | { |
| 50 | $test = ''; |
| 51 | if ($this->getAttribute()->isArray() && ((is_scalar($value) && 'unbounded' !== $value) || (is_array($value) && !in_array('unbounded', $value)))) { |
| 52 | if ($itemType) { |
| 53 | $test = 'is_array($this->%1$s) && count($this->%1$s) %3$s %2$d'; |
| 54 | $symbol = self::SYMBOL_MAX_EXCLUSIVE; |
| 55 | } else { |
| 56 | $test = 'is_array($%4$s) && count($%4$s) %3$s %2$d'; |
| 57 | $symbol = $this->symbol(); |
| 58 | } |
| 59 | $test = sprintf($test, $this->getAttribute()->getCleanName(), $value, $symbol, $parameterName); |
| 60 | } |
| 61 | |
| 62 | return $test; |
| 63 | } |
| 64 | |
| 65 | final public function exceptionMessageOnTestFailure(string $parameterName, $value, bool $itemType = false): string |
| 66 | { |
| 67 | if ($itemType) { |
| 68 | $message = 'sprintf(\'You can\\\'t add anymore element to this property that already contains %%s elements, the number of elements contained by the property must be %1$s %2$s\', count($this->%4$s))'; |
| 69 | } else { |
| 70 | $message = 'sprintf(\'Invalid count of %%s, the number of elements contained by the property must be %1$s %2$s\', count($%3$s))'; |
| 71 | } |
| 72 | |
| 73 | return sprintf($message, $this->comparisonString(), is_array($value) ? implode(',', array_unique($value)) : $value, $parameterName, $this->getAttribute()->getCleanName()); |
| 74 | } |
| 75 | } |