Complex classes like Struct 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 Struct, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
19 | class Struct extends AbstractModelFile |
||
20 | { |
||
21 | /** |
||
22 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getClassConstants() |
||
23 | */ |
||
24 | 68 | protected function getClassConstants(ConstantContainer $constants) |
|
27 | /** |
||
28 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getConstantAnnotationBlock() |
||
29 | */ |
||
30 | protected function getConstantAnnotationBlock(PhpConstant $constant) |
||
33 | /** |
||
34 | * @param bool $includeInheritanceAttributes include the attributes of parent class, default parent attributes are not included. If true, then the array is an associative array containing and index "attribute" for the StructAttribute object and an index "model" for the Struct object. |
||
35 | * @param bool $requiredFirst places the required attributes first, then the not required in order to have the _contrust method with the required attribute at first |
||
36 | * @return StructAttributeContainer |
||
37 | */ |
||
38 | 68 | protected function getModelAttributes($includeInheritanceAttributes = false, $requiredFirst = true) |
|
42 | /** |
||
43 | * @param PropertyContainer |
||
44 | */ |
||
45 | 96 | protected function getClassProperties(PropertyContainer $properties) |
|
53 | /** |
||
54 | * @return PhpAnnotationBlock |
||
55 | */ |
||
56 | 68 | protected function getPropertyAnnotationBlock(PhpProperty $property) |
|
69 | /** |
||
70 | * @param MethodContainer |
||
71 | */ |
||
72 | 68 | protected function getClassMethods(MethodContainer $methods) |
|
79 | /** |
||
80 | * @param MethodContainer $methods |
||
81 | * @return Struct |
||
82 | */ |
||
83 | 68 | protected function addStructMethodConstruct(MethodContainer $methods) |
|
90 | /** |
||
91 | * @param PhpMethod $method |
||
92 | * @return Struct |
||
93 | */ |
||
94 | 68 | protected function addStructMethodConstructBody(PhpMethod $method) |
|
105 | /** |
||
106 | * @param PhpMethod $method |
||
107 | * @param StructAttributeModel $attribute |
||
108 | * @param bool $isLast |
||
109 | * @return Struct |
||
110 | */ |
||
111 | 68 | protected function addStructMethodConstructBodyForAttribute(PhpMethod $method, StructAttributeModel $attribute, $isLast) |
|
116 | /** |
||
117 | * @return PhpFunctionParameter[] |
||
118 | */ |
||
119 | 68 | protected function getStructMethodParametersValues() |
|
127 | /** |
||
128 | * @param StructAttributeModel $attribute |
||
129 | * @param bool $lowCaseFirstLetter |
||
130 | * @param mixed $defaultValue |
||
131 | * @return PhpFunctionParameter |
||
132 | */ |
||
133 | 68 | protected function getStructMethodParameter(StructAttributeModel $attribute, $lowCaseFirstLetter = false, $defaultValue = null) |
|
141 | /** |
||
142 | * @param StructAttributeModel $attribute |
||
143 | * @param bool $returnArrayType |
||
144 | * @return string|null |
||
145 | 48 | */ |
|
146 | protected function getStructMethodParameterType(StructAttributeModel $attribute, $returnArrayType = true) |
||
147 | 48 | { |
|
148 | return self::getValidType($this->getStructAttributeTypeHint($attribute, $returnArrayType), null); |
||
149 | } |
||
150 | /** |
||
151 | * @param MethodContainer $methods |
||
152 | * @return Struct |
||
153 | 68 | */ |
|
154 | protected function addStructMethodsSetAndGet(MethodContainer $methods) |
||
155 | 68 | { |
|
156 | 51 | foreach ($this->getModelAttributes() as $attribute) { |
|
157 | 68 | $this |
|
158 | 68 | ->addStructMethodGet($methods, $attribute) |
|
159 | 51 | ->addStructMethodSet($methods, $attribute) |
|
160 | 68 | ->addStructMethodAddTo($methods, $attribute); |
|
161 | } |
||
162 | return $this; |
||
163 | } |
||
164 | /** |
||
165 | * @param MethodContainer $methods |
||
166 | * @param StructAttributeModel $attribute |
||
167 | 48 | * @return Struct |
|
168 | */ |
||
169 | 48 | protected function addStructMethodAddTo(MethodContainer $methods, StructAttributeModel $attribute) |
|
170 | 48 | { |
|
171 | 36 | if ($attribute->isArray()) { |
|
172 | 48 | $method = new PhpMethod(sprintf('addTo%s', ucfirst($attribute->getCleanName())), array( |
|
173 | 48 | new PhpFunctionParameter('item', PhpFunctionParameter::NO_VALUE, $this->getStructMethodParameterType($attribute, false)), |
|
174 | 48 | )); |
|
175 | $this->addStructMethodAddToBody($method, $attribute); |
||
176 | $methods->add($method); |
||
177 | } |
||
178 | return $this; |
||
179 | } |
||
180 | /** |
||
181 | 68 | * @param PhpMethod $method |
|
182 | * @param StructAttributeModel $attribute |
||
183 | 51 | * @return Struct |
|
184 | 68 | */ |
|
185 | 68 | protected function addStructMethodAddToBody(PhpMethod $method, StructAttributeModel $attribute) |
|
186 | 68 | { |
|
187 | if ($this->getRestrictionFromStructAttribute($attribute) instanceof StructModel) { |
||
188 | $this->addStructMethodSetBodyForRestriction($method, $attribute, 'item'); |
||
189 | } else { |
||
190 | $this->addStructMethodSetBodyForAnyType($method, $attribute); |
||
191 | } |
||
192 | $method |
||
193 | 68 | ->addChild(sprintf('$this->%s[] = $item;', $attribute->getCleanName())) |
|
194 | ->addChild('return $this;'); |
||
195 | 68 | return $this; |
|
196 | 68 | } |
|
197 | /** |
||
198 | * @param PhpMethod $method |
||
199 | * @param StructAttributeModel $attribute |
||
200 | * @return Struct |
||
201 | */ |
||
202 | 68 | protected function addStructMethodSetBodyForAnyType(PhpMethod $method, StructAttributeModel $attribute) |
|
203 | { |
||
204 | 68 | $method |
|
205 | 68 | ->addChild(sprintf('if (!%s) {', $this->getStructMethodSetBodyForArrayItemSanityCheck($attribute))) |
|
206 | ->addChild($method->getIndentedString(sprintf('throw new \InvalidArgumentException(sprintf(\'The %s property can only contain items of %s, "%%s" given\', is_object($item) ? get_class($item) : gettype($item)), __LINE__);', $attribute->getCleanName(), $this->getStructAttributeType($attribute, true)), 1)) |
||
207 | ->addChild('}'); |
||
208 | return $this; |
||
209 | } |
||
210 | /** |
||
211 | * @param MethodContainer $methods |
||
212 | 48 | * @param StructAttributeModel $attribute |
|
213 | * @return Struct |
||
214 | 48 | */ |
|
215 | 32 | protected function addStructMethodSet(MethodContainer $methods, StructAttributeModel $attribute) |
|
216 | { |
||
217 | 32 | $method = new PhpMethod($attribute->getSetterName(), array( |
|
218 | 32 | $this->getStructMethodParameter($attribute, true, null), |
|
219 | 32 | )); |
|
220 | 24 | $this->addStructMethodSetBody($method, $attribute); |
|
221 | 48 | $methods->add($method); |
|
222 | return $this; |
||
223 | } |
||
224 | /** |
||
225 | * @param PhpMethod $method |
||
226 | * @param StructAttributeModel $attribute |
||
227 | 68 | * @return Struct |
|
228 | */ |
||
229 | 68 | protected function addStructMethodSetBody(PhpMethod $method, StructAttributeModel $attribute) |
|
230 | 68 | { |
|
231 | 51 | if ($attribute->isArray()) { |
|
232 | $this->addStructMethodSetBodyForArray($method, $attribute); |
||
233 | } else { |
||
234 | 68 | $this->addStructMethodSetBodyForRestriction($method, $attribute); |
|
235 | } |
||
236 | return $this |
||
237 | ->addStructMethodSetBodyAssignment($method, $attribute) |
||
238 | ->addStructMethodSetBodyReturn($method); |
||
239 | } |
||
240 | /** |
||
241 | * @param PhpMethod $method |
||
242 | 68 | * @param StructAttributeModel $attribute |
|
243 | * @return Struct |
||
244 | 51 | */ |
|
245 | 68 | protected function addStructMethodSetBodyAssignment(PhpMethod $method, StructAttributeModel $attribute) |
|
246 | 68 | { |
|
247 | $method->addChild($this->getStructMethodSetBodyAssignment($attribute)); |
||
248 | return $this; |
||
249 | } |
||
250 | /** |
||
251 | * @param PhpMethod $method |
||
252 | * @return Struct |
||
253 | */ |
||
254 | 68 | protected function addStructMethodSetBodyReturn(PhpMethod $method) |
|
259 | 4 | /** |
|
260 | 4 | * @param PhpMethod $method |
|
261 | 4 | * @param StructAttributeModel $attribute |
|
262 | 4 | * @param string $parameterName |
|
263 | 4 | * @return Struct |
|
264 | 4 | */ |
|
265 | 4 | protected function addStructMethodSetBodyForRestriction(PhpMethod $method, StructAttributeModel $attribute, $parameterName = null) |
|
266 | 3 | { |
|
267 | 68 | if (($model = $this->getRestrictionFromStructAttribute($attribute)) instanceof StructModel) { |
|
268 | $parameterName = empty($parameterName) ? lcfirst($attribute->getCleanName()) : $parameterName; |
||
269 | $method |
||
270 | ->addChild(sprintf('if (!%s::%s($%s)) {', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID, $parameterName)) |
||
271 | ->addChild($method->getIndentedString(sprintf('throw new \InvalidArgumentException(sprintf(\'Value "%%s" is invalid, please use one of: %%s\', $%s, implode(\', \', %s::%s())), __LINE__);', $parameterName, $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES), 1)) |
||
272 | ->addChild('}'); |
||
273 | } |
||
274 | return $this; |
||
275 | 68 | } |
|
276 | /** |
||
277 | 68 | * @param PhpMethod $method |
|
278 | 68 | * @param StructAttributeModel $attribute |
|
279 | 4 | * @return Struct |
|
280 | 3 | */ |
|
281 | 68 | protected function addStructMethodSetBodyForArray(PhpMethod $method, StructAttributeModel $attribute) |
|
282 | 68 | { |
|
283 | if ($attribute->isArray()) { |
||
284 | $model = $this->getRestrictionFromStructAttribute($attribute); |
||
285 | $parameterName = lcfirst($attribute->getCleanName()); |
||
286 | if ($model instanceof StructModel) { |
||
287 | $method |
||
288 | ->addChild('$invalidValues = array();') |
||
289 | 68 | ->addChild(sprintf('foreach($%s as $item) {', $parameterName)) |
|
290 | ->addChild($method->getIndentedString(sprintf('if (!%s::%s($item)) {', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID), 1)) |
||
291 | 68 | ->addChild($method->getIndentedString('$invalidValues[] = var_export($item);', 2)) |
|
292 | 68 | ->addChild($method->getIndentedString('}', 1)) |
|
293 | 68 | ->addChild('}') |
|
294 | 51 | ->addChild('if (!empty($invalidValues)) {') |
|
295 | ->addChild($method->getIndentedString(sprintf('throw new \InvalidArgumentException(sprintf(\'Value(s) "%%s" is/are invalid, please use one of: %%s\', implode(\', \', $invalidValues), implode(\', \', %s::%s())), __LINE__);', $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES), 1)) |
||
296 | ->addChild('}'); |
||
297 | 68 | } else { |
|
298 | 68 | $method |
|
299 | 68 | ->addChild(sprintf('foreach($%s as $item) {', $parameterName)) |
|
300 | ->addChild($method->getIndentedString(sprintf('if (!%s) {', $this->getStructMethodSetBodyForArrayItemSanityCheck($attribute)), 1)) |
||
301 | ->addChild($method->getIndentedString(sprintf('throw new \InvalidArgumentException(sprintf(\'The %s property can only contain items of %s, "%%s" given\', is_object($item) ? get_class($item) : gettype($item)), __LINE__);', $attribute->getCleanName(), $this->getStructAttributeType($attribute, true)), 2)) |
||
302 | ->addChild($method->getIndentedString('}', 1)) |
||
303 | ->addChild('}'); |
||
304 | } |
||
305 | 68 | } |
|
306 | return $this; |
||
307 | 68 | } |
|
308 | 68 | /** |
|
309 | 4 | * The second case which used PHP native functions is volontary limited by the native functions provided by PHP, |
|
310 | 3 | * and the possible types defined in xsd_types.yml |
|
311 | 68 | * @param StructAttributeModel $attribute |
|
312 | */ |
||
313 | protected function getStructMethodSetBodyForArrayItemSanityCheck(StructAttributeModel $attribute) |
||
314 | { |
||
315 | $model = $this->getModelFromStructAttribute($attribute); |
||
316 | $sanityCheck = 'false'; |
||
317 | 68 | if ($model instanceof StructModel) { |
|
318 | $sanityCheck = sprintf('$item instanceof %s', $this->getStructAttributeType($attribute, true)); |
||
319 | 68 | } else { |
|
320 | 68 | switch (self::getPhpType($attribute->getType())) { |
|
321 | 68 | case 'int': |
|
322 | 68 | $sanityCheck = 'is_int($item)'; |
|
323 | 68 | break; |
|
324 | 68 | case 'bool': |
|
325 | $sanityCheck = 'is_bool($item)'; |
||
326 | break; |
||
327 | case 'float': |
||
328 | $sanityCheck = 'is_float($item)'; |
||
329 | 68 | break; |
|
330 | case 'string': |
||
331 | 68 | $sanityCheck = 'is_string($item)'; |
|
332 | break; |
||
333 | } |
||
334 | } |
||
335 | return $sanityCheck; |
||
336 | } |
||
337 | 68 | /** |
|
338 | * @param StructAttributeModel $attribute |
||
339 | 68 | * @return string |
|
340 | 68 | */ |
|
341 | 68 | protected function getStructMethodSetBodyAssignment(StructAttributeModel $attribute) |
|
342 | 48 | { |
|
343 | 48 | if ($attribute->nameIsClean()) { |
|
344 | 68 | $assignment = sprintf('$this->%s = $%s;', $attribute->getName(), lcfirst($attribute->getCleanName())); |
|
345 | 48 | } else { |
|
346 | 48 | $assignment = sprintf('$this->%s = $this->{\'%s\'} = $%s;', $attribute->getCleanName(), addslashes($attribute->getName()), lcfirst($attribute->getCleanName())); |
|
347 | 68 | } |
|
348 | 68 | return $assignment; |
|
349 | 68 | } |
|
350 | 68 | /** |
|
351 | 51 | * @param PhpMethod $method |
|
352 | 68 | * @param StructAttributeModel $attribute |
|
353 | * @param string $thisAccess |
||
354 | * @return Struct |
||
355 | */ |
||
356 | protected function addStructMethodGetBody(PhpMethod $method, StructAttributeModel $attribute, $thisAccess) |
||
362 | 68 | /** |
|
363 | 68 | * @param PhpMethod $method |
|
364 | * @param StructAttributeModel $attribute |
||
365 | * @param string $thisAccess |
||
366 | * @return Struct |
||
367 | */ |
||
368 | 68 | protected function addStructMethodGetBodyForXml(PhpMethod $method, StructAttributeModel $attribute, $thisAccess) |
|
369 | { |
||
370 | 68 | if ($attribute->isXml()) { |
|
371 | 68 | $method |
|
372 | 68 | ->addChild(sprintf('if (!empty($this->%1$s) && !($this->%1$s instanceof \DOMDocument)) {', $thisAccess)) |
|
373 | 68 | ->addChild($method->getIndentedString('$dom = new \DOMDocument(\'1.0\', \'UTF-8\');', 1)) |
|
374 | 68 | ->addChild($method->getIndentedString('$dom->formatOutput = true;', 1)) |
|
383 | 68 | /** |
|
384 | * @param PhpMethod $method |
||
385 | 68 | * @param StructAttributeModel $attribute |
|
386 | 68 | * @param string $thisAccess |
|
387 | 68 | * @return Struct |
|
388 | */ |
||
389 | protected function addStructMethodGetBodyReturn(PhpMethod $method, StructAttributeModel $attribute, $thisAccess) |
||
398 | 40 | /** |
|
399 | 40 | * @param MethodContainer $methods |
|
400 | 30 | * @param StructAttributeModel $attribute |
|
401 | 68 | * @return Struct |
|
402 | 68 | */ |
|
403 | 68 | protected function addStructMethodGet(MethodContainer $methods, StructAttributeModel $attribute) |
|
415 | /** |
||
416 | * @param StructAttributeModel $attribute |
||
417 | * @return PhpFunctionParameter[] |
||
418 | 68 | */ |
|
419 | protected function getStructMethodGetParameters(StructAttributeModel $attribute) |
||
427 | 68 | /** |
|
428 | 68 | * @param MethodContainer $methods |
|
429 | 51 | * @return Struct |
|
430 | 68 | */ |
|
431 | 68 | protected function addStructMethodSetState(MethodContainer $methods) |
|
440 | /** |
||
441 | * @return PhpAnnotationBlock|null |
||
442 | 4 | */ |
|
443 | protected function getMethodAnnotationBlock(PhpMethod $method) |
||
447 | /** |
||
448 | 3 | * @param PhpMethod $method |
|
449 | 4 | * @return PhpAnnotationBlock|null |
|
450 | 4 | */ |
|
451 | protected function getStructMethodAnnotationBlock(PhpMethod $method) |
||
471 | /** |
||
472 | 68 | * @return PhpAnnotationBlock |
|
473 | */ |
||
474 | 68 | protected function getStructMethodConstructAnnotationBlock() |
|
482 | /** |
||
483 | 68 | * @return PhpAnnotationBlock |
|
484 | */ |
||
485 | 4 | protected function getStructMethodSetStateAnnotationBlock() |
|
496 | /** |
||
497 | 68 | * @param PhpMethod $method |
|
498 | * @return PhpAnnotationBlock |
||
499 | 51 | */ |
|
500 | 68 | protected function getStructMethodsSetAndGetAnnotationBlock(PhpMethod $method) |
|
529 | 116 | /** |
|
530 | * @param string $setOrGet |
||
531 | 116 | * @param PhpAnnotationBlock $annotationBlock |
|
532 | * @param StructAttributeModel $attribute |
||
533 | * @return Struct |
||
534 | */ |
||
535 | protected function addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute) |
||
556 | /** |
||
557 | * @param string $setOrGet |
||
558 | * @param PhpAnnotationBlock $annotationBlock |
||
559 | * @param string $attributeName |
||
560 | * @return Struct |
||
561 | */ |
||
562 | protected function addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, PhpAnnotationBlock $annotationBlock, $attributeName) |
||
574 | /** |
||
575 | * @param PhpAnnotationBlock $annotationBlock |
||
576 | * @param string $type |
||
577 | * @param string $name |
||
578 | * @return Struct |
||
579 | */ |
||
580 | protected function addStructMethodsSetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $type, $name) |
||
587 | /** |
||
588 | * @param PhpAnnotationBlock $annotationBlock |
||
589 | * @param string $attribute |
||
590 | * @return Struct |
||
591 | */ |
||
592 | protected function addStructMethodsGetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $attribute) |
||
597 | /** |
||
598 | * @param PhpAnnotationBlock $annotationBlock |
||
599 | * @param StructAttributeModel $attribute |
||
600 | */ |
||
601 | protected function addStructMethodsGetAnnotationBlockFromXmlAttribute(PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute) |
||
613 | /** |
||
614 | * @param PhpAnnotationBlock $annotationBlock |
||
615 | * @return Struct |
||
616 | */ |
||
617 | protected function addStructPropertiesToAnnotationBlock(PhpAnnotationBlock $annotationBlock) |
||
623 | /** |
||
624 | * @param PhpAnnotationBlock $annotationBlock |
||
625 | * @return Struct |
||
626 | */ |
||
627 | protected function addStructPropertiesToAnnotationBlockUses(PhpAnnotationBlock $annotationBlock) |
||
634 | /** |
||
635 | * @param PhpAnnotationBlock $annotationBlock |
||
636 | * @return Struct |
||
637 | */ |
||
638 | protected function addStructPropertiesToAnnotationBlockParams(PhpAnnotationBlock $annotationBlock) |
||
645 | /** |
||
646 | * @param PhpMethod $method |
||
647 | * @return PhpAnnotationBlock |
||
648 | */ |
||
649 | protected function getStructMethodsAddToAnnotationBlock(PhpMethod $method) |
||
672 | /** |
||
673 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getModel() |
||
674 | * @return StructModel |
||
675 | */ |
||
676 | public function getModel() |
||
680 | /** |
||
681 | * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel() |
||
682 | * @throws \InvalidaArgumentException |
||
683 | * @param AbstractModel $model |
||
684 | * @return StructArray |
||
685 | */ |
||
686 | public function setModel(AbstractModel $model) |
||
693 | } |
||
694 |