Completed
Push — master ( 7d6b1f...14b45d )
by smiley
05:36
created

ManipulationTrait::insert()   D

Complexity

Conditions 10
Paths 4

Size

Total Lines 31
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 10

Importance

Changes 0
Metric Value
dl 0
loc 31
ccs 12
cts 12
cp 1
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 13
nc 4
nop 1
crap 10

How to fix   Complexity   

Long Method

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:

1
<?php
2
/**
3
 * Trait ManipulationTrait
4
 *
5
 * @filesource   ManipulationTrait.php
6
 * @created      08.05.2017
7
 * @package      chillerlan\PrototypeDOM
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\PrototypeDOM;
14
15
use DOMNode;
16
17
/**
18
 * @extends \DOMNode
19
 */
20
trait ManipulationTrait{
21
22
	/**
23
	 * @link http://php.net/manual/class.domnode.php#domnode.props.ownerdocument
24
	 *
25
	 * @var \chillerlan\PrototypeDOM\Document
26
	 */
27
	public $ownerDocument;
28
29
	/**
30
	 * @var \chillerlan\PrototypeDOM\Element
31
	 */
32
	public $parentNode;
33
34
	/**
35
	 * @var \chillerlan\PrototypeDOM\Element
36
	 */
37
	public $firstChild;
38
39
	/**
40
	 * @var \chillerlan\PrototypeDOM\Element
41
	 */
42
	public $nextSibling;
43
44
	/**
45
	 * @return \DOMNode
46
	 */
47 5
	public function remove():DOMNode{
48
49 5
		if(!$this->parentNode){
50
			/** @var \DOMNode $this */
51 1
			return $this;
52
		}
53
54
		/** @var \DOMNode $this */
55 5
		return $this->parentNode->removeChild($this);
56
	}
57
58
	/**
59
	 * @param \DOMNode $newnode
60
	 *
61
	 * @return \DOMNode
62
	 */
63 2
	public function replace(DOMNode $newnode):DOMNode{
64
65 2
		if(!$this->parentNode){
66
			/** @var \DOMNode $this */
67 1
			return $this;
68
		}
69
70
		/** @var \DOMNode $this */
71 2
		return $this->parentNode->replaceChild($this->_importNode($newnode), $this);
72
	}
73
74
	/**
75
	 * @param \DOMNode $wrapper
76
	 *
77
	 * @return \chillerlan\PrototypeDOM\Element
78
	 */
79 1
	public function wrap(DOMNode $wrapper):Element{
80
		/** @var \chillerlan\PrototypeDOM\Element $wrapper */
81 1
		return $wrapper->insert($this->replace($wrapper));
82
	}
83
84
	/**
85
	 * @return \DOMNode
86
	 */
87 6
	public function empty():DOMNode{
88
89 6
		while($this->hasChildNodes()){
0 ignored issues
show
Bug introduced by
It seems like hasChildNodes() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
90 2
			$this->firstChild->remove();
91
		}
92
93
		/** @var \DOMNode $this */
94 6
		return $this;
95
	}
96
97
	/**
98
	 * @param string|\DOMNode|\DOMNodeList $content
99
	 *
100
	 * @return \DOMNode
101
	 */
102 5
	public function update($content):DOMNode{
103 5
		$this->empty();
104 5
		$this->insert($content);
105
106
		/** @var \DOMNode $this */
107 5
		return $this;
108
	}
109
110
	/**
111
	 * @return \DOMNode
112
	 */
113 1
	public function cleanWhitespace():DOMNode{
114 1
		$node = $this->firstChild;
115
116 1
		while($node){
117 1
			$nextNode = $node->nextSibling;
118
119 1
			if($node->nodeType === XML_TEXT_NODE && empty(trim($node->nodeValue))){
120 1
				$node->remove();
121
			}
122
123 1
			$node = $nextNode;
124
		}
125
126
		/** @var \DOMNode $this */
127 1
		return $this;
128
	}
129
130
	/**
131
	 * @param \DOMNode $newNode
132
	 *
133
	 * @return \DOMNode
134
	 */
135 5
	public function _importNode(DOMNode $newNode):DOMNode{
136 5
		return $this->ownerDocument->importNode($newNode, true);
137
	}
138
139
	/**
140
	 * Accepted insertion points are:
141
	 * - before (as element's previous sibling)
142
	 * - after (as element's next sibling)
143
	 * - top (as element's first child)
144
	 * - bottom (as element's last child)
145
	 *
146
	 * @param string|array|\DOMNode|\DOMNodeList $content
147
	 *
148
	 * @return \DOMNode
149
	 */
150 5
	public function insert($content):DOMNode{
151
152 5
		if(is_array($content)){
153
154 1
			foreach(['before', 'after', 'top', 'bottom'] as $pos){
155
156 1
				if(array_key_exists($pos, $content)){
157 1
					$nodes = $this->ownerDocument->_toNodeList($content[$pos]);
158
159 1
					if($pos === 'top' && $this->hasChildNodes() || $pos === 'after' && $this->nextSibling){
0 ignored issues
show
Bug introduced by
It seems like hasChildNodes() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
160 1
						$nodes->reverse();
161
					}
162
163 1
					foreach($nodes as $node){
164 1
						call_user_func_array([$this, 'insert_'.$pos], [$node]);
165
					}
166
167
				}
168
169
			}
170
171
		}
172
		else{
173 5
			foreach($this->ownerDocument->_toNodeList($content) as $node){
174 5
				$this->insert_bottom($node);
175
			}
176
		}
177
178
		/** @var \DOMNode $this */
179 5
		return $this;
180
	}
181
182
	/**
183
	 * @param \DOMNode      $node
184
	 * @param \DOMNode|null $refNode
185
	 *
186
	 * @return \DOMNode
187
	 */
188 1
	public function insert_before(DOMNode $node, DOMNode $refNode = null):DOMNode{
189
190 1
		if($this->parentNode){
191 1
			$this->parentNode->insertBefore($this->_importNode($node), $refNode ?? $this);
192
		}
193
194
		/** @var \DOMNode $this */
195 1
		return $this;
196
	}
197
198
	/**
199
	 * @param \DOMNode $node
200
	 *
201
	 * @return \DOMNode
202
	 */
203 1
	public function insert_after(DOMNode $node):DOMNode{
204 1
		return !$this->nextSibling && $this->parentNode
205 1
			? $this->parentNode->insert_bottom($node)
206 1
			: $this->nextSibling->insert_before($node);
207
	}
208
209
	/**
210
	 * @param \DOMNode $node
211
	 *
212
	 * @return \DOMNode
213
	 */
214 1
	public function insert_top(DOMNode $node):DOMNode{
215 1
		return $this->hasChildNodes()
0 ignored issues
show
Bug introduced by
It seems like hasChildNodes() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
216 1
			? $this->firstChild->insert_before($node, $this->firstChild)
217 1
			: $this->insert_bottom($node);
218
	}
219
220
	/**
221
	 * @param \DOMNode $node
222
	 *
223
	 * @return \DOMNode
224
	 */
225 5
	public function insert_bottom(DOMNode $node):DOMNode{
226 5
		$this->appendChild($this->_importNode($node));
0 ignored issues
show
Bug introduced by
It seems like appendChild() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
227
228
		/** @var \DOMNode $this */
229 5
		return $this;
230
	}
231
232
}
233