We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.
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 DOM 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 DOM, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 35 | abstract class DOM { |
||
| 36 | |||
| 37 | /** |
||
| 38 | * An array of block tag names. |
||
| 39 | * |
||
| 40 | * @var array |
||
| 41 | */ |
||
| 42 | private static $block_tags; |
||
| 43 | |||
| 44 | /** |
||
| 45 | * Retrieves an array of block tag names. |
||
| 46 | * |
||
| 47 | * @param bool $reset Optional. Default false. |
||
| 48 | * |
||
| 49 | * @return array |
||
| 50 | */ |
||
| 51 | public static function block_tags( $reset = false ) { |
||
| 63 | |||
| 64 | |||
| 65 | /** |
||
| 66 | * Converts \DOMNodeList to array; |
||
| 67 | * |
||
| 68 | * @param \DOMNodeList $list Required. |
||
| 69 | * |
||
| 70 | * @return array An associative array in the form ( $spl_object_hash => $node ). |
||
| 71 | */ |
||
| 72 | public static function nodelist_to_array( \DOMNodeList $list ) { |
||
| 81 | |||
| 82 | /** |
||
| 83 | * Retrieves an array containing all the ancestors of the node. This could be done |
||
| 84 | * via an XPath query for "ancestor::*", but DOM walking is in all likelyhood faster. |
||
| 85 | * |
||
| 86 | * @param \DOMNode $node Required. |
||
| 87 | * |
||
| 88 | * @return array An array of \DOMNode. |
||
| 89 | */ |
||
| 90 | public static function get_ancestors( \DOMNode $node ) { |
||
| 99 | |||
| 100 | /** |
||
| 101 | * Checks whether the \DOMNode has one of the given classes. |
||
| 102 | * If $tag is a \DOMText, the parent DOMElement is checked instead. |
||
| 103 | * |
||
| 104 | * @param \DOMNode $tag An element or textnode. |
||
| 105 | * @param string|array $classnames A single classname or an array of classnames. |
||
| 106 | * |
||
| 107 | * @return boolean True if the element has any of the given class(es). |
||
| 108 | */ |
||
| 109 | public static function has_class( \DOMNode $tag, $classnames ) { |
||
| 136 | |||
| 137 | /** |
||
| 138 | * Retrieves the last character of the previous \DOMText sibling (if there is one). |
||
| 139 | * |
||
| 140 | * @param \DOMNode $node The content node. |
||
| 141 | * |
||
| 142 | * @return string A single character (or the empty string). |
||
| 143 | */ |
||
| 144 | public static function get_prev_chr( \DOMNode $node ) { |
||
| 147 | |||
| 148 | /** |
||
| 149 | * Retrieves the first character of the next \DOMText sibling (if there is one). |
||
| 150 | * |
||
| 151 | * @param \DOMNode $node The content node. |
||
| 152 | * |
||
| 153 | * @return string A single character (or the empty string). |
||
| 154 | */ |
||
| 155 | public static function get_next_chr( \DOMNode $node ) { |
||
| 158 | |||
| 159 | /** |
||
| 160 | * Retrieves a character from the given \DOMNode. |
||
| 161 | * |
||
| 162 | * @since 5.0.0 |
||
| 163 | * |
||
| 164 | * @param \DOMNode $node Required. |
||
| 165 | * @param int $position The position parameter for `substr`. |
||
| 166 | * @param int $length The length parameter for `substr`. |
||
| 167 | * @param callable $get_textnode A function to retrieve the \DOMText from the node. |
||
| 168 | * |
||
| 169 | * @return string The character or an empty string. |
||
| 170 | */ |
||
| 171 | private static function get_adjacent_chr( \DOMNode $node, $position, $length, callable $get_textnode ) { |
||
| 185 | |||
| 186 | /** |
||
| 187 | * Retrieves the previous \DOMText sibling (if there is one). |
||
| 188 | * |
||
| 189 | * @param \DOMNode|null $node Optional. The content node. Default null. |
||
| 190 | * |
||
| 191 | * @return \DOMText|null Null if $node is a block-level element or no text sibling exists. |
||
| 192 | */ |
||
| 193 | public static function get_previous_textnode( \DOMNode $node = null ) { |
||
| 199 | |||
| 200 | /** |
||
| 201 | * Retrieves the next \DOMText sibling (if there is one). |
||
| 202 | * |
||
| 203 | * @param \DOMNode|null $node Optional. The content node. Default null. |
||
| 204 | * |
||
| 205 | * @return \DOMText|null Null if $node is a block-level element or no text sibling exists. |
||
| 206 | */ |
||
| 207 | public static function get_next_textnode( \DOMNode $node = null ) { |
||
| 213 | |||
| 214 | /** |
||
| 215 | * Retrieves an adjacent \DOMText sibling if there is one. |
||
| 216 | * |
||
| 217 | * @since 5.0.0 |
||
| 218 | * |
||
| 219 | * @param callable $iterate Takes a reference \DOMElement and returns a \DOMText (or null). |
||
| 220 | * @param callable $get_adjacent_parent Takes a single \DOMElement parameter and returns a \DOMText (or null). |
||
| 221 | * @param \DOMNode|null $node Optional. The content node. Default null. |
||
| 222 | * |
||
| 223 | * @return \DOMText|null Null if $node is a block-level element or no text sibling exists. |
||
| 224 | */ |
||
| 225 | private static function get_adjacent_textnode( callable $iterate, callable $get_adjacent_parent, \DOMNode $node = null ) { |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Retrieves the first \DOMText child of the element. Block-level child elements are ignored. |
||
| 255 | * |
||
| 256 | * @param \DOMNode|null $node Optional. Default null. |
||
| 257 | * @param bool $recursive Should be set to true on recursive calls. Optional. Default false. |
||
| 258 | * |
||
| 259 | * @return \DOMText|null The first child of type \DOMText, the element itself if it is of type \DOMText or null. |
||
| 260 | */ |
||
| 261 | View Code Duplication | public static function get_first_textnode( \DOMNode $node = null, $recursive = false ) { |
|
| 271 | |||
| 272 | /** |
||
| 273 | * Retrieves the last \DOMText child of the element. Block-level child elements are ignored. |
||
| 274 | * |
||
| 275 | * @param \DOMNode|null $node Optional. Default null. |
||
| 276 | * @param bool $recursive Should be set to true on recursive calls. Optional. Default false. |
||
| 277 | * |
||
| 278 | * @return \DOMText|null The last child of type \DOMText, the element itself if it is of type \DOMText or null. |
||
| 279 | */ |
||
| 280 | View Code Duplication | public static function get_last_textnode( \DOMNode $node = null, $recursive = false ) { |
|
| 290 | |||
| 291 | /** |
||
| 292 | * Retrieves an edge \DOMText child of the element specified by the callable. |
||
| 293 | * Block-level child elements are ignored. |
||
| 294 | * |
||
| 295 | * @since 5.0.0 |
||
| 296 | * |
||
| 297 | * @param callable $iteration Takes two parameters, a \DOMNodeList and |
||
| 298 | * a reference to the \DOMText used as the result. |
||
| 299 | * @param \DOMNode|null $node Optional. Default null. |
||
| 300 | * @param bool $recursive Should be set to true on recursive calls. Optional. Default false. |
||
| 301 | * |
||
| 302 | * @return \DOMText|null The last child of type \DOMText, the element itself if it is of type \DOMText or null. |
||
| 303 | */ |
||
| 304 | private static function get_edge_textnode( callable $iteration, \DOMNode $node = null, $recursive = false ) { |
||
| 326 | |||
| 327 | /** |
||
| 328 | * Returns the nearest block-level parent (or null). |
||
| 329 | * |
||
| 330 | * @param \DOMNode $node Required. |
||
| 331 | * |
||
| 332 | * @return \DOMElement|null |
||
| 333 | */ |
||
| 334 | public static function get_block_parent( \DOMNode $node ) { |
||
| 351 | |||
| 352 | /** |
||
| 353 | * Retrieves the tag name of the nearest block-level parent. |
||
| 354 | * |
||
| 355 | * @param \DOMNode $node A node. |
||
| 356 | |||
| 357 | * @return string The tag name (or the empty string). |
||
| 358 | */ |
||
| 359 | public static function get_block_parent_name( \DOMNode $node ) { |
||
| 368 | } |
||
| 369 | |||
| 374 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.