Complex classes like Relational 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 Relational, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | class Relational extends Base |
||
9 | { |
||
10 | protected $parent; |
||
11 | protected $manufacturer; |
||
12 | protected $options; |
||
13 | protected $uoms; |
||
14 | protected $images; |
||
15 | protected $specs; |
||
16 | protected $documents; |
||
17 | protected $features; |
||
18 | protected $builders; |
||
19 | |||
20 | public function getKey() |
||
24 | |||
25 | public function getRecursivePrice($retailPrice = false) |
||
26 | { |
||
27 | $price = $this->getPrice($retailPrice); |
||
28 | |||
29 | $adjustmentPrice = 0; |
||
30 | if ($this->has('options')) { |
||
31 | foreach ($this->getOptions() as $option) { |
||
32 | $adjustmentPrice += $option->getRecursivePrice($price, $retailPrice); |
||
33 | } |
||
34 | } |
||
35 | |||
36 | return $price + $adjustmentPrice; |
||
37 | } |
||
38 | |||
39 | public function type($type = null) |
||
40 | { |
||
41 | if ($type === 'shell') { |
||
42 | $product->setProductTypeId(1); |
||
|
|||
43 | } elseif ($type === 'product') { |
||
44 | $product->setProductTypeId(2); |
||
45 | } |
||
46 | switch ($this->getProductTypeId()) { |
||
47 | case 1: |
||
48 | return 'shell'; |
||
49 | break; |
||
50 | case 2: |
||
51 | return 'product'; |
||
52 | break; |
||
53 | } |
||
54 | } |
||
55 | |||
56 | |||
57 | public function getPrice($retailPrice = false) |
||
58 | { |
||
59 | if ($this->has('uoms')) { |
||
60 | $uomPrices = array(); |
||
61 | foreach ($this->getUoms() as $uom) { |
||
62 | $uomPrices[] = $retailPrice ? $uom->getRetail() : $uom->getPrice(); |
||
63 | } |
||
64 | asort($uomPrices, SORT_NUMERIC); |
||
65 | return array_shift($uomPrices); |
||
66 | } elseif ($this->has('builders')) { |
||
67 | $uomPrices = array(); |
||
68 | foreach ($this->getBuilders() as $builder) { |
||
69 | foreach ($builder->getProduct()->getUoms() as $uom) { |
||
70 | $uomPrices[] = $retailPrice ? $uom->getRetail() : $uom->getPrice(); |
||
71 | } |
||
72 | } |
||
73 | asort($uomPrices, SORT_NUMERIC); |
||
74 | return array_shift($uomPrices); |
||
75 | } |
||
76 | return 0; |
||
77 | } |
||
78 | |||
79 | public function getImage() |
||
80 | { |
||
81 | if (isset($this->images[0])) { |
||
82 | return $this->images[0]; |
||
83 | } |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * @return uoms |
||
88 | */ |
||
89 | public function getUoms() |
||
93 | |||
94 | public function addUom($uom) |
||
95 | { |
||
96 | $uom->setParent($this); |
||
97 | $this->uoms[] = $uom; |
||
98 | return $this; |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * @param $uoms |
||
103 | * @return self |
||
104 | */ |
||
105 | public function setUoms($uoms) |
||
106 | { |
||
107 | $this->uoms = array(); |
||
108 | |||
109 | foreach ($uoms as $uom) { |
||
110 | $this->addUom($uom); |
||
111 | } |
||
112 | |||
113 | return $this; |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * @return images |
||
118 | */ |
||
119 | public function getImages() |
||
123 | |||
124 | public function addImage($image) |
||
125 | { |
||
126 | $image->setParent($this); |
||
127 | $this->images[] = $image; |
||
128 | return $this; |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * @param $images |
||
133 | * @return self |
||
134 | */ |
||
135 | public function setImages($images) |
||
136 | { |
||
137 | $this->images = array(); |
||
138 | |||
139 | foreach ($images as $image) { |
||
140 | $this->addImage($image); |
||
141 | } |
||
142 | |||
143 | return $this; |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * @return specs |
||
148 | */ |
||
149 | public function getSpecs() |
||
153 | |||
154 | public function addSpec($spec) |
||
155 | { |
||
156 | $spec->setParent($this); |
||
157 | $this->specs[] = $spec; |
||
158 | return $this; |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * @param $specs |
||
163 | * @return self |
||
164 | */ |
||
165 | public function setSpecs($specs) |
||
166 | { |
||
167 | $this->specs = array(); |
||
168 | |||
169 | foreach ($specs as $spec) { |
||
170 | $this->addSpec($spec); |
||
171 | } |
||
172 | |||
173 | return $this; |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * @return documents |
||
178 | */ |
||
179 | public function getDocuments() |
||
183 | |||
184 | public function addDocument($document) |
||
185 | { |
||
186 | $document->setParent($this); |
||
187 | $this->documents[] = $document; |
||
188 | return $this; |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * @param $documents |
||
193 | * @return self |
||
194 | */ |
||
195 | public function setDocuments($documents) |
||
196 | { |
||
197 | $this->documents = array(); |
||
198 | |||
199 | foreach ($documents as $document) { |
||
200 | $this->addDocument($document); |
||
201 | } |
||
202 | |||
203 | return $this; |
||
204 | } |
||
205 | |||
206 | /** |
||
207 | * @return features |
||
208 | */ |
||
209 | public function getFeatures() |
||
213 | |||
214 | public function addFeature($feature) |
||
215 | { |
||
216 | $feature->setParent($this); |
||
217 | $this->features[] = $feature; |
||
218 | return $this; |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * @param $features |
||
223 | * @return self |
||
224 | */ |
||
225 | public function setFeatures($features) |
||
226 | { |
||
227 | $this->features = array(); |
||
228 | |||
229 | foreach ($features as $feature) { |
||
230 | $this->addFeature($feature); |
||
231 | } |
||
232 | |||
233 | return $this; |
||
234 | } |
||
235 | |||
236 | /** |
||
237 | * @return options |
||
238 | */ |
||
239 | public function getOptions() |
||
243 | |||
244 | public function addOption($option) |
||
245 | { |
||
246 | $option->setParent($this); |
||
247 | $this->options[] = $option; |
||
248 | return $this; |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * @param $options |
||
253 | * @return self |
||
254 | */ |
||
255 | public function setOptions($options) |
||
256 | { |
||
257 | $this->options = array(); |
||
258 | |||
259 | foreach ($options as $option) { |
||
260 | $this->addOption($option); |
||
261 | } |
||
262 | |||
263 | return $this; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * @return manufacturer |
||
268 | */ |
||
269 | public function getManufacturer() |
||
273 | |||
274 | /** |
||
275 | * @param $manufacturer |
||
276 | * @return self |
||
277 | */ |
||
278 | public function setManufacturer(\SpeckContact\Entity\Company $manufacturer = null) |
||
279 | { |
||
280 | if ($manufacturer) { |
||
281 | $manufacturer->setParent($this); |
||
282 | } |
||
283 | $this->manufacturer = $manufacturer; |
||
284 | return $this; |
||
285 | } |
||
286 | |||
287 | public function __toString() |
||
288 | { |
||
289 | $name = $this->getName(); |
||
290 | $parent = parent::__toString(); |
||
291 | return ($name ?: $parent); |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * @return parent |
||
296 | */ |
||
297 | public function getParent() |
||
301 | |||
302 | /** |
||
303 | * @param $parent |
||
304 | * @return self |
||
305 | */ |
||
306 | public function setParent(AbstractModel $parent) |
||
307 | { |
||
308 | $this->parent = $parent; |
||
309 | return $this; |
||
310 | } |
||
311 | |||
312 | /** |
||
313 | * @return builders |
||
314 | */ |
||
315 | public function getBuilders() |
||
319 | |||
320 | /** |
||
321 | * @param $builders |
||
322 | * @return self |
||
323 | */ |
||
324 | public function setBuilders($builders) |
||
325 | { |
||
326 | $this->builders = $builders; |
||
327 | return $this; |
||
328 | } |
||
329 | } |
||
330 |
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.