Completed
Push — master ( b4a32a...a386bd )
by Tim
18s queued 14s
created

TypedTextContentTrait::toXML()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 9
c 2
b 0
f 1
dl 0
loc 17
rs 9.9666
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\XML;
6
7
use DOMElement;
8
use SimpleSAML\XML\Assert\Assert;
9
use SimpleSAML\XML\Exception\{InvalidDOMElementException, InvalidValueTypeException};
10
use SimpleSAML\XML\Type\{QNameValue, StringValue, ValueTypeInterface};
11
12
use function defined;
13
use function strval;
14
15
/**
16
 * Trait for elements that hold a typed textContent value.
17
 *
18
 * @package simplesaml/xml-common
19
 */
20
trait TypedTextContentTrait
21
{
22
    /** @var \SimpleSAML\XML\Type\ValueTypeInterface $content */
23
    protected ValueTypeInterface $content;
24
25
26
    /**
27
     * @param \SimpleSAML\XML\Type\ValueTypeInterface $content
28
     */
29
    public function __construct(
30
        ValueTypeInterface $content,
31
    ) {
32
        $this->setContent($content);
33
    }
34
35
36
    /**
37
     * Set the content of the element.
38
     *
39
     * @param \SimpleSAML\XML\Type\ValueTypeInterface $content  The value to go in the XML textContent
40
     */
41
    protected function setContent(ValueTypeInterface $content): void
42
    {
43
        Assert::isAOf($content, self::getTextContentType(), InvalidValueTypeException::class);
44
        $this->content = $content;
45
    }
46
47
48
    /**
49
     * Get the typed content of the element
50
     *
51
     * @return \SimpleSAML\XML\Type\ValueTypeInterface
52
     */
53
    public function getContent(): ValueTypeInterface
54
    {
55
        return $this->content;
56
    }
57
58
59
    /**
60
     * Create a class from XML
61
     *
62
     * @param \DOMElement $xml
63
     * @return static
64
     */
65
    public static function fromXML(DOMElement $xml): static
66
    {
67
        Assert::same($xml->localName, static::getLocalName(), InvalidDOMElementException::class);
68
        Assert::same($xml->namespaceURI, static::NS, InvalidDOMElementException::class);
69
70
        $type = self::getTextContentType();
71
        if ($type === QNameValue::class) {
72
            $qName = QNameValue::fromDocument($xml->textContent, $xml);
73
            $text = $qName->getRawValue();
74
        } else {
75
            $text = $xml->textContent;
76
        }
77
78
        return new static($type::fromString($text));
79
    }
80
81
82
    /**
83
     * Create XML from this class
84
     *
85
     * @param \DOMElement|null $parent
86
     * @return \DOMElement
87
     */
88
    public function toXML(?DOMElement $parent = null): DOMElement
89
    {
90
        $e = $this->instantiateParentElement($parent);
91
92
        if ($this->getTextContentType() === QNameValue::class) {
93
            if (!$e->lookupPrefix($this->getContent()->getNamespaceURI()->getValue())) {
0 ignored issues
show
Bug introduced by
The method getNamespaceURI() does not exist on SimpleSAML\XML\Type\ValueTypeInterface. It seems like you code against a sub-type of SimpleSAML\XML\Type\ValueTypeInterface such as SimpleSAML\XML\Type\QNameValue. ( Ignorable by Annotation )

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

93
            if (!$e->lookupPrefix($this->getContent()->/** @scrutinizer ignore-call */ getNamespaceURI()->getValue())) {
Loading history...
94
                $e->setAttributeNS(
95
                    'http://www.w3.org/2000/xmlns/',
96
                    'xmlns:' . $this->getContent()->getNamespacePrefix()->getValue(),
0 ignored issues
show
Bug introduced by
The method getNamespacePrefix() does not exist on SimpleSAML\XML\Type\ValueTypeInterface. It seems like you code against a sub-type of SimpleSAML\XML\Type\ValueTypeInterface such as SimpleSAML\XML\Type\QNameValue. ( Ignorable by Annotation )

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

96
                    'xmlns:' . $this->getContent()->/** @scrutinizer ignore-call */ getNamespacePrefix()->getValue(),
Loading history...
97
                    $this->getContent()->getNamespaceURI()->getValue(),
98
                );
99
            }
100
        }
101
102
        $e->textContent = strval($this->getContent());
103
104
        return $e;
105
    }
106
107
108
    /**
109
     * Get the type the element's textContent value.
110
     *
111
     * @return class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
112
     */
113
    public static function getTextContentType(): string
114
    {
115
        if (defined('self::TEXTCONTENT_TYPE')) {
116
            $type = self::TEXTCONTENT_TYPE;
117
        } else {
118
            $type = StringValue::class;
119
        }
120
121
        Assert::isAOf($type, ValueTypeInterface::class, InvalidValueTypeException::class);
122
        return $type;
123
    }
124
125
126
    /**
127
     * Create a document structure for this element
128
     *
129
     * @param \DOMElement|null $parent The element we should append to.
130
     * @return \DOMElement
131
     */
132
    abstract public function instantiateParentElement(?DOMElement $parent = null): DOMElement;
133
}
134