1<?php
2
3namespace SAML2\XML\saml;
4
5use SAML2\Constants;
6use SAML2\Utils;
7
8/**
9 * Class representing SAML 2 Attribute.
10 *
11 * @package SimpleSAMLphp
12 */
13class Attribute
14{
15    /**
16     * The Name of this attribute.
17     *
18     * @var string
19     */
20    public $Name;
21
22    /**
23     * The NameFormat of this attribute.
24     *
25     * @var string|null
26     */
27    public $NameFormat;
28
29    /**
30     * The FriendlyName of this attribute.
31     *
32     * @var string|null
33     */
34    public $FriendlyName = null;
35
36    /**
37     * List of attribute values.
38     *
39     * Array of \SAML2\XML\saml\AttributeValue elements.
40     *
41     * @var \SAML2\XML\saml\AttributeValue[]
42     */
43    public $AttributeValue = array();
44
45    /**
46     * Initialize an Attribute.
47     *
48     * @param \DOMElement|null $xml The XML element we should load.
49     * @throws \Exception
50     */
51    public function __construct(\DOMElement $xml = null)
52    {
53        if ($xml === null) {
54            return;
55        }
56
57        if (!$xml->hasAttribute('Name')) {
58            throw new \Exception('Missing Name on Attribute.');
59        }
60        $this->Name = $xml->getAttribute('Name');
61
62        if ($xml->hasAttribute('NameFormat')) {
63            $this->NameFormat = $xml->getAttribute('NameFormat');
64        }
65
66        if ($xml->hasAttribute('FriendlyName')) {
67            $this->FriendlyName = $xml->getAttribute('FriendlyName');
68        }
69
70        foreach (Utils::xpQuery($xml, './saml_assertion:AttributeValue') as $av) {
71            $this->AttributeValue[] = new AttributeValue($av);
72        }
73    }
74
75    /**
76     * Internal implementation of toXML.
77     * This function allows RequestedAttribute to specify the element name and namespace.
78     *
79     * @param \DOMElement $parent    The element we should append this Attribute to.
80     * @param string     $namespace The namespace the element should be created in.
81     * @param string     $name      The name of the element.
82     * @return \DOMElement
83     */
84    protected function toXMLInternal(\DOMElement $parent, $namespace, $name)
85    {
86        assert(is_string($namespace));
87        assert(is_string($name));
88        assert(is_string($this->Name));
89        assert(is_null($this->NameFormat) || is_string($this->NameFormat));
90        assert(is_null($this->FriendlyName) || is_string($this->FriendlyName));
91        assert(is_array($this->AttributeValue));
92
93        $e = $parent->ownerDocument->createElementNS($namespace, $name);
94        $parent->appendChild($e);
95
96        $e->setAttribute('Name', $this->Name);
97
98        if (isset($this->NameFormat)) {
99            $e->setAttribute('NameFormat', $this->NameFormat);
100        }
101
102        if (isset($this->FriendlyName)) {
103            $e->setAttribute('FriendlyName', $this->FriendlyName);
104        }
105
106        foreach ($this->AttributeValue as $av) {
107            $av->toXML($e);
108        }
109
110        return $e;
111    }
112
113    /**
114     * Convert this Attribute to XML.
115     *
116     * @param \DOMElement $parent The element we should append this Attribute to.
117     * @return \DOMElement
118     */
119    public function toXML(\DOMElement $parent)
120    {
121        return $this->toXMLInternal($parent, Constants::NS_SAML, 'saml:Attribute');
122    }
123}
124