Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of PHPUnit.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace PHPUnit\Util;
11
 
12
use const ENT_QUOTES;
13
use function assert;
14
use function class_exists;
15
use function htmlspecialchars;
16
use function mb_convert_encoding;
17
use function ord;
18
use function preg_replace;
19
use function settype;
20
use function strlen;
21
use DOMCharacterData;
22
use DOMDocument;
23
use DOMElement;
24
use DOMNode;
25
use DOMText;
26
use ReflectionClass;
27
use ReflectionException;
28
 
29
/**
30
 * @internal This class is not covered by the backward compatibility promise for PHPUnit
31
 */
32
final class Xml
33
{
34
    /**
35
     * @deprecated Only used by assertEqualXMLStructure()
36
     */
37
    public static function import(DOMElement $element): DOMElement
38
    {
39
        return (new DOMDocument)->importNode($element, true);
40
    }
41
 
42
    /**
43
     * @deprecated Only used by assertEqualXMLStructure()
44
     */
45
    public static function removeCharacterDataNodes(DOMNode $node): void
46
    {
47
        if ($node->hasChildNodes()) {
48
            for ($i = $node->childNodes->length - 1; $i >= 0; $i--) {
49
                if (($child = $node->childNodes->item($i)) instanceof DOMCharacterData) {
50
                    $node->removeChild($child);
51
                }
52
            }
53
        }
54
    }
55
 
56
    /**
57
     * Escapes a string for the use in XML documents.
58
     *
59
     * Any Unicode character is allowed, excluding the surrogate blocks, FFFE,
60
     * and FFFF (not even as character reference).
61
     *
62
     * @see https://www.w3.org/TR/xml/#charsets
63
     */
64
    public static function prepareString(string $string): string
65
    {
66
        return preg_replace(
67
            '/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/',
68
            '',
69
            htmlspecialchars(
70
                self::convertToUtf8($string),
71
                ENT_QUOTES
72
            )
73
        );
74
    }
75
 
76
    /**
77
     * "Convert" a DOMElement object into a PHP variable.
78
     */
79
    public static function xmlToVariable(DOMElement $element)
80
    {
81
        $variable = null;
82
 
83
        switch ($element->tagName) {
84
            case 'array':
85
                $variable = [];
86
 
87
                foreach ($element->childNodes as $entry) {
88
                    if (!$entry instanceof DOMElement || $entry->tagName !== 'element') {
89
                        continue;
90
                    }
91
                    $item = $entry->childNodes->item(0);
92
 
93
                    if ($item instanceof DOMText) {
94
                        $item = $entry->childNodes->item(1);
95
                    }
96
 
97
                    $value = self::xmlToVariable($item);
98
 
99
                    if ($entry->hasAttribute('key')) {
100
                        $variable[(string) $entry->getAttribute('key')] = $value;
101
                    } else {
102
                        $variable[] = $value;
103
                    }
104
                }
105
 
106
                break;
107
 
108
            case 'object':
109
                $className = $element->getAttribute('class');
110
 
111
                if ($element->hasChildNodes()) {
112
                    $arguments       = $element->childNodes->item(0)->childNodes;
113
                    $constructorArgs = [];
114
 
115
                    foreach ($arguments as $argument) {
116
                        if ($argument instanceof DOMElement) {
117
                            $constructorArgs[] = self::xmlToVariable($argument);
118
                        }
119
                    }
120
 
121
                    try {
122
                        assert(class_exists($className));
123
 
124
                        $variable = (new ReflectionClass($className))->newInstanceArgs($constructorArgs);
125
                        // @codeCoverageIgnoreStart
126
                    } catch (ReflectionException $e) {
127
                        throw new Exception(
128
                            $e->getMessage(),
129
                            $e->getCode(),
130
                            $e
131
                        );
132
                    }
133
                    // @codeCoverageIgnoreEnd
134
                } else {
135
                    $variable = new $className;
136
                }
137
 
138
                break;
139
 
140
            case 'boolean':
141
                $variable = $element->textContent === 'true';
142
 
143
                break;
144
 
145
            case 'integer':
146
            case 'double':
147
            case 'string':
148
                $variable = $element->textContent;
149
 
150
                settype($variable, $element->tagName);
151
 
152
                break;
153
        }
154
 
155
        return $variable;
156
    }
157
 
158
    private static function convertToUtf8(string $string): string
159
    {
160
        if (!self::isUtf8($string)) {
161
            $string = mb_convert_encoding($string, 'UTF-8');
162
        }
163
 
164
        return $string;
165
    }
166
 
167
    private static function isUtf8(string $string): bool
168
    {
169
        $length = strlen($string);
170
 
171
        for ($i = 0; $i < $length; $i++) {
172
            if (ord($string[$i]) < 0x80) {
173
                $n = 0;
174
            } elseif ((ord($string[$i]) & 0xE0) === 0xC0) {
175
                $n = 1;
176
            } elseif ((ord($string[$i]) & 0xF0) === 0xE0) {
177
                $n = 2;
178
            } elseif ((ord($string[$i]) & 0xF0) === 0xF0) {
179
                $n = 3;
180
            } else {
181
                return false;
182
            }
183
 
184
            for ($j = 0; $j < $n; $j++) {
185
                if ((++$i === $length) || ((ord($string[$i]) & 0xC0) !== 0x80)) {
186
                    return false;
187
                }
188
            }
189
        }
190
 
191
        return true;
192
    }
193
}