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 Collection 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 Collection, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class Collection extends BaseCollection |
||
12 | { |
||
13 | /** |
||
14 | * Cassandra rows instance |
||
15 | * |
||
16 | * @var \Cassandra\Rows |
||
17 | */ |
||
18 | private $rows; |
||
19 | |||
20 | /** |
||
21 | * Items model |
||
22 | * |
||
23 | * @var Model |
||
24 | */ |
||
25 | private $model; |
||
26 | |||
27 | /** |
||
28 | * Create a new collection. |
||
29 | * |
||
30 | * @param mixed $items |
||
31 | * @param Model $model |
||
32 | */ |
||
33 | 31 | public function __construct($items = [], Model $model = null) |
|
42 | |||
43 | /** |
||
44 | * Prepare items for collection |
||
45 | * |
||
46 | * @return array|Model[] |
||
47 | */ |
||
48 | 31 | protected function prepareItems($items) |
|
62 | |||
63 | /** |
||
64 | * Next page token |
||
65 | * |
||
66 | * @return mixed |
||
67 | */ |
||
68 | 2 | public function getNextPageToken() |
|
72 | |||
73 | /** |
||
74 | * Last page indicator |
||
75 | * @return bool |
||
76 | */ |
||
77 | 28 | public function isLastPage() |
|
85 | |||
86 | /** |
||
87 | * Get next page |
||
88 | * |
||
89 | * @return Collection |
||
90 | */ |
||
91 | 3 | public function nextPage() |
|
97 | |||
98 | /** |
||
99 | * Get rows instance |
||
100 | * |
||
101 | * @return \Cassandra\Rows |
||
102 | */ |
||
103 | 25 | public function getRows() |
|
107 | |||
108 | /** |
||
109 | * Update current collection with results from |
||
110 | * the next page |
||
111 | * |
||
112 | * @return Collection |
||
113 | */ |
||
114 | 2 | public function appendNextPage() |
|
125 | |||
126 | /** |
||
127 | * Find a model in the collection by key. |
||
128 | * |
||
129 | * @param mixed $key |
||
130 | * @param mixed $default |
||
131 | * |
||
132 | * @return \Illuminate\Database\Eloquent\Model|static |
||
133 | */ |
||
134 | 2 | public function find($key, $default = null) |
|
156 | |||
157 | /** |
||
158 | * Merge the collection with the given items. |
||
159 | * |
||
160 | * @param \ArrayAccess|array $items |
||
161 | * @return static |
||
162 | */ |
||
163 | public function merge($items) |
||
173 | |||
174 | /** |
||
175 | * Reload a fresh model instance from the database for all the entities. |
||
176 | * |
||
177 | * @param array|string $with |
||
178 | * @return static |
||
179 | */ |
||
180 | public function fresh($with = []) |
||
199 | |||
200 | /** |
||
201 | * Diff the collection with the given items. |
||
202 | * |
||
203 | * @param \ArrayAccess|array $items |
||
204 | * @return static |
||
205 | */ |
||
206 | View Code Duplication | public function diff($items) |
|
220 | |||
221 | /** |
||
222 | * Intersect the collection with the given items. |
||
223 | * |
||
224 | * @param \ArrayAccess|array $items |
||
225 | * @return static |
||
226 | */ |
||
227 | View Code Duplication | public function intersect($items) |
|
241 | |||
242 | /** |
||
243 | * Return only unique items from the collection. |
||
244 | * |
||
245 | * @param string|callable|null $key |
||
246 | * @param bool $strict |
||
247 | * @return static|\Illuminate\Support\Collection |
||
248 | */ |
||
249 | public function unique($key = null, $strict = false) |
||
257 | |||
258 | /** |
||
259 | * Returns only the models from the collection with the specified keys. |
||
260 | * |
||
261 | * @param mixed $keys |
||
262 | * @return static |
||
263 | */ |
||
264 | public function only($keys) |
||
274 | |||
275 | /** |
||
276 | * Returns all models in the collection except the models with specified keys. |
||
277 | * |
||
278 | * @param mixed $keys |
||
279 | * @return static |
||
280 | */ |
||
281 | public function except($keys) |
||
287 | |||
288 | |||
289 | /** |
||
290 | * Get a dictionary keyed by primary keys. |
||
291 | * |
||
292 | * @param \ArrayAccess|array|null $items |
||
293 | * @return array |
||
294 | */ |
||
295 | public function getDictionary($items = null) |
||
307 | } |
||
308 |
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.