Passed
Push — feature/issue-7 ( a99ccc...b4cb71 )
by Mikaël
02:41
created

Element::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 7
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
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 54
     *
77
     * @var \DOMDocument
78 27
     */
79 54
    protected static $dom = null;
80 54
81 54
    /**
82 54
     * Generic constructor.
83 54
     *
84
     * @param string $name
85
     * @param string $namespace
86
     * @param mixed  $value
87 54
     * @param array  $attributes
88
     */
89 54
    public function __construct($name, $namespace, $value = null, array $attributes = [])
90
    {
91
        $this
92
            ->setName($name)
93
            ->setNamespace($namespace)
94
            ->setValue($value)
95 54
            ->setAttributes($attributes)
96
        ;
97 54
    }
98 54
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 54
     *
104
     * @return \DOMElement|string
105 54
     */
106
    protected function __toSend($asDomElement = false)
107
    {
108
        /**
109
         * Create element tag.
110
         */
111 54
        $element = self::getDom()->createElement($this->getNamespacedName());
112
        $element->setAttributeNS('http://www.w3.org/2000/xmlns/', sprintf('xmlns:%s', $this->getNamespacePrefix()), $this->getNamespace());
113 54
        /*
114 54
         * Define element value
115
         * Add attributes if there are any
116
         */
117
        $this
118
            ->appendValueToElementToSend($this->getValue(), $element)
119
            ->appendAttributesToElementToSend($element)
120
        ;
121 42
        // Returns element content
122
        if ($asDomElement) {
123 42
            return $element;
124 42
        }
125
126
        return self::getDom()->saveXML($element);
127
    }
128
129 54
    /**
130
     * @return string
131 54
     */
132
    public function getName()
133
    {
134
        return $this->name;
135
    }
136 54
137
    /**
138 54
     * @param string $name
139
     *
140
     * @return Element
141
     */
142
    public function setName($name)
143 54
    {
144
        $this->name = $name;
145 54
146 54
        return $this;
147 54
    }
148 54
149 54
    /**
150 54
     * @return array
151 54
     */
152 54
    public function getAttributes()
153 27
    {
154 54
        return $this->attributes;
155
    }
156
157
    /**
158
     * @param array $attributes
159
     *
160 54
     * @return Element
161
     */
162 54
    public function setAttributes(array $attributes)
163 54
    {
164
        $this->attributes = $attributes;
165
166
        return $this;
167
    }
168 54
169
    /**
170 54
     * @param string $name
171
     * @param mixed  $value
172
     *
173
     * @return Element
174
     */
175
    public function setAttribute($name, $value)
176 54
    {
177
        $this->attributes[$name] = $value;
178 54
179 54
        return $this;
180
    }
181
182
    /**
183
     * @return bool true|false
184 48
     */
185
    public function hasAttributes()
186 48
    {
187
        return count($this->attributes) > 0;
188
    }
189
190
    /**
191
     * @return string
192 54
     */
193
    public function getNamespace()
194 54
    {
195 54
        return $this->namespace;
196
    }
197
198
    /**
199
     * @param string $namespace
200 54
     *
201
     * @return Element
202 54
     */
203
    public function setNamespace($namespace)
204
    {
205
        $this->namespace = $namespace;
206
207
        return $this;
208 54
    }
209
210 54
    /**
211 54
     * @return Element|string
212
     */
213
    public function getValue()
214
    {
215
        return $this->value;
216 54
    }
217
218 54
    /**
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 54
228
        return $this;
229
    }
230
231
    /**
232
     * @return string
233 54
     */
234
    public function getNonceValue()
235
    {
236
        return $this->nonceValue;
237
    }
238 54
239 54
    /**
240
     * @param string $nonceValue
241
     *
242
     * @return Element
243
     */
244 27
    public function setNonceValue($nonceValue)
245 54
    {
246 54
        $this->nonceValue = $nonceValue;
247
248
        return $this;
249
    }
250 54
251 54
    /**
252
     * @param mixed $formated
253 54
     *
254
     * @return int|string
255
     */
256
    public function getTimestampValue($formated = false)
