1 | <?php |
||
12 | class Composite implements Specification |
||
13 | { |
||
14 | /** |
||
15 | * @var string |
||
16 | */ |
||
17 | private $operator; |
||
18 | |||
19 | /** |
||
20 | * @var array |
||
21 | */ |
||
22 | private $specifications = []; |
||
23 | |||
24 | /** |
||
25 | * Builds a composite specification. |
||
26 | * |
||
27 | * @param string $operator The operator used to join the specifications. |
||
28 | * @param array $specifications A list specifications to combine. |
||
29 | */ |
||
30 | public function __construct($operator, array $specifications = []) |
||
31 | { |
||
32 | $this->operator = $operator; |
||
33 | |||
34 | if (empty($specifications)) { |
||
35 | throw new \LogicException('No specifications given.'); |
||
36 | } |
||
37 | |||
38 | foreach ($specifications as $specification) { |
||
39 | $this->addSpecification($specification); |
||
40 | } |
||
41 | } |
||
42 | |||
43 | private function addSpecification(Specification $specification): void |
||
44 | { |
||
45 | $this->specifications[] = $specification; |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * {@inheritdoc} |
||
50 | */ |
||
51 | public function getRule(): string |
||
52 | { |
||
53 | return implode(sprintf(' %s ', $this->operator), array_map(function (Specification $specification) { |
||
54 | return sprintf('(%s)', $specification->getRule()); |
||
55 | }, $this->specifications)); |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * {@inheritdoc} |
||
60 | */ |
||
61 | public function getParameters(): array |
||
62 | { |
||
63 | $parametersCount = 0; |
||
64 | |||
65 | $parametersList = array_map(function (Specification $specification) use (&$parametersCount) { |
||
66 | $parametersCount += count($specification->getParameters()); |
||
67 | |||
68 | return $specification->getParameters(); |
||
69 | }, $this->specifications); |
||
70 | |||
71 | $mergedParameters = array_merge([], ...$parametersList); |
||
72 | |||
73 | // error handling in case of overriden parameters |
||
74 | if ($parametersCount !== count($mergedParameters)) { |
||
75 | $overridenParameters = $this->searchOverridenParameters($parametersList); |
||
76 | $specificationsTypes = array_map(function (Specification $spec) { |
||
77 | return get_class($spec); |
||
78 | }, $this->specifications); |
||
79 | |||
80 | throw new ParameterOverridenException(sprintf( |
||
81 | 'Looks like some parameters were overriden (%s) while combining specifications of types %s'."\n". |
||
82 | 'More information on how to solve this can be found here: https://github.com/K-Phoen/rulerz/issues/3', |
||
83 | implode(', ', $overridenParameters), |
||
84 | implode(', ', $specificationsTypes) |
||
85 | )); |
||
86 | } |
||
87 | |||
88 | return $mergedParameters; |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * Search the parameters that were overridden during the parameters-merge phase. |
||
93 | * |
||
94 | * @return array Names of the overridden parameters. |
||
95 | */ |
||
96 | private function searchOverridenParameters(array $parametersList): array |
||
116 | } |
||
117 |