AHTMLNode::__destruct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
ccs 4
cts 4
cp 1
crap 1
1
<?php
2
3
namespace Bavix\AdvancedHtmlDom;
4
5
/**
6
 * Class AHTMLNode
7
 *
8
 * @package Bavix\AdvancedHtmlDom
9
 *
10
 * @property-read string $clean_text
11
 */
12
class AHTMLNode extends AdvancedHtmlBase implements \ArrayAccess
13
{
14
15
    /**
16
     * @var
17
     */
18
    private $_path;
19
20
    /**
21
     * AHTMLNode constructor.
22
     *
23
     * @param $node
24
     * @param $doc
25
     */
26 6
    public function __construct($node, $doc)
27
    {
28 6
        $this->node = $node;
29 6
        $this->_path = $node->getNodePath();
30 6
        $this->doc = $doc;
31 6
        $this->is_text = $node->nodeName === '#text';
32 6
    }
33
34
    /**
35
     * @inheritdoc
36
     */
37 4
    public function __destruct()
38
    {
39 4
        $this->_path = null;
40 4
        unset($this->_path);
41 4
        parent::__destruct();
42 4
    }
43
44
    /**
45
     * @param $html
46
     */
47
    public function after($html)
48
    {
49
        $fragment = $this->get_fragment($html);
50
        if ($ref_node = $this->node->nextSibling) {
51
            $this->node->parentNode->insertBefore($fragment, $ref_node);
52
        } else {
53
            $this->node->parentNode->appendChild($fragment);
54
        }
55
    }
56
57
    /**
58
     * @param $html
59
     *
60
     * @return mixed
61
     */
62
    private function get_fragment($html)
63
    {
64
        $dom = $this->doc->dom;
65
        $fragment = $dom->createDocumentFragment() or die('nope');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
66
        $fragment->appendXML($html);
67
68
        return $fragment;
69
    }
70
71
    /**
72
     * @return array
73
     */
74
    public function attributes()
75
    {
76
        $ret = array();
77
        foreach ($this->node->attributes as $attr) {
78
            $ret[$attr->nodeName] = $attr->nodeValue;
79
        }
80
81
        return $ret;
82
    }
83
84
    /**
85
     * @param null $key
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $key is correct as it would always require null to be passed?
Loading history...
86
     * @param int $level
87
     *
88
     * @return array
89
     */
90
    public function flatten($key = null, $level = 1)
91
    {
92
93
        $children = $this->children;
0 ignored issues
show
Bug Best Practice introduced by
The property children does not exist on Bavix\AdvancedHtmlDom\AHTMLNode. Since you implemented __get, consider adding a @property annotation.
Loading history...
94
        $ret = array();
95
        $tag = $this->tag;
0 ignored issues
show
Bug Best Practice introduced by
The property tag does not exist on Bavix\AdvancedHtmlDom\AHTMLNode. Since you implemented __get, consider adding a @property annotation.
Loading history...
96
97
        if ($this->at('./preceding-sibling::' . $this->tag) || $this->at('./following-sibling::' . $this->tag) || ($key = $this->tag . 's')) {
0 ignored issues
show
Bug introduced by
The method at() does not exist on Bavix\AdvancedHtmlDom\AHTMLNode. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
        if ($this->/** @scrutinizer ignore-call */ at('./preceding-sibling::' . $this->tag) || $this->at('./following-sibling::' . $this->tag) || ($key = $this->tag . 's')) {
Loading history...
98
            $count = $this->search('./preceding-sibling::' . $this->tag)->length + 1;
0 ignored issues
show
Bug introduced by
The method search() does not exist on Bavix\AdvancedHtmlDom\AHTMLNode. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

98
            $count = $this->/** @scrutinizer ignore-call */ search('./preceding-sibling::' . $this->tag)->length + 1;
Loading history...
99
            $tag .= '_' . $count;
100
        }
101
102
        if ($children->length == 0) {
0 ignored issues
show
Bug Best Practice introduced by
The property length does not exist on Bavix\AdvancedHtmlDom\AHTMLNodeList. Since you implemented __get, consider adding a @property annotation.
Loading history...
103
            $ret[$this->decamelize(\implode(' ', \array_filter(array($key, $tag))))] = $this->text;
0 ignored issues
show
Bug Best Practice introduced by
The property text does not exist on Bavix\AdvancedHtmlDom\AHTMLNode. Since you implemented __get, consider adding a @property annotation.
Loading history...
104
        } else {
105
            $flatten = [];
106
            foreach ($children as $child) {
107
                $flatten[] = $child->flatten(\implode(' ', \array_filter(array($key, $level <= 0 ? $tag : null))), $level - 1);
108
            }
109
110
            $ret = \array_merge($ret, ...$flatten);
111
        }
112
113
        return $ret;
114
    }
115
116
    /**
117
     * @param $str
118
     *
119
     * @return mixed
120
     */
121
    public function decamelize($str)
122
    {
123
        $str = \preg_replace_callback(
124
            '/(^|[a-z])([A-Z])/',
125
            function ($matches) {
126
                return
127
                    \strtolower(
128
                        \strlen($matches[1])
129
                            ? $matches[1] . '_' . $matches[2] : $matches[2]
130
                    );
131
            },
132
            $str
133
        );
134
135
        return \preg_replace('/ /', '_', \strtolower($str));
136
    }
137
138
    /**
139
     * @param $name
140
     * @param $value
141
     */
142
    public function __set($name, $value)
143
    {
144
        switch ($name) {
145
            case 'text':
146
            case 'innertext':
147
            case 'innerText':
148
            case 'plaintext':
149
                $this->node->nodeValue = $value;
150
151
                return;
152
            case 'outertext':
153
                $this->replace($value);
154
155
                return;
156
            case 'tag':
157
                $el = $this->replace('<' . $value . '>' . $this->innerhtml . '</' . $value . '>');
0 ignored issues
show
Bug Best Practice introduced by
The property innerhtml does not exist on Bavix\AdvancedHtmlDom\AHTMLNode. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
Are you sure $this->innerhtml of type Bavix\AdvancedHtmlDom\AH...tmlDom\AHTMLNode[]|null can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
                $el = $this->replace('<' . $value . '>' . /** @scrutinizer ignore-type */ $this->innerhtml . '</' . $value . '>');
Loading history...
158
                foreach ($this->node->attributes as $_name => $att) {
159
                    $el->$_name = $att->nodeValue;
160
                }
161
                $this->node = $el->node;
162
163
                return;
164
165
        }
166
167
        $this->offsetSet($name, $value);
168
    }
169
170
    /**
171
     * @param $html
172
     *
173
     * @return AHTMLNode|null
174
     */
175
    public function replace($html)
176
    {
177
        $node = empty($html) ? null : $this->before($html);
178
        $this->remove();
179
180
        return $node;
181
    }
182
183
    /**
184
     * @param $html
185
     *
186
     * @return AHTMLNode
187
     */
188
    public function before($html)
189
    {
190
        $fragment = $this->get_fragment($html);
191
        $this->node->parentNode->insertBefore($fragment, $this->node);
192
193
        return new AHTMLNode($this->node->previousSibling, $this->doc);
194
    }
195
196
    /**
197
     * @param mixed $key
198
     * @param mixed $value
199
     */
200
    public function offsetSet($key, $value)
201
    {
202
        if (\in_array($key, ['_path', 'dom', 'doc', 'node'])) {
203
            return;
204
        }
205
206
        if ($value) {
207
            $this->node->setAttribute($key, $value);
208
            return;
209
        }
210
211
        $this->node->removeAttribute($key);
212
    }
213
214
    /**
215
     * @param mixed $offset
216
     *
217
     * @return bool
218
     */
219
    public function offsetExists($offset)
220
    {
221
        return true;
222
    }
223
224
    /**
225
     * @param mixed $offset
226
     *
227
     * @return mixed
228
     */
229
    public function offsetGet($offset)
230
    {
231
        return $this->node->getAttribute($offset);
232
    }
233
234
    /**
235
     * @param mixed $offset
236
     */
237
    public function offsetUnset($offset)
238
    {
239
        \trigger_error('offsetUnset not implemented', E_USER_WARNING);
240
    }
241
242
    /**
243
     * @return mixed
244
     */
245
    public function title()
246
    {
247
        return $this->node->getAttribute('title');
248
    }
249
}
250