Completed
Push — feature/issue-7 ( 1ff64b...c1a8e7 )
by Mikaël
04:04
created

Element::setDom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace WsdlToPhp\WsSecurity;
4
5
/**
6
 * Base class to represent any element that must be included for a WS-Security header.
7
 * Each element must be named with the actual targeted element tag name.
8
 * The namespace is also mandatory.
9
 * Finally the attributes are optional.
10
 */
11
class Element
12
{
13
    /**
14
     * Namespace for WSSE elements.
15
     *
16
     * @var string
17
     */
18
    const NS_WSSE = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
19
    /**
20
     * Namespace name for WSSE elements.
21
     *
22
     * @var string
23
     */
24
    const NS_WSSE_NAME = 'wsse';
25
    /**
26
     * Namespace for WSSU elements.
27
     *
28
     * @var string
29
     */
30
    const NS_WSSU = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
31
    /**
32
     * Namespace name for WSSU elements.
33
     *
34
     * @var string
35
     */
36
    const NS_WSSU_NAME = 'wssu';
37
    /**
38
     * Name of the element used as the WS-Security tag.
39
     *
40
     * @var string
41
     */
42
    protected $name = '';
43
    /**
44
     * Value of the element.
45
     * It can either be a string value or a Element object.
46
     *
47
     * @var Element|string
48
     */
49
    protected $value = '';
50
    /**
51
     * Array of attributes that must contains the element.
52
     *
53
     * @var array
54
     */
55
    protected $attributes = [];
56
    /**
57
     * The namespace the element belongs to.
58
     *
59
     * @var string
60
     */
61
    protected $namespace = '';
62
    /**
63
     * Nonce used to generate digest password.
64
     *
65
     * @var string
66
     */
67
    protected $nonceValue;
68
    /**
69
     * Timestamp used to generate digest password.
70
     *
71
     * @var int
72
     */
73
    protected $timestampValue;
74
    /**
75
     * Current \DOMDocument used to generate XML content.
76
     *
77
     * @var \DOMDocument
78
     */
79
    protected static $dom = null;
80
81
    /**
82
     * Generic constructor.
83
     *
84
     * @param string $name
85
     * @param string $namespace
86
     * @param mixed  $value
87
     * @param array  $attributes
88
     */
89 54
    public function __construct($name, $namespace, $value = null, array $attributes = [])
90
    {
91 27
        $this
92 54
            ->setName($name)
93 54
            ->setNamespace($namespace)
94 54
            ->setValue($value)
95 54
            ->setAttributes($attributes)
96
        ;
97 54
    }
98
99
    /**
100
     * Method called to generate the string XML request to be sent among the SOAP Header.
101
     *
102
     * @param bool $asDomElement returns elements as a \DOMElement or as a string
103
     *
104
     * @return \DOMElement|string
105
     */
106 54
    protected function __toSend($asDomElement = false)
107
    {
108
        /**
109
         * Create element tag.
110
         */
111 54
        $element = self::getDom()->createElement($this->getNamespacedName());
112 54
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', sprintf('xmlns:%s', $this->getNamespacePrefix()), $this->getNamespace());
113
        /*
114
         * Define element value
115
         * Add attributes if there are any
116
         */
117 27
        $this
118 54
            ->appendValueToElementToSend($this->getValue(), $element)
119 54
            ->appendAttributesToElementToSend($element)
120
        ;
121
        // Returns element content
122 54
        if ($asDomElement) {
123 54
            return $element;
124
        }
125
126 54
        return self::getDom()->saveXML($element);
127
    }
128
129
    /**
130
     * @return string
131
     */
132 54
    public function getName()
133
    {
134 54
        return $this->name;
135
    }
136
137
    /**
138
     * @param string $name
139
     *
140
     * @return Element
141
     */
142 54
    public function setName($name)
143
    {
144 54
        $this->name = $name;
145
146 54
        return $this;
147
    }
148
149
    /**
150
     * @return array
151
     */
152 54
    public function getAttributes()
153
    {
154 54
        return $this->attributes;
155
    }
156
157
    /**
158
     * @param array $attributes
159
     *
160
     * @return Element
161
     */
162 54
    public function setAttributes(array $attributes)
163
    {
164 54
        $this->attributes = $attributes;
165
166 54
        return $this;
167
    }
168
169
    /**
170
     * @param string $name
171
     * @param mixed  $value
172
     *
173
     * @return Element
174
     */
175 42
    public function setAttribute($name, $value)
176
    {
177 42
        $this->attributes[$name] = $value;
178
179 42
        return $this;
180
    }
181
182
    /**
183
     * @return bool true|false
184
     */
185 54
    public function hasAttributes()
186
    {
187 54
        return count($this->attributes) > 0;
188
    }
189
190
    /**
191
     * @return string
192
     */
193 54
    public function getNamespace()
194
    {
195 54
        return $this->namespace;
196
    }
197
198
    /**
199
     * @param string $namespace
200
     *
201
     * @return Element
202
     */
203 54
    public function setNamespace($namespace)
204
    {
205 54
        $this->namespace = $namespace;
206
207 54
        return $this;
208
    }
209
210
    /**
211
     * @return Element|string
212
     */
213 54
    public function getValue()
214
    {
215 54
        return $this->value;
216
    }
217
218
    /**
219
     * @param Element|string
220
     * @param mixed $value
221
     *
222
     * @return Element
223
     */
224 54
    public function setValue($value)
225
    {
226 54
        $this->value = $value;
227
228 54
        return $this;
229
    }
230
231
    /**
232
     * @return string
233
     */
234 48
    public function getNonceValue()
235
    {
236 48
        return $this->nonceValue;
237
    }
238
239
    /**
240
     * @param string $nonceValue
241
     *
242
     * @return Element
243
     */
244 54
    public function setNonceValue($nonceValue)
245
    {
246 54
        $this->nonceValue = $nonceValue;
247
248 54
        return $this;
249
    }
250
251
    /**
252
     * @param mixed $formated
253
     *
254
     * @return int|string
255
     */
256 54
    public function getTimestampValue($formated = false)
257
    {
258 54
        return ($formated && $this->timestampValue > 0) ? gmdate('Y-m-d\TH:i:s\Z', $this->timestampValue) : $this->timestampValue;
259
    }
260
261
    /**
262
     * @param int $timestampValue
263
     *
264
     * @return Element
265
     */
266 54
    public function setTimestampValue($timestampValue)
267
    {
268 54
        $this->timestampValue = $timestampValue;
269
270 54
        return $this;
271
    }
272
273
    /**
274
     * Returns the element to send as WS-Security header.
275
     *
276
     * @return string
277
     */
278 54
    public function toSend()
279
    {
280 54
        self::setDom(new \DOMDocument('1.0', 'UTF-8'));
281
282 54
        return $this->__toSend();
283
    }
284
285
    /**
286
     * Handle adding value to element according to the value type.
287
     *
288
     * @param mixed       $value
289
     * @param \DOMElement $element
290
     *
291
     * @return Element
292
     */
293 54
    protected function appendValueToElementToSend($value, \DOMElement $element)
294
    {
295 54
        if ($value instanceof Element) {
296 54
            $this->appendElementToElementToSend($value, $element);
297 54
        } elseif (is_array($value)) {
298 54
            $this->appendValuesToElementToSend($value, $element);
299 54
        } elseif (!empty($value)) {
300 54
            $element->appendChild(self::getDom()->createTextNode($value));
301 27
        }
302
303 54
        return $this;
304
    }
305
306
    /**
307
     * @param Element     $element
308
     * @param \DOMElement $element
309
     */
310 54
    protected function appendElementToElementToSend(Element $value, \DOMElement $element)
311
    {
312 54
        $toSend = $value->__toSend(true);
313 54
        if ($toSend instanceof \DOMElement) {
0 ignored issues
show
introduced by
$toSend is always a sub-type of DOMElement.
Loading history...
314 54
            $element->appendChild($toSend);
315 27
        }
316 54
    }
317
318
    /**
319
     * @param array       $values
320
     * @param \DOMElement $element
321
     */
322 54
    protected function appendValuesToElementToSend(array $values, \DOMElement $element)
323
    {
324 54
        foreach ($values as $value) {
325 54
            $this->appendValueToElementToSend($value, $element);
326 27
        }
327 54
    }
328
329
    /**
330
     * @param \DOMElement $element
331
     *
332
     * @return Element
333
     */
334 54
    protected function appendAttributesToElementToSend(\DOMElement $element)
335
    {
336 54
        if ($this->hasAttributes()) {
337 54
            foreach ($this->getAttributes() as $attributeName => $attributeValue) {
338 54
                $matches = [];
339 54
                if (0 === preg_match(sprintf('/(%s|%s):/', self::NS_WSSU_NAME, self::NS_WSSE_NAME), $attributeName, $matches)) {
340 54
                    $element->setAttribute($attributeName, $attributeValue);
341 27
                } else {
342 26
                    $element->setAttributeNS(self::NS_WSSE_NAME === $matches[1] ? self::NS_WSSE : self::NS_WSSU, $attributeName, $attributeValue);
343
                }
344 27
            }
345 27
        }
346
347 54
        return $this;
348
    }
349
350
    /**
351
     * Returns the name with its namespace.
352
     *
353
     * @return string
354
     */
355 54
    protected function getNamespacedName()
356
    {
357 54
        return sprintf('%s:%s', $this->getNamespacePrefix(), $this->getName());
358
    }
359
360
    /**
361
     * @return string
362
     */
363 54
    private function getNamespacePrefix()
364
    {
365 54
        $namespacePrefix = '';
366 54
        switch ($this->getNamespace()) {
367 54
            case self::NS_WSSE:
368 54
                $namespacePrefix = self::NS_WSSE_NAME;
369 54
                break;
370 54
            case self::NS_WSSU:
371 54
                $namespacePrefix = self::NS_WSSU_NAME;
372 54
                break;
373 27
        }
374
375 54
        return $namespacePrefix;
376
    }
377
378
    /**
379
     * @return \DOMDocument
380
     */
381 54
    private static function getDom()
382
    {
383 54
        return self::$dom;
384
    }
385
386
    /**
387
     * @param \DOMDocument $dom
388
     *
389
     * @return \DOMDocument
390
     */
391 54
    private static function setDom(\DOMDocument $dom)
392
    {
393 54
        self::$dom = $dom;
394 54
    }
395
}
396