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:
1 | <?php |
||
25 | class QueryParameters implements EncodingParametersInterface |
||
26 | { |
||
27 | const INVALID_INCLUDE_PATHS = '9f4922b8-8e8b-4847-baf2-5831adfd6813'; |
||
28 | const INVALID_FIELD_SET = 'ec7d2c6b-97d1-4f94-ba94-d141d985fc6f'; |
||
29 | |||
30 | /** |
||
31 | * @var string[]|null |
||
32 | * @API\Property(path="[include]", parser="parseIncludePaths") |
||
33 | * @Assert\Type(type="array") |
||
34 | * @Assert\All({@Assert\Type(type="string")}) |
||
35 | */ |
||
36 | protected $includePaths; |
||
37 | |||
38 | /** |
||
39 | * @var array[]|null |
||
40 | * @API\Property(path="[fields]", parser="parseFieldSets") |
||
41 | * @Assert\Type(type="array") |
||
42 | * @Assert\All({@Assert\Type(type="string")}) |
||
43 | */ |
||
44 | protected $fieldSets; |
||
45 | |||
46 | /** |
||
47 | * @inheritdoc |
||
48 | */ |
||
49 | 2 | public function getIncludePaths() |
|
53 | |||
54 | /** |
||
55 | * Sets include paths |
||
56 | * |
||
57 | * @param string[]|null $paths |
||
58 | * @return $this |
||
59 | */ |
||
60 | 3 | public function setIncludePaths(array $paths = null) |
|
66 | |||
67 | /** |
||
68 | * @inheritdoc |
||
69 | */ |
||
70 | 1 | public function getFieldSets() |
|
74 | |||
75 | /** |
||
76 | * @inheritdoc |
||
77 | */ |
||
78 | 1 | public function getFieldSet($type) |
|
82 | |||
83 | /** |
||
84 | * @param \array[]|null $fieldSets |
||
85 | * @return $this |
||
86 | */ |
||
87 | 3 | public function setFieldSets(array $fieldSets = null) |
|
93 | |||
94 | /** |
||
95 | * @inheritdoc |
||
96 | */ |
||
97 | 1 | public function getSortParameters() |
|
101 | |||
102 | /** |
||
103 | * @inheritdoc |
||
104 | */ |
||
105 | 1 | public function getPaginationParameters() |
|
109 | |||
110 | /** |
||
111 | * @inheritdoc |
||
112 | */ |
||
113 | 1 | public function getFilteringParameters() |
|
117 | |||
118 | /** |
||
119 | * @inheritdoc |
||
120 | */ |
||
121 | public function getUnrecognizedParameters() |
||
125 | |||
126 | /** |
||
127 | * @inheritdoc |
||
128 | */ |
||
129 | 1 | public function isEmpty() |
|
130 | { |
||
131 | 1 | if (empty($this->getIncludePaths()) && |
|
132 | 1 | empty($this->getFieldSets()) && |
|
133 | 1 | empty($this->getSortParameters()) && |
|
134 | 1 | empty($this->getPaginationParameters()) && |
|
135 | 1 | empty($this->getFilteringParameters()) |
|
136 | ) { |
||
137 | 1 | return true; |
|
138 | } |
||
139 | |||
140 | 1 | return false; |
|
141 | } |
||
142 | |||
143 | /** |
||
144 | * Parse value of parameter that store include paths |
||
145 | * which should be included into response |
||
146 | * |
||
147 | * @param string|null $value |
||
148 | * @return array|null |
||
149 | */ |
||
150 | 2 | public function parseIncludePaths($value = null) { |
|
161 | |||
162 | /** |
||
163 | * Parse value of parameter that store fields which |
||
164 | * should be included into response |
||
165 | * |
||
166 | * @param array|null $value |
||
167 | * @return array|null |
||
168 | */ |
||
169 | 2 | public function parseFieldSets($value = null) { |
|
170 | 2 | if (empty($value)) { |
|
171 | 1 | return null; |
|
172 | } |
||
173 | |||
174 | 2 | if (!is_array($value)) { |
|
175 | 1 | throw new \InvalidArgumentException('Field sets value must be an array', 400); |
|
176 | } |
||
177 | |||
178 | 1 | foreach ($value as $resource => $fields) { |
|
179 | 1 | $value[$resource] = explode(',', $fields); |
|
180 | } |
||
181 | |||
182 | 1 | return $value; |
|
183 | } |
||
184 | |||
185 | /** |
||
186 | * Validate specified include paths |
||
187 | * |
||
188 | * @param ExecutionContextInterface $context |
||
189 | * @Assert\Callback() |
||
190 | */ |
||
191 | 1 | public function validateIncludePaths(ExecutionContextInterface $context) |
|
192 | { |
||
193 | 1 | if (!is_array($this->includePaths)) { |
|
194 | 1 | return; |
|
195 | } |
||
196 | |||
197 | 1 | $invalidPaths = array_diff($this->includePaths, $this->getAllowedIncludePaths()); |
|
198 | 1 | View Code Duplication | if (count($invalidPaths) > 0) { |
199 | $context |
||
200 | 1 | ->buildViolation('Invalid include paths: %paths%') |
|
201 | 1 | ->setParameter('%paths%', sprintf("'%s'", implode("', '", $invalidPaths))) |
|
202 | 1 | ->setPlural(count($invalidPaths)) |
|
203 | 1 | ->setInvalidValue($invalidPaths) |
|
204 | 1 | ->setCode(self::INVALID_INCLUDE_PATHS) |
|
205 | 1 | ->atPath('includePaths') |
|
206 | 1 | ->addViolation(); |
|
207 | } |
||
208 | 1 | } |
|
209 | |||
210 | /** |
||
211 | * Validate specified fields sets |
||
212 | * |
||
213 | * @param ExecutionContextInterface $context |
||
214 | * @Assert\Callback() |
||
215 | */ |
||
216 | 1 | public function validateFieldSets(ExecutionContextInterface $context) |
|
217 | { |
||
218 | 1 | if (!is_array($this->fieldSets)) { |
|
219 | 1 | return; |
|
220 | } |
||
221 | |||
222 | 1 | foreach ($this->fieldSets as $resource => $fields) { |
|
223 | 1 | $invalidFields = array_diff($fields, $this->getAllowedFields($resource)); |
|
224 | |||
225 | 1 | View Code Duplication | if (count($invalidFields) > 0) { |
226 | $context |
||
227 | 1 | ->buildViolation('Invalid fields: %fields%') |
|
228 | 1 | ->setParameter('%fields%', sprintf("'%s'", implode("', '", $invalidFields))) |
|
229 | 1 | ->setPlural(count($invalidFields)) |
|
230 | 1 | ->setInvalidValue($invalidFields) |
|
231 | 1 | ->setCode(self::INVALID_FIELD_SET) |
|
232 | 1 | ->atPath('fieldSets.' . $resource) |
|
233 | 1 | ->addViolation(); |
|
234 | } |
||
235 | } |
||
236 | 1 | } |
|
237 | |||
238 | /** |
||
239 | * Returns list of allowed include paths |
||
240 | * |
||
241 | * @return string[] |
||
242 | */ |
||
243 | 1 | protected function getAllowedIncludePaths() |
|
247 | |||
248 | /** |
||
249 | * Returns list of fields available in specified resource |
||
250 | * |
||
251 | * @param string $resource |
||
252 | * @return array[] |
||
253 | */ |
||
254 | 1 | protected function getAllowedFields($resource) |
|
258 | } |
||
259 |