Complex classes like XmlElement 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 XmlElement, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 41 | class XmlElement implements ContainerInterface |
||
| 42 | { |
||
| 43 | use Accessors; |
||
| 44 | |||
| 45 | /** |
||
| 46 | * Settings for tiding up XML output |
||
| 47 | * |
||
| 48 | * @var array |
||
| 49 | */ |
||
| 50 | public static $tidy = [ |
||
| 51 | 'indent' => true, |
||
| 52 | 'input-xml' => true, |
||
| 53 | 'output-xml' => true, |
||
| 54 | 'drop-empty-paras' => false, |
||
| 55 | 'wrap' => 0 |
||
| 56 | ]; |
||
| 57 | |||
| 58 | /** @var string */ |
||
| 59 | private $_localName; |
||
| 60 | /** @var null|string|false */ |
||
| 61 | private $_prefix = null; |
||
| 62 | |||
| 63 | /** @var array */ |
||
| 64 | private $_namespaces = []; |
||
| 65 | /** @var array */ |
||
| 66 | private $_attributes = []; |
||
| 67 | |||
| 68 | /** |
||
| 69 | * @var XmlElement |
||
| 70 | */ |
||
| 71 | private $_parent; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * @var XmlElement[] |
||
| 75 | */ |
||
| 76 | private $_children = []; |
||
| 77 | |||
| 78 | /** |
||
| 79 | * Initializes element with given name and URI |
||
| 80 | * |
||
| 81 | * @param string $name Element name, including prefix if needed |
||
| 82 | * @param string $uri Namespace URI of element |
||
| 83 | */ |
||
| 84 | 20 | protected function init(string $name, string $uri = null) |
|
| 95 | |||
| 96 | /** |
||
| 97 | * XmlElement constructor |
||
| 98 | * |
||
| 99 | * @param string $name Element name, including prefix if needed |
||
| 100 | * @param string $uri Namespace URI of element |
||
| 101 | * @param mixed $content Content of element |
||
| 102 | * @param array $attributes |
||
| 103 | */ |
||
| 104 | 16 | public function __construct(string $name, string $uri = null, $content = null, array $attributes = []) |
|
| 112 | |||
| 113 | /** |
||
| 114 | * Elements named constructor, same for every subclass. |
||
| 115 | * It's used for factory creation. |
||
| 116 | * |
||
| 117 | * @param string $name Element name, including prefix if needed |
||
| 118 | * @param string $uri Namespace URI of element |
||
| 119 | * |
||
| 120 | * @return static |
||
| 121 | */ |
||
| 122 | 4 | public static function plain(string $name, string $uri = null) |
|
| 130 | |||
| 131 | /** |
||
| 132 | * @see $innerXml |
||
| 133 | * @return string |
||
| 134 | */ |
||
| 135 | 2 | public function getInnerXml() |
|
| 147 | |||
| 148 | /** |
||
| 149 | * Returns XML representation of element |
||
| 150 | * |
||
| 151 | * @param bool $clean Result will be cleaned if set to true |
||
| 152 | * |
||
| 153 | * @return string |
||
| 154 | */ |
||
| 155 | 3 | public function xml(bool $clean = true): string |
|
| 176 | |||
| 177 | /** |
||
| 178 | * Looks up prefix associated with given URI |
||
| 179 | * |
||
| 180 | * @param string|null $uri |
||
| 181 | * @return string|false |
||
| 182 | */ |
||
| 183 | 10 | public function lookupPrefix(string $uri = null) |
|
| 187 | |||
| 188 | /** |
||
| 189 | * Looks up URI associated with given prefix |
||
| 190 | * |
||
| 191 | * @param string|null $prefix |
||
| 192 | * @return string|false |
||
| 193 | */ |
||
| 194 | 15 | public function lookupUri(string $prefix = null) |
|
| 198 | |||
| 199 | /** |
||
| 200 | * Returns element's namespaces |
||
| 201 | * |
||
| 202 | * @param bool $parent Include namespaces from parent? |
||
| 203 | * @return array |
||
| 204 | */ |
||
| 205 | 17 | public function getNamespaces($parent = true): array |
|
| 217 | |||
| 218 | /** |
||
| 219 | * Sets XML attribute of element |
||
| 220 | * |
||
| 221 | * @param string $attribute Attribute name, optionally with prefix |
||
| 222 | * @param mixed $value Attribute value |
||
| 223 | * @param string|null $uri XML Namespace URI of attribute, prefix will be automatically looked up |
||
| 224 | */ |
||
| 225 | 4 | public function setAttribute(string $attribute, $value, string $uri = null) |
|
| 236 | |||
| 237 | /** |
||
| 238 | * Returns value of specified attribute. |
||
| 239 | * |
||
| 240 | * @param string $attribute Attribute name, optionally with prefix |
||
| 241 | * @param string|null $uri XML Namespace URI of attribute, prefix will be automatically looked up |
||
| 242 | * @return bool|mixed |
||
| 243 | */ |
||
| 244 | 2 | public function getAttribute(string $attribute, string $uri = null) |
|
| 248 | |||
| 249 | /** |
||
| 250 | * Checks if attribute exists |
||
| 251 | * |
||
| 252 | * @param string $attribute Attribute name, optionally with prefix |
||
| 253 | * @param string|null $uri XML Namespace URI of attribute, prefix will be automatically looked up |
||
| 254 | * |
||
| 255 | * @return bool |
||
| 256 | */ |
||
| 257 | 2 | public function hasAttribute(string $attribute, string $uri = null) |
|
| 261 | |||
| 262 | /** |
||
| 263 | * Returns element's parent |
||
| 264 | * @return XmlElement|null |
||
| 265 | */ |
||
| 266 | 1 | public function getParent() |
|
| 270 | |||
| 271 | /** |
||
| 272 | * Sets element's parent |
||
| 273 | * @param XmlElement $parent |
||
| 274 | */ |
||
| 275 | 9 | protected function setParent(XmlElement $parent) |
|
| 287 | |||
| 288 | /** |
||
| 289 | * Appends child to element |
||
| 290 | * |
||
| 291 | * @param XmlElement|string $element |
||
| 292 | * |
||
| 293 | * @return XmlElement|string Same as $element |
||
| 294 | */ |
||
| 295 | 16 | public function append($element) |
|
| 321 | |||
| 322 | /** |
||
| 323 | * Returns namespace URI associated with element |
||
| 324 | * |
||
| 325 | * @return false|string |
||
| 326 | */ |
||
| 327 | 15 | public function getNamespace() |
|
| 331 | |||
| 332 | /** |
||
| 333 | * Adds namespace to element, and associates it with prefix. |
||
| 334 | * |
||
| 335 | * @param string $uri Namespace URI |
||
| 336 | * @param string|bool|null $prefix Prefix which will be used for namespace, false for using element's prefix |
||
| 337 | * and null for no prefix |
||
| 338 | */ |
||
| 339 | 13 | public function setNamespace(string $uri, $prefix = false) |
|
| 347 | |||
| 348 | 7 | public function getName() |
|
| 352 | |||
| 353 | 5 | public function getChildren() |
|
| 357 | |||
| 358 | 15 | public function getPrefix() |
|
| 362 | |||
| 363 | 10 | public function getLocalName() |
|
| 367 | |||
| 368 | 6 | public function getAttributes() |
|
| 372 | |||
| 373 | /** |
||
| 374 | * Returns one element at specified index (for default the first one). |
||
| 375 | * |
||
| 376 | * @param string $name Requested element tag name |
||
| 377 | * @param string $uri Requested element namespace |
||
| 378 | * @param int $index Index of element to retrieve |
||
| 379 | * |
||
| 380 | * @return XmlElement|false Retrieved element |
||
| 381 | */ |
||
| 382 | 1 | public function element(string $name, string $uri = null, int $index = 0) |
|
| 386 | |||
| 387 | /** |
||
| 388 | * Retrieves array of matching elements |
||
| 389 | * |
||
| 390 | * @param string $name Requested element tag name |
||
| 391 | * @param string|null $uri Requested element namespace |
||
| 392 | * |
||
| 393 | * @return XmlElement[] Found Elements |
||
| 394 | */ |
||
| 395 | 2 | public function elements($name, $uri = null) : array |
|
| 404 | |||
| 405 | /** |
||
| 406 | * Filters element with given predicate |
||
| 407 | * |
||
| 408 | * @param callable|string $predicate Predicate or class name |
||
| 409 | * |
||
| 410 | * @return XmlElement[] |
||
| 411 | */ |
||
| 412 | 2 | public function all($predicate) |
|
| 416 | |||
| 417 | /** |
||
| 418 | * Iterates over matching elements |
||
| 419 | * |
||
| 420 | * @param callable|string $predicate Predicate or class name |
||
| 421 | * |
||
| 422 | * @return XmlElement|false |
||
| 423 | */ |
||
| 424 | 1 | public function get($predicate) |
|
| 435 | |||
| 436 | public function has($predicate) |
||
| 440 | |||
| 441 | /** |
||
| 442 | * @param string|null $query |
||
| 443 | * @return XPathQuery |
||
| 444 | */ |
||
| 445 | 1 | public function query(string $query = null) |
|
| 449 | |||
| 450 | /** |
||
| 451 | * Helper for retrieving all arguments (including namespaces) |
||
| 452 | * |
||
| 453 | * @return array |
||
| 454 | */ |
||
| 455 | 3 | private function attributes(): array |
|
| 467 | |||
| 468 | /** |
||
| 469 | * Prefixes $name with attribute associated with $uri |
||
| 470 | * |
||
| 471 | * @param string $name Name to prefix |
||
| 472 | * @param string $uri Namespace URI |
||
| 473 | * |
||
| 474 | * @return string |
||
| 475 | */ |
||
| 476 | 4 | protected function _prefix(string $name, string $uri = null): string |
|
| 488 | |||
| 489 | 2 | public function __toString() |
|
| 493 | |||
| 494 | /** |
||
| 495 | * Splits name into local-name and prefix |
||
| 496 | * |
||
| 497 | * @param $name |
||
| 498 | * @return array [$name, $prefix] |
||
| 499 | */ |
||
| 500 | 20 | public static function resolve($name) |
|
| 510 | } |
||
| 511 |