257
    {
258
        return ($formated && $this->timestampValue > 0) ? gmdate('Y-m-d\TH:i:s\Z', $this->timestampValue) : $this->timestampValue;
259
    }
260
261
    /**
262 54
     * @param int $timestampValue
263
     *
264 54
     * @return Element
265 54
     */
266 54
    public function setTimestampValue($timestampValue)
267 54
    {
268 54
        $this->timestampValue = $timestampValue;
269 54
270 27
        return $this;
271 54
    }
272
273
    /**
274
     * Returns the element to send as WS-Security header.
275
     *
276
     * @return string
277 54
     */
278
    public function toSend()
279 54
    {
280 54
        self::setDom(new \DOMDocument('1.0', 'UTF-8'));
281 54
282 27
        return $this->__toSend();
283 54
    }
284
285
    /**
286
     * Handle adding value to element according to the value type.
287
     *
288 54
     * @param mixed       $value
289
     * @param \DOMElement $element
290 54
     *
291 54
     * @return Element
292 27
     */
293 54
    protected function appendValueToElementToSend($value, \DOMElement $element)
294
    {
295
        if ($value instanceof Element) {
296
            $this->appendElementToElementToSend($value, $element);
297
        } elseif (is_array($value)) {
298 54
            $this->appendValuesToElementToSend($value, $element);
299
        } elseif (!empty($value)) {
300 54
            $element->appendChild(self::getDom()->createTextNode($value));
301 54
        }
302 54
303 27
        return $this;
304 27
    }
305 54
306
    /**
307
     * @param Element     $element
308
     * @param \DOMElement $element
309
     */
310
    protected function appendElementToElementToSend(Element $value, \DOMElement $element)
311 54
    {
312
        $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
            $element->appendChild($toSend);
315
        }
316
    }
317
318
    /**
319 54
     * @param array       $values
320
     * @param \DOMElement $element
321 54
     */
322 54
    protected function appendValuesToElementToSend(array $values, \DOMElement $element)
323
    {
324
        foreach ($values as $value) {
325
            $this->appendValueToElementToSend($value, $element);
326
        }
327
    }
328
329
    /**
330
     * @param \DOMElement $element
331
     *
332
     * @return Element
333
     */
334
    protected function appendAttributesToElementToSend(\DOMElement $element)
335
    {
336
        if ($this->hasAttributes()) {
337
            foreach ($this->getAttributes() as $attributeName => $attributeValue) {
338
                if (false === strpos($attributeName, ':')) {
339
                    $element->setAttribute($attributeName, $attributeValue);
340
                } else {
341
                    list($ns, $name) = explode(':', $attributeName);
342
                    if (self::NS_WSSE_NAME === $ns || self::NS_WSSU_NAME === $ns) {
343
                        $element->setAttributeNS(self::NS_WSSE_NAME === $ns ? self::NS_WSSE : self::NS_WSSU, $attributeName, $attributeValue);
344
                    } else {
345
                        $element->setAttribute($attributeName, $attributeValue);
346
                    }
347
                }
348
            }
349
        }
350
351
        return $this;
352
    }
353
354
    /**
355
     * Returns the name with its namespace.
356
     *
357
     * @return string
358
     */
359
    protected function getNamespacedName()
360
    {
361
        return sprintf('%s:%s', $this->getNamespacePrefix(), $this->getName());
362
    }
363
364
    /**
365
     * @return string
366
     */
367
    private function getNamespacePrefix()
368
    {
369
        $namespacePrefix = '';
370
        switch ($this->getNamespace()) {
371
            case self::NS_WSSE:
372
                $namespacePrefix = self::NS_WSSE_NAME;
373
                break;
374
            case self::NS_WSSU:
375
                $namespacePrefix = self::NS_WSSU_NAME;
376
                break;
377
        }
378
379
        return $namespacePrefix;
380
    }
381
382
    /**
383
     * @return \DOMDocument
384
     */
385
    private static function getDom()
386
    {
387
        return self::$dom;
388
    }
389
390
    /**
391
     * @param \DOMDocument $dom
392
     *
393
     * @return \DOMDocument
394
     */
395
    private static function setDom(\DOMDocument $dom)
396
    {
397
        self::$dom = $dom;
398
    }
399
}
400