Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
365 lars 1
<?php declare(strict_types=1);
2
namespace PHPHtmlParser\Dom;
3
 
4
use PHPHtmlParser\Exceptions\UnknownChildTypeException;
5
use PHPHtmlParser\Exceptions\ChildNotFoundException;
6
 
7
/**
8
 * Class HtmlNode
9
 *
10
 * @package PHPHtmlParser\Dom
11
 */
12
class HtmlNode extends InnerNode
13
{
14
 
15
    /**
16
     * Remembers what the innerHtml was if it was scanned previously.
17
     *
18
     * @var ?string
19
     */
20
    protected $innerHtml = null;
21
 
22
    /**
23
     * Remembers what the outerHtml was if it was scanned previously.
24
     *
25
     * @var ?string
26
     */
27
    protected $outerHtml = null;
28
 
29
    /**
30
     * Remembers what the text was if it was scanned previously.
31
     *
32
     * @var ?string
33
     */
34
    protected $text = null;
35
 
36
    /**
37
     * Remembers what the text was when we looked into all our
38
     * children nodes.
39
     *
40
     * @var ?string
41
     */
42
    protected $textWithChildren = null;
43
 
44
    /**
45
     * Sets up the tag of this node.
46
     *
47
     * @param string|Tag $tag
48
     */
49
    public function __construct($tag)
50
    {
51
        if ( ! $tag instanceof Tag) {
52
            $tag = new Tag($tag);
53
        }
54
        $this->tag = $tag;
55
        parent::__construct();
56
    }
57
 
58
    /**
59
     * @param bool $htmlSpecialCharsDecode
60
     * @return void
61
     */
62
    public function setHtmlSpecialCharsDecode($htmlSpecialCharsDecode = false): void
63
    {
64
        parent::setHtmlSpecialCharsDecode($htmlSpecialCharsDecode);
65
        $this->tag->setHtmlSpecialCharsDecode($htmlSpecialCharsDecode);
66
    }
67
 
68
    /**
69
     * Gets the inner html of this node.
70
     * @return string
71
     * @throws ChildNotFoundException
72
     * @throws UnknownChildTypeException
73
     */
74
    public function innerHtml(): string
75
    {
76
        if ( ! $this->hasChildren()) {
77
            // no children
78
            return '';
79
        }
80
 
81
        if ( ! is_null($this->innerHtml)) {
82
            // we already know the result.
83
            return $this->innerHtml;
84
        }
85
 
86
        $child  = $this->firstChild();
87
        $string = '';
88
 
89
        // continue to loop until we are out of children
90
        while ( ! is_null($child)) {
91
            if ($child instanceof TextNode) {
92
                $string .= $child->text();
93
            } elseif ($child instanceof HtmlNode) {
94
                $string .= $child->outerHtml();
95
            } else {
96
                throw new UnknownChildTypeException('Unknown child type "'.get_class($child).'" found in node');
97
            }
98
 
99
            try {
100
                $child = $this->nextChild($child->id());
101
            } catch (ChildNotFoundException $e) {
102
                // no more children
103
                unset($e);
104
                $child = null;
105
            }
106
        }
107
 
108
        // remember the results
109
        $this->innerHtml = $string;
110
 
111
        return $string;
112
    }
113
 
114
    /**
115
     * Gets the html of this node, including it's own
116
     * tag.
117
     * @return string
118
     * @throws ChildNotFoundException
119
     * @throws UnknownChildTypeException
120
     */
121
    public function outerHtml(): string
122
    {
123
        // special handling for root
124
        if ($this->tag->name() == 'root') {
125
            return $this->innerHtml();
126
        }
127
 
128
        if ( ! is_null($this->outerHtml)) {
129
            // we already know the results.
130
            return $this->outerHtml;
131
        }
132
 
133
        $return = $this->tag->makeOpeningTag();
134
        if ($this->tag->isSelfClosing()) {
135
            // ignore any children... there should not be any though
136
            return $return;
137
        }
138
 
139
        // get the inner html
140
        $return .= $this->innerHtml();
141
 
142
        // add closing tag
143
        $return .= $this->tag->makeClosingTag();
144
 
145
        // remember the results
146
        $this->outerHtml = $return;
147
 
148
        return $return;
149
    }
150
 
151
    /**
152
     * Gets the text of this node (if there is any text). Or get all the text
153
     * in this node, including children.
154
     *
155
     * @param bool $lookInChildren
156
     * @return string
157
     */
158
    public function text(bool $lookInChildren = false): string
159
    {
160
        if ($lookInChildren) {
161
            if ( ! is_null($this->textWithChildren)) {
162
                // we already know the results.
163
                return $this->textWithChildren;
164
            }
165
        } elseif ( ! is_null($this->text)) {
166
            // we already know the results.
167
            return $this->text;
168
        }
169
 
170
        // find out if this node has any text children
171
        $text = '';
172
        foreach ($this->children as $child) {
173
            /** @var AbstractNode $node */
174
            $node = $child['node'];
175
            if ($node instanceof TextNode) {
176
                $text .= $child['node']->text;
177
            } elseif ($lookInChildren &&
178
                $node instanceof HtmlNode
179
            ) {
180
                $text .= $node->text($lookInChildren);
181
            }
182
        }
183
 
184
        // remember our result
185
        if ($lookInChildren) {
186
            $this->textWithChildren = $text;
187
        } else {
188
            $this->text = $text;
189
        }
190
 
191
        return $text;
192
    }
193
 
194
    /**
195
     * Call this when something in the node tree has changed. Like a child has been added
196
     * or a parent has been changed.
197
     */
198
    protected function clear(): void
199
    {
200
        $this->innerHtml = null;
201
        $this->outerHtml = null;
202
        $this->text      = null;
203
        $this->textWithChildren = null;
204
 
205
        if (!is_null($this->parent)) {
206
            $this->parent->clear();
207
        }
208
    }
209
 
210
    /**
211
     * Returns all children of this html node.
212
     *
213
     * @return array
214
     */
215
    protected function getIteratorArray(): array
216
    {
217
        return $this->getChildren();
218
    }
219
}