Completed
Push — master ( 08b675...1bb0e2 )
by Ryan
04:40
created

Node::handleAsText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright (c) 2017–2018 Ryan Parman <http://ryanparman.com>.
4
 * Copyright (c) 2017–2018 Contributors.
5
 *
6
 * http://opensource.org/licenses/Apache2.0
7
 */
8
9
declare(strict_types=1);
10
11
namespace SimplePie\Type;
12
13
use DOMAttr;
14
use DOMNode;
15
use DOMText;
16
use SimplePie\Enum\CharacterSet;
17
use SimplePie\Enum\Serialization;
18
19
/**
20
 * A type model for a deep-level Node element.
21
 */
22
class Node extends AbstractType implements NodeInterface
23
{
24
    /**
25
     * The raw `DOMNode` element.
26
     *
27
     * @var DOMNode|null
28
     */
29
    protected $node;
30
31
    /**
32
     * The content of the node, serialized appropriately.
33
     *
34
     * @var string|null
35
     */
36
    protected $value;
37
38
    /**
39
     * The serialization of the content.
40
     *
41
     * @var string
42
     */
43
    protected $serialization = Serialization::TEXT;
44
45
    /**
46
     * Get the text node in multiple formats.
47
     *
48
     * @param DOMNode|null $node A `DOMNode` element to read properties from.
49
     */
50
    public function __construct(?DOMNode $node = null)
51
    {
52
        if ($node) {
53
            $this->node  = $node;
54
            $this->value = $node->nodeValue;
55
56
            if (XML_ELEMENT_NODE === $node->nodeType && $node->attributes->length > 0) {
57
                foreach ($node->attributes as $attribute) {
58
                    if ('src' === $attribute->name) {
59
                        $this->handleAsSource($node, $attribute);
60
                        break;
61
                    } elseif ('type' === $attribute->name && Serialization::TEXT === $attribute->value) {
62
                        $this->handleAsText($node, $attribute);
63
                        break;
64
                    } elseif ('type' === $attribute->name && Serialization::HTML === $attribute->value) {
65
                        $this->handleAsHtml($node, $attribute);
66
                        break;
67
                    } elseif ('type' === $attribute->name && Serialization::XHTML === $attribute->value) {
68
                        $this->handleAsXhtml($node, $attribute);
69
                        break;
70
                    } elseif ('type' === $attribute->name && 'application/octet-stream' === $attribute->value) {
71
                        $this->handleAsBase64($node);
72
                        break;
73
                    } else {
74
                        $this->serialization = Serialization::TEXT;
75
                        $this->value         = $node->nodeValue;
76
                    }
77
                }
78
            }
79
        }
80
    }
81
82
    /**
83
     * Casting this Node element to a string with return the _value_ of the Node.
84
     *
85
     * @return string
86
     */
87
    public function __toString(): string
88
    {
89
        return $this->getValue() ?? '';
90
    }
91
92
    /**
93
     * Creates a new `Node` object from a string of text (such as from an XML attribute).
94
     *
95
     * @param string $value The string of text to convert to a `Node` object.
96
     *
97
     * @return Node
98
     */
99
    public static function factory(string $value): self
100
    {
101
        return new self(
102
            new DOMText($value)
103
        );
104
    }
105
106
    /**
107
     * Gets the raw `DOMNode` element.
108
     *
109
     * @return DOMNode|null
110
     */
111
    public function getNode(): ?DOMNode
112
    {
113
        return $this->node;
114
    }
115
116
    /**
117
     * Gets the content of the node, serialized appropriately.
118
     *
119
     * @return string|null
120
     */
121
    public function getValue(): ?string
122
    {
123
        return $this->value;
124
    }
125
126
    /**
127
     * Gets the serialization of the content.
128
     *
129
     * Will always be one of the enums from `SimplePie\Enum\Serialization`.
130
     *
131
     * @return string
132
     */
133
    public function getSerialization(): string
134
    {
135
        return $this->serialization;
136
    }
137
138
    /**
139
     * Handle the content as source.
140
     *
141
     * @param  DOMNode $node      The DOMNode element.
142
     * @param  DOMAttr $attribute The DOMAttr element.
143
     */
144
    private function handleAsSource(DOMNode $node, DOMAttr $attribute): void
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed. ( Ignorable by Annotation )

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

144
    private function handleAsSource(/** @scrutinizer ignore-unused */ DOMNode $node, DOMAttr $attribute): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
145
    {
146
        $this->serialization = Serialization::TEXT;
147
        $this->value         = $attribute->nodeValue;
148
    }
149
150
    /**
151
     * Handle the content as plain text.
152
     *
153
     * @param  DOMNode $node      The DOMNode element.
154
     * @param  DOMAttr $attribute The DOMAttr element.
155
     */
156
    private function handleAsText(DOMNode $node, DOMAttr $attribute): void
157
    {
158
        $this->serialization = $attribute->nodeValue;
159
        $this->value         = \html_entity_decode(
160
            $node->nodeValue,
161
            ENT_COMPAT,
162
            CharacterSet::UTF_8
163
        );
164
    }
165
166
    /**
167
     * Handle the content as HTML.
168
     *
169
     * @param  DOMNode $node      The DOMNode element.
170
     * @param  DOMAttr $attribute The DOMAttr element.
171
     */
172
    private function handleAsHtml(DOMNode $node, DOMAttr $attribute): void
173
    {
174
        $this->serialization = $attribute->nodeValue;
175
        $this->value         = \html_entity_decode(
176
            $node->nodeValue,
177
            ENT_COMPAT | ENT_HTML5,
178
            CharacterSet::UTF_8
179
        );
180
    }
181
182
    /**
183
     * Handle the content as XHTML.
184
     *
185
     * @param  DOMNode $node      The DOMNode element.
186
     * @param  DOMAttr $attribute The DOMAttr element.
187
     */
188
    private function handleAsXhtml(DOMNode $node, DOMAttr $attribute): void
189
    {
190
        $this->serialization = $attribute->nodeValue;
191
192
        // We can't just grab the content. We need to stringify it, then remove the wrapper element.
193
        $content = preg_replace(
194
            '/^<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">(.*)<\/div>$/ims',
195
            '$1',
196
            $node->ownerDocument->saveXML(
197
                $node->getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'div')[0]
198
            )
199
        );
200
201
        $this->value = trim($content);
202
    }
203
204
    /**
205
     * Handle the content as Base64-encoded text.
206
     *
207
     * @param  DOMNode $node      The DOMNode element.
208
     */
209
    private function handleAsBase64(DOMNode $node): void
210
    {
211
        $this->serialization = Serialization::TEXT;
212
        $this->value = base64_decode(trim($node->nodeValue));
213
    }
214
}
215