• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

voku / simple_html_dom / 24702136431

21 Apr 2026 03:15AM UTC coverage: 96.034% (-0.07%) from 96.106%
24702136431

push

github

voku
[+]: work on phpstan reported issues :)

... before a new release goes live.

208 of 218 new or added lines in 12 files covered. (95.41%)

6 existing lines in 2 files now uncovered.

2155 of 2244 relevant lines covered (96.03%)

286.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.31
/src/voku/helper/AbstractSimpleHtmlDom.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace voku\helper;
6

7
abstract class AbstractSimpleHtmlDom
8
{
9
    /**
10
     * @var array<string, string>
11
     */
12
    protected static $functionAliases = [
13
        'children'     => 'childNodes',
14
        'first_child'  => 'firstChild',
15
        'last_child'   => 'lastChild',
16
        'next_sibling' => 'nextSibling',
17
        'prev_sibling' => 'previousSibling',
18
        'parent'       => 'parentNode',
19
        'outertext'    => 'html',
20
        'outerhtml'    => 'html',
21
        'innertext'    => 'innerHtml',
22
        'innerhtml'    => 'innerHtml',
23
        'innerhtmlkeep'    => 'innerHtmlKeep',
24
    ];
25

26
    /**
27
     * @var string[]
28
     */
29
    protected static $stringDomNodes = [
30
        'id',
31
        'prefix',
32
        'content'
33
    ];
34

35
    /**
36
     * @var \DOMElement|\DOMNode|null
37
     */
38
    protected $node;
39

40
    /**
41
     * @var SimpleHtmlAttributes|null
42
     */
43
    private $classListCache;
44

45
    /**
46
     * @param string       $name
47
     * @param array<mixed> $arguments
48
     *
49
     * @throws \BadMethodCallException
50
     *
51
     * @return SimpleHtmlDomInterface|string|null
52
     */
53
    public function __call($name, $arguments)
54
    {
55
        $name = \strtolower($name);
×
56

57
        if (isset(self::$functionAliases[$name])) {
×
NEW
58
            $method = self::$functionAliases[$name];
×
59

NEW
60
            return $this->{$method}(...$arguments);
×
61
        }
62

63
        throw new \BadMethodCallException('Method does not exist');
×
64
    }
65

66
    /**
67
     * @param string $name
68
     *
69
     * @return array<int, string>|SimpleHtmlAttributes|string|null
70
     */
71
    public function __get($name)
72
    {
73
        $nameOrig = $name;
770✔
74
        $name = \strtolower($name);
770✔
75

76
        switch ($name) {
77
            case 'outerhtml':
770✔
78
            case 'outertext':
714✔
79
            case 'html':
623✔
80
                return $this->html();
238✔
81
            case 'innerhtml':
616✔
82
            case 'innertext':
518✔
83
                return $this->innerHtml();
168✔
84
            case 'innerhtmlkeep':
476✔
85
                return $this->innerHtml(false, false);
14✔
86
            case 'text':
476✔
87
            case 'plaintext':
434✔
88
                return $this->text();
252✔
89
            case 'tag':
259✔
90
                return $this->node->nodeName ?? '';
70✔
91
            case 'attr':
224✔
92
                return $this->getAllAttributes();
7✔
93
            case 'classlist':
224✔
94
                if ($this->classListCache === null) {
91✔
95
                    $this->classListCache = new SimpleHtmlAttributes(
91✔
96
                        $this->node instanceof \DOMElement ? $this->node : null,
91✔
97
                        'class'
91✔
98
                    );
91✔
99
                }
100

101
                return $this->classListCache;
91✔
102
            default:
103
                if ($this->node && \property_exists($this->node, $nameOrig)) {
133✔
104
                    if (\is_string($this->node->{$nameOrig})) {
34✔
105
                        return HtmlDomParser::putReplacedBackToPreserveHtmlEntities($this->node->{$nameOrig});
34✔
106
                    }
107

108
                    return $this->node->{$nameOrig};
×
109
                }
110

111
                return $this->getAttribute($name);
117✔
112
        }
113
    }
114

115
    /**
116
     * @param string $selector
117
     * @param int    $idx
118
     *
119
     * @return SimpleHtmlDomInterface|SimpleHtmlDomInterface[]|SimpleHtmlDomNodeInterface<SimpleHtmlDomInterface>
120
     */
121
    public function __invoke($selector, $idx = null)
122
    {
123
        return $this->find($selector, $idx);
91✔
124
    }
125

126
    /**
127
     * @param string $name
128
     *
129
     * @return bool
130
     */
131
    public function __isset($name)
132
    {
133
        $nameOrig = $name;
14✔
134
        $name = \strtolower($name);
14✔
135

136
        switch ($name) {
137
            case 'outertext':
14✔
138
            case 'outerhtml':
14✔
139
            case 'innertext':
14✔
140
            case 'innerhtml':
14✔
141
            case 'innerhtmlkeep':
14✔
142
            case 'plaintext':
14✔
143
            case 'text':
14✔
144
            case 'tag':
14✔
145
                return true;
7✔
146
            default:
147
                if ($this->node && \property_exists($this->node, $nameOrig)) {
14✔
UNCOV
148
                    return isset($this->node->{$nameOrig});
2✔
149
                }
150

151
                return $this->hasAttribute($name);
12✔
152
        }
153
    }
154

155
    /**
156
     * @param string $name
157
     * @param mixed  $value
158
     *
159
     * @return void
160
     */
161
    public function __set($name, $value): void
162
    {
163
        $nameOrig = $name;
350✔
164
        $name = \strtolower($name);
350✔
165

166
        switch ($name) {
167
            case 'outerhtml':
350✔
168
            case 'outertext':
287✔
169
                $this->replaceNodeWithString($value);
203✔
170
                return;
203✔
171
            case 'innertext':
168✔
172
            case 'innerhtml':
133✔
173
                $this->replaceChildWithString($value);
91✔
174
                return;
91✔
175
            case 'innerhtmlkeep':
112✔
176
                $this->replaceChildWithString($value, false);
14✔
177
                return;
14✔
178
            case 'plaintext':
105✔
179
                $this->replaceTextWithString($value);
14✔
180
                return;
14✔
181
            case 'classlist':
98✔
182
                $name = 'class';
14✔
183
                $nameOrig = 'class';
14✔
184
                // no break
185
            default:
186
                if ($this->node && \property_exists($this->node, $nameOrig)) {
98✔
187
                    // INFO: Cannot assign null to property DOMNode::* of type string
UNCOV
188
                    if (\in_array($nameOrig, self::$stringDomNodes)) {
2✔
UNCOV
189
                        $value = (string) $value;
2✔
190
                    }
191

UNCOV
192
                    if ($value !== null) {
2✔
UNCOV
193
                        $this->node->{$nameOrig} = $value;
2✔
NEW
194
                        return;
2✔
195
                    }
196
                }
197

198
                $this->setAttribute($name, $value);
98✔
199
        }
200
    }
201

202
    /**
203
     * @return string
204
     */
205
    public function __toString()
206
    {
207
        return $this->html();
28✔
208
    }
209

210
    /**
211
     * @param string $name
212
     *
213
     * @return void
214
     */
215
    public function __unset($name)
216
    {
217
        /** @noinspection UnusedFunctionResultInspection */
218
        $this->removeAttribute($name);
7✔
219
    }
220

221
    /**
222
     * @param string $selector
223
     * @param int|null   $idx
224
     *
225
     * @return mixed
226
     */
227
    abstract public function find(string $selector, $idx = null);
228

229
    /**
230
     * @return string[]|null
231
     */
232
    abstract public function getAllAttributes();
233

234
    abstract public function getAttribute(string $name): string;
235

236
    abstract public function hasAttribute(string $name): bool;
237

238
    abstract public function html(bool $multiDecodeNewHtmlEntity = false): string;
239

240
    abstract public function innerHtml(bool $multiDecodeNewHtmlEntity = false, bool $putBrokenReplacedBack = true): string;
241

242
    abstract public function removeAttribute(string $name): SimpleHtmlDomInterface;
243

244
    abstract protected function replaceChildWithString(string $string, bool $putBrokenReplacedBack = true): SimpleHtmlDomInterface;
245

246
    abstract protected function replaceNodeWithString(string $string): SimpleHtmlDomInterface;
247

248
    /**
249
     * @param string $string
250
     *
251
     * @return SimpleHtmlDomInterface
252
     */
253
    abstract protected function replaceTextWithString($string): SimpleHtmlDomInterface;
254

255
    /**
256
     * @param string      $name
257
     * @param string|null $value
258
     * @param bool        $strictEmptyValueCheck
259
     *
260
     * @return SimpleHtmlDomInterface
261
     */
262
    abstract public function setAttribute(string $name, $value = null, bool $strictEmptyValueCheck = false): SimpleHtmlDomInterface;
263

264
    abstract public function text(): string;
265
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc