Complex classes like BaseTrait 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 BaseTrait, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
19 | trait BaseTrait |
||
20 | { |
||
21 | /** |
||
22 | * @var array default items |
||
23 | */ |
||
24 | protected static $_defaults = []; |
||
25 | |||
26 | /** |
||
27 | * @var array items |
||
28 | */ |
||
29 | protected $_items = []; |
||
30 | |||
31 | /** |
||
32 | * Straight put an item. |
||
33 | * |
||
34 | * @param string $name item name. |
||
35 | * @param array $value item value. |
||
36 | */ |
||
37 | public function putItem($name, $value = null) |
||
38 | { |
||
39 | if (is_null($name) || is_int($name)) { |
||
40 | $this->_items[] = $value; |
||
41 | } else { |
||
42 | $this->_items[$name] = $value; |
||
43 | } |
||
44 | } |
||
45 | |||
46 | /** |
||
47 | * Get raw item. |
||
48 | * |
||
49 | * @param string $name item name. |
||
50 | * |
||
51 | * @return mixed item value. |
||
52 | */ |
||
53 | public function rawItem($name, $default = null) |
||
57 | |||
58 | /** |
||
59 | * Adds an item. Doesn't touch if already exists. |
||
60 | * |
||
61 | * @param string $name item name. |
||
62 | * @param array $value item value. |
||
63 | * @param string|array $where where to put, @see setItem |
||
64 | * |
||
65 | * @return $this for chaining |
||
66 | */ |
||
67 | public function addItem($name, $value = null, $where = '') |
||
68 | { |
||
69 | if (!$this->hasItem($name)) { |
||
70 | $this->setItem($name, $value, $where); |
||
71 | } |
||
72 | |||
73 | return $this; |
||
74 | } |
||
75 | |||
76 | /** |
||
77 | * Sets an item. Silently resets if already exists and mov. |
||
78 | * |
||
79 | * @param string $name item name. |
||
80 | * @param array $value item value. |
||
81 | * @param string|array $where where to put, can be empty, first, last and array of before and after |
||
82 | */ |
||
83 | public function setItem($name, $value = null, $where = '') |
||
84 | { |
||
85 | if ($name === null || $where === '') { |
||
86 | $this->putItem($name, $value); |
||
87 | } else { |
||
88 | $this->setItems([$name => $value], $where); |
||
89 | } |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * Returns item by name. |
||
94 | * |
||
95 | * @param string $name item name. |
||
96 | * |
||
97 | * @return mixed item value. |
||
98 | */ |
||
99 | public function getItem($name) |
||
103 | |||
104 | /** |
||
105 | * Check collection has the item. |
||
106 | * |
||
107 | * @param string $name item name. |
||
108 | * |
||
109 | * @return bool whether item exist. |
||
110 | */ |
||
111 | public function hasItem($name) |
||
115 | |||
116 | public function mergeItem($name, array $value) |
||
117 | { |
||
118 | if (!is_null($name)) { |
||
119 | $this->_items[$name] = ArrayHelper::merge($this->_items[$name], $value); |
||
120 | } |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * Check is item set. |
||
125 | * |
||
126 | * @param string $name item name. |
||
127 | * |
||
128 | * @return bool whether item is set. |
||
129 | */ |
||
130 | public function issetItem($name) |
||
134 | |||
135 | /** |
||
136 | * Delete an item. |
||
137 | * |
||
138 | * @param $name |
||
139 | */ |
||
140 | public function unsetItem($name) |
||
144 | |||
145 | /** |
||
146 | * Get specified items as array. |
||
147 | * |
||
148 | * @param mixed $keys specification |
||
149 | * |
||
150 | * @return array list of items |
||
151 | */ |
||
152 | public function getItems($keys = null) |
||
156 | |||
157 | /** |
||
158 | * Straight put items. |
||
159 | * |
||
160 | * @param array $items list of items |
||
161 | * |
||
162 | * @see setItem |
||
163 | */ |
||
164 | public function putItems(array $items) |
||
165 | { |
||
166 | foreach ($items as $k => $v) { |
||
167 | $this->putItem($k, $v); |
||
168 | } |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Adds items to specified place. |
||
173 | * |
||
174 | * @param array $items list of items |
||
175 | * @param mixed $where |
||
176 | * |
||
177 | * @see setItem() |
||
178 | */ |
||
179 | public function setItems($items, $where = '') |
||
180 | { |
||
181 | if (!$items) { |
||
|
|||
182 | return; |
||
183 | } elseif ($where === '') { |
||
184 | $this->putItems($items); |
||
185 | } elseif ($where === 'last') { |
||
186 | $this->_items = ArrayHelper::insertLast($this->_items, $items); |
||
187 | } elseif ($where === 'first') { |
||
188 | $this->_items = ArrayHelper::insertFirst($this->_items, $items); |
||
189 | } else { |
||
190 | $this->_items = ArrayHelper::insertInside($this->_items, $items, $where); |
||
191 | } |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * Adds items to specified place. |
||
196 | * Does not touch those items that already exists. |
||
197 | * |
||
198 | * @param array $items array of items. |
||
199 | * @param string|array $where where to add. See [[setItem()]] |
||
200 | * |
||
201 | * @return $this for chaining |
||
202 | * |
||
203 | * @see setItem() |
||
204 | */ |
||
205 | public function addItems(array $items, $where = '') |
||
206 | { |
||
207 | foreach ($items as $k => $v) { |
||
208 | if (!is_int($k) && $this->hasItem($k)) { |
||
209 | unset($items[$k]); |
||
210 | } |
||
211 | } |
||
212 | if ($items) { |
||
213 | $this->setItems($items, $where); |
||
214 | } |
||
215 | |||
216 | return $this; |
||
217 | } |
||
218 | |||
219 | public function mergeItems(array $items) |
||
223 | |||
224 | /** |
||
225 | * Unset specified items. |
||
226 | * |
||
227 | * @param mixed $keys specification |
||
228 | * |
||
229 | * @return array list of items |
||
230 | */ |
||
231 | public function unsetItems($keys = null) |
||
243 | |||
244 | public function resetItems(array $items) |
||
248 | /** |
||
249 | * Get keys. |
||
250 | * |
||
251 | * @return array for chaining |
||
252 | */ |
||
253 | public function keys() |
||
257 | |||
258 | /** |
||
259 | * The default implementation of this method returns [[attributes()]] indexed by the same attribute names. |
||
260 | * |
||
261 | * @return array the list of field names or field definitions. |
||
262 | * |
||
263 | * @see toArray() |
||
264 | */ |
||
265 | public function fields() |
||
266 | { |
||
267 | $fields = $this->keys(); |
||
268 | |||
269 | return array_combine($fields, $fields); |
||
270 | } |
||
271 | |||
272 | /** |
||
273 | * Returns number of items in the collection. |
||
274 | * |
||
275 | * @return int |
||
276 | */ |
||
277 | public function count() |
||
281 | /** |
||
282 | * Returns the element at the specified offset. |
||
283 | * This method is required by the SPL interface `ArrayAccess`. |
||
284 | * It is implicitly called when you use something like `$value = $collection[$offset];`. |
||
285 | * |
||
286 | * @param mixed $offset the offset to retrieve element. |
||
287 | * |
||
288 | * @return mixed the element at the offset, null if no element is found at the offset |
||
289 | */ |
||
290 | public function offsetGet($offset) |
||
294 | |||
295 | /** |
||
296 | * Sets the element at the specified offset. |
||
297 | * This method is required by the SPL interface `ArrayAccess`. |
||
298 | * It is implicitly called when you use something like `$collection[$offset] = $value;`. |
||
299 | * |
||
300 | * @param int $offset the offset to set element |
||
301 | * @param mixed $value the element value |
||
302 | */ |
||
303 | public function offsetSet($offset, $value) |
||
307 | |||
308 | /** |
||
309 | * Returns whether there is an element at the specified offset. |
||
310 | * This method is required by the SPL interface `ArrayAccess`. |
||
311 | * It is implicitly called when you use something like `isset($collection[$offset])`. |
||
312 | * |
||
313 | * @param mixed $offset the offset to check on |
||
314 | * |
||
315 | * @return bool |
||
316 | */ |
||
317 | public function offsetExists($offset) |
||
321 | |||
322 | /** |
||
323 | * Sets the element value at the specified offset to null. |
||
324 | * This method is required by the SPL interface ArrayAccess. |
||
325 | * It is implicitly called when you use something like `unset($collection[$offset])`. |
||
326 | * |
||
327 | * @param mixed $offset the offset to unset element |
||
328 | */ |
||
329 | public function offsetUnset($offset) |
||
333 | |||
334 | /** |
||
335 | * Method for IteratorAggregate interface. |
||
336 | * Enables foreach'ing the object. |
||
337 | * |
||
338 | * @return ArrayIterator |
||
339 | */ |
||
340 | public function getIterator() |
||
344 | } |
||
345 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.