Conditions | 1 |
Paths | 1 |
Total Lines | 511 |
Code Lines | 5 |
Lines | 0 |
Ratio | 0 % |
Changes | 3 | ||
Bugs | 0 | Features | 2 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
21 | /** |
||
22 | * Build destination code tree from source code. |
||
23 | * |
||
24 | * @param string $source Source code |
||
25 | * |
||
26 | * @return Node Less tree root node |
||
27 | */ |
||
28 | 1 | public function build($source) |
|
29 | { |
||
30 | // Prepare source code |
||
31 | 1 | $source = $this->prepare($source); |
|
32 | |||
33 | // Build destination node tree |
||
34 | 1 | return $this->analyze($source); |
|
35 | } |
||
36 | |||
37 | /** |
||
38 | * Source code cleaner. |
||
39 | * |
||
40 | * @param string $source |
||
41 | * |
||
42 | * @return string Cleared source code |
||
43 | */ |
||
44 | 1 | protected function prepare($source) |
|
45 | { |
||
46 | // Remove all PHP code from view |
||
47 | 1 | return trim(preg_replace('/<\?(php|=).*?\?>/', '', $source)); |
|
48 | } |
||
49 | |||
50 | /** |
||
51 | * Analyze source code and create destination code tree. |
||
52 | * |
||
53 | * @param string $source Source code |
||
54 | * |
||
55 | * @return Node Internal code tree |
||
56 | */ |
||
57 | 1 | protected function &analyze($source) |
|
58 | { |
||
59 | 1 | libxml_use_internal_errors(true); |
|
60 | |||
61 | /** @var \DOMNode Pointer to current dom element */ |
||
62 | 1 | $dom = new \DOMDocument(); |
|
63 | 1 | $dom->loadHTML($source); |
|
64 | |||
65 | // Perform recursive node analysis |
||
66 | 1 | return $this->analyzeSourceNode($dom, new Node('')); |
|
67 | } |
||
68 | |||
69 | /** |
||
70 | * Perform source node analysis. |
||
71 | * |
||
72 | * @param \DOMNode $domNode |
||
73 | * @param Node $parent |
||
74 | * |
||
75 | * @return Node |
||
76 | */ |
||
77 | 1 | protected function &analyzeSourceNode(\DOMNode $domNode, Node $parent) |
|
78 | { |
||
79 | 1 | foreach ($domNode->childNodes as $child) { |
|
80 | 1 | $tag = $child->nodeName; |
|
81 | |||
82 | // Work only with allowed DOMElements |
||
83 | 1 | if ($child->nodeType === 1 && !in_array($tag, static::$ignoredNodes)) { |
|
84 | // Get node classes |
||
85 | 1 | $classes = array_filter(explode(' ', $this->getDOMAttributeValue($child, 'class'))); |
|
86 | |||
87 | // Define less node selector |
||
88 | 1 | $selector = $tag; |
|
89 | 1 | if (($identifier = $this->getDOMAttributeValue($child, 'id')) !== null) { |
|
90 | 1 | $selector = '#' . $identifier; |
|
91 | 1 | } elseif (count($classes)) { |
|
92 | $selector = '.' . array_shift($classes); |
||
93 | 1 | } elseif (($name = $this->getDOMAttributeValue($child, 'name')) !== null) { |
|
94 | $selector = $tag . '[name=' . $name . ']'; |
||
95 | } |
||
96 | |||
97 | // Find child node by selector |
||
98 | 1 | $node = $parent->getChild($selector); |
|
99 | |||
100 | // Check if we have created this selector LessNode for this branch |
||
101 | 1 | if (null === $node) { |
|
102 | // Create internal node instance |
||
103 | 1 | $node = new Node($selector, $parent); |
|
|
|||
104 | 1 | } |
|
105 | |||
106 | // Create inner class modifiers for parent node |
||
107 | 1 | foreach ($classes as $class) { |
|
108 | 1 | new Node('&.' . $class, $node); |
|
109 | 1 | } |
|
110 | |||
111 | // Go deeper in recursion |
||
112 | 1 | $this->analyzeSourceNode($child, $node); |
|
113 | 1 | } |
|
114 | 1 | } |
|
115 | |||
116 | 1 | return $parent; |
|
117 | } |
||
118 | |||
119 | /** |
||
120 | * Get DOM node attribute value. |
||
121 | * |
||
122 | * @param \DOMNode $domNode |
||
123 | * @param string $attributeName |
||
124 | * |
||
125 | * @return null|string DOM node attribute value |
||
126 | */ |
||
127 | 1 | protected function getDOMAttributeValue(\DOMNode $domNode, $attributeName) |
|
128 | { |
||
129 | 1 | if (null !== $domNode->attributes) { |
|
130 | /**@var \DOMNode $attribute */ |
||
131 | 1 | foreach ($domNode->attributes as $attribute) { |
|
132 | 1 | $value = trim($attribute->nodeValue); |
|
133 | // If DOM attribute matches needed |
||
134 | 1 | if ($attributeName === $attribute->name && $value !== '') { |
|
135 | // Remove white spaces |
||
136 | 1 | return $value; |
|
137 | } |
||
138 | 1 | } |
|
139 | 1 | } |
|
140 | |||
141 | 1 | return null; |
|
142 | } |
||
143 | |||
144 | /** |
||
145 | * @param Node $node |
||
146 | * @param string $output |
||
147 | * @param int $level |
||
148 | * |
||
149 | * @return string |
||
150 | */ |
||
151 | 1 | public function output(Node $node, &$output = '', $level = 0) |
|
152 | { |
||
153 | 1 | $hasSelector = isset($node->selector{0}); |
|
154 | 1 | View Code Duplication | if ($hasSelector) { |
155 | // Generate tabs array |
||
156 | 1 | $output .= implode('', array_fill(0, $level, ' ')) . $node . ' {' . "\n"; |
|
157 | 1 | } |
|
158 | |||
159 | 1 | foreach ($node->children as $child) { |
|
160 | 1 | $this->output($child, $output, $level + 1); |
|
161 | 1 | } |
|
162 | |||
163 | 1 | View Code Duplication | if ($hasSelector) { |
164 | 1 | $output .= implode('', array_fill(0, $level, ' ')) . '}' . "\n"; |
|
165 | 1 | } |
|
166 | |||
167 | 1 | return $output; |
|
168 | } |
||
169 | } |
||
170 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: