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 declare(strict_types=1); |
||
30 | trait EncoderPropertiesTrait |
||
31 | { |
||
32 | /** |
||
33 | * @var SchemaContainerInterface |
||
34 | */ |
||
35 | private $container; |
||
36 | |||
37 | /** |
||
38 | * @var FactoryInterface |
||
39 | */ |
||
40 | private $factory; |
||
41 | |||
42 | /** |
||
43 | * @var string |
||
44 | */ |
||
45 | private $urlPrefix; |
||
46 | |||
47 | /** |
||
48 | * @var array |
||
49 | */ |
||
50 | private $includePaths; |
||
51 | |||
52 | /** |
||
53 | * @var array |
||
54 | */ |
||
55 | private $fieldSets; |
||
56 | |||
57 | /** |
||
58 | * @var int |
||
59 | */ |
||
60 | private $encodeOptions; |
||
61 | |||
62 | /** |
||
63 | * @var int |
||
64 | */ |
||
65 | private $encodeDepth; |
||
66 | |||
67 | /** |
||
68 | * @var iterable |
||
69 | */ |
||
70 | private $links; |
||
71 | |||
72 | /** |
||
73 | * @var iterable |
||
74 | */ |
||
75 | private $profile; |
||
76 | |||
77 | /** |
||
78 | * @var bool |
||
79 | */ |
||
80 | private $hasMeta; |
||
81 | |||
82 | /** |
||
83 | * @var mixed |
||
84 | */ |
||
85 | private $meta; |
||
86 | |||
87 | /** |
||
88 | * @var string|null |
||
89 | */ |
||
90 | private $jsonApiVersion; |
||
91 | |||
92 | /** |
||
93 | * @var mixed |
||
94 | */ |
||
95 | private $jsonApiMeta; |
||
96 | |||
97 | /** |
||
98 | * @var bool |
||
99 | */ |
||
100 | private $hasJsonApiMeta; |
||
101 | |||
102 | /** |
||
103 | * Reset to initial state. |
||
104 | * |
||
105 | * @param string $urlPrefix |
||
106 | * @param iterable $includePaths |
||
107 | * @param array $fieldSets |
||
108 | * @param int $encodeOptions |
||
109 | * @param int $encodeDepth |
||
110 | * |
||
111 | * @return self|EncoderInterface |
||
112 | */ |
||
113 | 82 | public function reset( |
|
137 | |||
138 | /** |
||
139 | * @return SchemaContainerInterface |
||
140 | */ |
||
141 | 71 | protected function getSchemaContainer(): SchemaContainerInterface |
|
145 | |||
146 | /** |
||
147 | * @param SchemaContainerInterface $container |
||
148 | * |
||
149 | * @return self |
||
150 | */ |
||
151 | 82 | public function setContainer(SchemaContainerInterface $container): self |
|
157 | |||
158 | /** |
||
159 | * @return FactoryInterface |
||
160 | */ |
||
161 | 80 | protected function getFactory(): FactoryInterface |
|
165 | |||
166 | /** |
||
167 | * @param FactoryInterface $factory |
||
168 | * |
||
169 | * @return self |
||
170 | */ |
||
171 | 82 | public function setFactory(FactoryInterface $factory): self |
|
177 | |||
178 | /** |
||
179 | * @param string $prefix |
||
180 | * |
||
181 | * @return self|EncoderInterface |
||
182 | */ |
||
183 | 82 | public function withUrlPrefix(string $prefix): EncoderInterface |
|
189 | /** |
||
190 | * @return string |
||
191 | */ |
||
192 | 80 | protected function getUrlPrefix(): string |
|
196 | |||
197 | /** |
||
198 | * @param iterable $paths |
||
199 | * |
||
200 | * @return self|EncoderInterface |
||
201 | */ |
||
202 | 82 | public function withIncludedPaths(iterable $paths): EncoderInterface |
|
222 | |||
223 | /** |
||
224 | * @return array |
||
225 | */ |
||
226 | 71 | protected function getIncludePaths(): array |
|
230 | |||
231 | /** |
||
232 | * @param array $fieldSets |
||
233 | * |
||
234 | * @return self|EncoderInterface |
||
235 | */ |
||
236 | 82 | public function withFieldSets(array $fieldSets): EncoderInterface |
|
242 | |||
243 | |||
244 | /** |
||
245 | * @return array |
||
246 | */ |
||
247 | 71 | protected function getFieldSets(): array |
|
251 | |||
252 | /** |
||
253 | * @param int $options |
||
254 | * |
||
255 | * @return self|EncoderInterface |
||
256 | */ |
||
257 | 82 | public function withEncodeOptions(int $options): EncoderInterface |
|
263 | |||
264 | /** |
||
265 | * @return int |
||
266 | */ |
||
267 | 74 | protected function getEncodeOptions(): int |
|
271 | |||
272 | /** |
||
273 | * @param int $depth |
||
274 | * |
||
275 | * @return self|EncoderInterface |
||
276 | */ |
||
277 | 82 | public function withEncodeDepth(int $depth): EncoderInterface |
|
285 | |||
286 | /** |
||
287 | * @return int |
||
288 | */ |
||
289 | 74 | protected function getEncodeDepth(): int |
|
293 | |||
294 | /** |
||
295 | * @param iterable $links |
||
296 | * |
||
297 | * @return self|EncoderInterface |
||
298 | */ |
||
299 | 5 | public function withLinks(iterable $links): EncoderInterface |
|
310 | |||
311 | /** |
||
312 | * @return bool |
||
313 | */ |
||
314 | 80 | protected function hasLinks(): bool |
|
318 | |||
319 | /** |
||
320 | * @return iterable |
||
321 | */ |
||
322 | 5 | protected function getLinks(): iterable |
|
326 | |||
327 | /** |
||
328 | * @param iterable $links |
||
329 | * |
||
330 | * @return self|EncoderInterface |
||
331 | */ |
||
332 | 1 | public function withProfile(iterable $links): EncoderInterface |
|
338 | |||
339 | /** |
||
340 | * @return bool |
||
341 | */ |
||
342 | 80 | protected function hasProfile(): bool |
|
346 | |||
347 | /** |
||
348 | * @return iterable |
||
349 | */ |
||
350 | 1 | protected function getProfile(): iterable |
|
354 | |||
355 | /** |
||
356 | * @param mixed $meta |
||
357 | * |
||
358 | * @return self|EncoderInterface |
||
359 | */ |
||
360 | 6 | public function withMeta($meta): EncoderInterface |
|
367 | |||
368 | /** |
||
369 | * @return bool |
||
370 | */ |
||
371 | 80 | protected function hasMeta(): bool |
|
375 | |||
376 | /** |
||
377 | * @return mixed |
||
378 | */ |
||
379 | 6 | public function getMeta() |
|
383 | |||
384 | /** |
||
385 | * @param string $version |
||
386 | * |
||
387 | * @return self|EncoderInterface |
||
388 | */ |
||
389 | 2 | public function withJsonApiVersion(string $version): EncoderInterface |
|
395 | |||
396 | /** |
||
397 | * @return bool |
||
398 | */ |
||
399 | 80 | protected function hasJsonApiVersion(): bool |
|
403 | |||
404 | /** |
||
405 | * @return string |
||
406 | */ |
||
407 | 2 | protected function getJsonApiVersion(): string |
|
411 | |||
412 | /** |
||
413 | * @param mixed $meta |
||
414 | * |
||
415 | * @return self|EncoderInterface |
||
416 | */ |
||
417 | 2 | public function withJsonApiMeta($meta): EncoderInterface |
|
424 | |||
425 | /** |
||
426 | * @return bool |
||
427 | */ |
||
428 | 80 | protected function hasJsonApiMeta(): bool |
|
432 | |||
433 | /** |
||
434 | * @return mixed |
||
435 | */ |
||
436 | 2 | protected function getJsonApiMeta() |
|
440 | |||
441 | /** |
||
442 | * @param mixed $resource |
||
443 | * @param string $relationshipName |
||
444 | * |
||
445 | * @return self|EncoderInterface |
||
446 | */ |
||
447 | 1 | View Code Duplication | public function withRelationshipSelfLink($resource, string $relationshipName): EncoderInterface |
457 | |||
458 | /** |
||
459 | * @param mixed $resource |
||
460 | * @param string $relationshipName |
||
461 | * |
||
462 | * @return self|EncoderInterface |
||
463 | */ |
||
464 | 1 | View Code Duplication | public function withRelationshipRelatedLink($resource, string $relationshipName): EncoderInterface |
474 | |||
475 | /** |
||
476 | * @param iterable $value |
||
477 | * |
||
478 | * @return array |
||
479 | */ |
||
480 | 2 | private function iterableToArray(iterable $value): array |
|
485 | } |
||
486 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.