Passed
Push — master ( e2177e...318bdf )
by Tim
11:09
created

Utils::copyElement()   B

Complexity

Conditions 9
Paths 40

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
cc 9
eloc 22
c 4
b 0
f 1
nc 40
nop 2
dl 0
loc 39
rs 8.0555

1 Method

Rating   Name   Duplication   Size   Complexity  
A Utils::extractStrings() 0 11 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XML;
6
7
use DateTimeImmutable;
8
use DOMElement;
9
use SimpleSAML\Assert\Assert;
10
11
use function trim;
12
13
/**
14
 * Helper functions for the XML library.
15
 *
16
 * @package simplesamlphp/xml-common
17
 */
18
class Utils
19
{
20
    /**
21
     * Extract localized strings from a set of nodes.
22
     *
23
     * @param \DOMElement $parent The element that contains the localized strings.
24
     * @param string $namespaceURI The namespace URI the localized strings should have.
25
     * @param string $localName The localName of the localized strings.
26
     * @return array Localized strings.
27
     */
28
    public static function extractLocalizedStrings(DOMElement $parent, string $namespaceURI, string $localName): array
29
    {
30
        $ret = [];
31
        foreach ($parent->childNodes as $node) {
32
            if ($node->namespaceURI !== $namespaceURI || $node->localName !== $localName) {
33
                continue;
34
            } elseif (!($node instanceof DOMElement)) {
35
                continue;
36
            }
37
38
            if ($node->hasAttribute('xml:lang')) {
39
                $language = $node->getAttribute('xml:lang');
40
            } else {
41
                $language = 'en';
42
            }
43
            $ret[$language] = trim($node->textContent);
44
        }
45
46
        return $ret;
47
    }
48
49
50
    /**
51
     * Extract strings from a set of nodes.
52
     *
53
     * @param \DOMElement $parent The element that contains the localized strings.
54
     * @param string $namespaceURI The namespace URI the string elements should have.
55
     * @param string $localName The localName of the string elements.
56
     * @return array The string values of the various nodes.
57
     */
58
    public static function extractStrings(DOMElement $parent, string $namespaceURI, string $localName): array
59
    {
60
        $ret = [];
61
        foreach ($parent->childNodes as $node) {
62
            if ($node->namespaceURI !== $namespaceURI || $node->localName !== $localName) {
63
                continue;
64
            }
65
            $ret[] = trim($node->textContent);
66
        }
67
68
        return $ret;
69
    }
70
71
72
    /**
73
     * Append string element.
74
     *
75
     * @param \DOMElement $parent The parent element we should append the new nodes to.
76
     * @param string $namespace The namespace of the created element.
77
     * @param string $name The name of the created element.
78
     * @param string $value The value of the element.
79
     * @return \DOMElement The generated element.
80
     */
81
    public static function addString(
82
        DOMElement $parent,
83
        string $namespace,
84
        string $name,
85
        string $value,
86
    ): DOMElement {
87
        $doc = $parent->ownerDocument;
88
        Assert::notNull($doc);
89
        /** @psalm-var \DOMDocument $doc */
90
91
        $n = $doc->createElementNS($namespace, $name);
92
        $n->appendChild($doc->createTextNode($value));
93
        $parent->appendChild($n);
94
95
        return $n;
96
    }
97
98
99
    /**
100
     * Append string elements.
101
     *
102
     * @param \DOMElement $parent The parent element we should append the new nodes to.
103
     * @param string $namespace The namespace of the created elements
104
     * @param string $name The name of the created elements
105
     * @param bool $localized Whether the strings are localized, and should include the xml:lang attribute.
106
     * @param array $values The values we should create the elements from.
107
     */
108
    public static function addStrings(
109
        DOMElement $parent,
110
        string $namespace,
111
        string $name,
112
        bool $localized,
113
        array $values,
114
    ): void {
115
        $doc = $parent->ownerDocument;
116
        Assert::notNull($doc);
117
        /** @psalm-var \DOMDocument $doc */
118
119
        foreach ($values as $index => $value) {
120
            $n = $doc->createElementNS($namespace, $name);
121
            $n->appendChild($doc->createTextNode($value));
122
            if ($localized) {
123
                $n->setAttribute('xml:lang', $index);
124
            }
125
            $parent->appendChild($n);
126
        }
127
    }
128
129
130
    /**
131
     * This function converts a SAML2 timestamp on the form
132
     * yyyy-mm-ddThh:mm:ss(\.s+)?Z to a UNIX timestamp. The sub-second
133
     * part is ignored.
134
     *
135
     * Note that we always require a 'Z' timezone for the dateTime to be valid.
136
     * This is not in the SAML spec but that's considered to be a bug in the
137
     * spec. See https://github.com/simplesamlphp/saml2/pull/36 for some
138
     * background.
139
     *
140
     * @param string $time The time we should convert.
141
     * @throws \Exception
142
     * @return int Converted to a unix timestamp.
143
     */
144
    public static function xsDateTimeToTimestamp(string $time): int
145
    {
146
        Assert::validDateTimeZulu($time);
147
148
        $dateTime1 = DateTimeImmutable::createFromFormat(DateTimeImmutable::ISO8601, $time);
149
        $dateTime2 = DateTimeImmutable::createFromFormat(DateTimeImmutable::RFC3339_EXTENDED, $time);
150
151
        $dateTime = $dateTime1 ?: $dateTime2;
0 ignored issues
show
introduced by
$dateTime1 is of type DateTimeImmutable, thus it always evaluated to true.
Loading history...
152
        Assert::isInstanceOf($dateTime, DateTimeImmutable::class);
153
        /** @psalm-var \DateTimeImmutable $dateTime */
154
        return $dateTime->getTimestamp();
155
    }
156
}
157