Passed
Push — master ( 526b0d...b337d2 )
by Gaetano
04:53
created

Value::__construct()   C

Complexity

Conditions 15
Paths 14

Size

Total Lines 32
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 15.0102

Importance

Changes 4
Bugs 1 Features 0
Metric Value
cc 15
eloc 28
c 4
b 1
f 0
nc 14
nop 2
dl 0
loc 32
rs 5.9166
ccs 27
cts 28
cp 0.9643
crap 15.0102

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PhpXmlRpc;
4
5
use PhpXmlRpc\Helper\Charset;
6
use PhpXmlRpc\Helper\Logger;
7
8
/**
9
 * This class enables the creation of values for XML-RPC, by encapsulating plain php values.
10
 */
11
class Value implements \Countable, \IteratorAggregate, \ArrayAccess
12
{
13
    public static $xmlrpcI4 = "i4";
14
    public static $xmlrpcI8 = "i8";
15
    public static $xmlrpcInt = "int";
16
    public static $xmlrpcBoolean = "boolean";
17
    public static $xmlrpcDouble = "double";
18
    public static $xmlrpcString = "string";
19
    public static $xmlrpcDateTime = "dateTime.iso8601";
20
    public static $xmlrpcBase64 = "base64";
21
    public static $xmlrpcArray = "array";
22
    public static $xmlrpcStruct = "struct";
23
    public static $xmlrpcValue = "undefined";
24
    public static $xmlrpcNull = "null";
25
26
    public static $xmlrpcTypes = array(
27
        "i4" => 1,
28
        "i8" => 1,
29
        "int" => 1,
30
        "boolean" => 1,
31
        "double" => 1,
32
        "string" => 1,
33
        "dateTime.iso8601" => 1,
34
        "base64" => 1,
35
        "array" => 2,
36
        "struct" => 3,
37
        "null" => 1,
38
    );
39
40
    protected static $logger;
41
    protected static $charsetEncoder;
42
43
    /// @todo: do these need to be public?
44
    /** @var Value[]|mixed */
45
    public $me = array();
46
    /**
47
     * @var int $mytype
48
     * @internal
49
     */
50
    public $mytype = 0;
51
    /** @var string|null $_php_class */
52
    public $_php_class = null;
53
54 1
    public function getLogger()
55
    {
56 1
        if (self::$logger === null) {
57 1
            self::$logger = Logger::instance();
58
        }
59 1
        return self::$logger;
60
    }
61
62
    public static function setLogger($logger)
63
    {
64
        self::$logger = $logger;
65
    }
66
67 499
    public function getCharsetEncoder()
68
    {
69 499
        if (self::$charsetEncoder === null) {
70 375
            self::$charsetEncoder = Charset::instance();
71
        }
72 499
        return self::$charsetEncoder;
73
    }
74
75
    public function setCharsetEncoder($charsetEncoder)
76
    {
77
        self::$charsetEncoder = $charsetEncoder;
78
    }
79
80
    /**
81
     * Build an xmlrpc value.
82
     *
83
     * When no value or type is passed in, the value is left uninitialized, and the value can be added later.
84
     *
85
     * @param Value[]|mixed $val if passing in an array, all array elements should be PhpXmlRpc\Value themselves
86
     * @param string $type any valid xmlrpc type name (lowercase): i4, int, boolean, string, double, dateTime.iso8601,
87
     *                     base64, array, struct, null.
88
     *                     If null, 'string' is assumed.
89
     *                     You should refer to http://www.xmlrpc.com/spec for more information on what each of these mean.
90
     */
91 638
    public function __construct($val = -1, $type = '')
92
    {
93
        // optimization creep - do not call addXX, do it all inline.
94
        // downside: booleans will not be coerced anymore
95 638
        if ($val !== -1 || $type != '') {
96 637
            switch ($type) {
97 637
                case '':
98 208
                    $this->mytype = 1;
99 208
                    $this->me['string'] = $val;
100 208
                    break;
101 637
                case 'i4':
102 637
                case 'i8':
103 637
                case 'int':
104 596
                case 'double':
105 577
                case 'string':
106 406
                case 'boolean':
107 387
                case 'dateTime.iso8601':
108 367
                case 'base64':
109 348
                case 'null':
110 613
                    $this->mytype = 1;
111 613
                    $this->me[$type] = $val;
112 613
                    break;
113 347
                case 'array':
114 218
                    $this->mytype = 2;
115 218
                    $this->me['array'] = $val;
116 218
                    break;
117 249
                case 'struct':
118 249
                    $this->mytype = 3;
119 249
                    $this->me['struct'] = $val;
120 249
                    break;
121
                default:
122
                    $this->getLogger()->errorLog("XML-RPC: " . __METHOD__ . ": not a known type ($type)");
123
            }
124
        }
125 638
    }
126
127
    /**
128
     * Add a single php value to an xmlrpc value.
129
     *
130
     * If the xmlrpc value is an array, the php value is added as its last element.
131
     * If the xmlrpc value is empty (uninitialized), this method makes it a scalar value, and sets that value.
132
     * Fails if the xmlrpc value is not an array and already initialized.
133
     *
134
     * @param mixed $val
135
     * @param string $type allowed values: i4, i8, int, boolean, string, double, dateTime.iso8601, base64, null.
136
     *
137
     * @return int 1 or 0 on failure
138
     */
139 1
    public function addScalar($val, $type = 'string')
140
    {
141 1
        $typeOf = null;
142 1
        if (isset(static::$xmlrpcTypes[$type])) {
143 1
            $typeOf = static::$xmlrpcTypes[$type];
144
        }
145
146 1
        if ($typeOf !== 1) {
147
            $this->getLogger()->errorLog("XML-RPC: " . __METHOD__ . ": not a scalar type ($type)");
148
            return 0;
149
        }
150
151
        // coerce booleans into correct values
152
        // NB: we should either do it for datetimes, integers, i8 and doubles, too,
153
        // or just plain remove this check, implemented on booleans only...
154 1
        if ($type == static::$xmlrpcBoolean) {
155
            if (strcasecmp($val, 'true') == 0 || $val == 1 || ($val == true && strcasecmp($val, 'false'))) {
156
                $val = true;
157
            } else {
158
                $val = false;
159
            }
160
        }
161
162 1
        switch ($this->mytype) {
163 1
            case 1:
164
                $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': scalar xmlrpc value can have only one value');
165
                return 0;
166 1
            case 3:
167 1
                $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': cannot add anonymous scalar to struct xmlrpc value');
168 1
                return 0;
169
            case 2:
170
                // we're adding a scalar value to an array here
171
                $this->me['array'][] = new Value($val, $type);
172
173
                return 1;
174
            default:
175
                // a scalar, so set the value and remember we're scalar
176
                $this->me[$type] = $val;
177
                $this->mytype = $typeOf;
178
179
                return 1;
180
        }
181
    }
182
183
    /**
184
     * Add an array of xmlrpc value objects to an xmlrpc value.
185
     *
186
     * If the xmlrpc value is an array, the elements are appended to the existing ones.
187
     * If the xmlrpc value is empty (uninitialized), this method makes it an array value, and sets that value.
188
     * Fails otherwise.
189
     *
190
     * @param Value[] $values
191
     *
192
     * @return int 1 or 0 on failure
193
     *
194
     * @todo add some checking for $values to be an array of xmlrpc values?
195
     */
196 1
    public function addArray($values)
197
    {
198 1
        if ($this->mytype == 0) {
199
            $this->mytype = static::$xmlrpcTypes['array'];
200
            $this->me['array'] = $values;
201
202
            return 1;
203 1
        } elseif ($this->mytype == 2) {
204
            // we're adding to an array here
205 1
            $this->me['array'] = array_merge($this->me['array'], $values);
206
207 1
            return 1;
208
        } else {
209
            $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': already initialized as a [' . $this->kindOf() . ']');
210
            return 0;
211
        }
212
    }
213
214
    /**
215
     * Merges an array of named xmlrpc value objects into an xmlrpc value.
216
     *
217
     * If the xmlrpc value is a struct, the elements are merged with the existing ones (overwriting existing ones).
218
     * If the xmlrpc value is empty (uninitialized), this method makes it a struct value, and sets that value.
219
     * Fails otherwise.
220
     *
221
     * @param Value[] $values
222
     *
223
     * @return int 1 or 0 on failure
224
     *
225
     * @todo add some checking for $values to be an array?
226
     */
227 1
    public function addStruct($values)
228
    {
229 1
        if ($this->mytype == 0) {
230
            $this->mytype = static::$xmlrpcTypes['struct'];
231
            $this->me['struct'] = $values;
232
233
            return 1;
234 1
        } elseif ($this->mytype == 3) {
235
            // we're adding to a struct here
236 1
            $this->me['struct'] = array_merge($this->me['struct'], $values);
237
238 1
            return 1;
239
        } else {
240
            $this->getLogger()->errorLog('XML-RPC: ' . __METHOD__ . ': already initialized as a [' . $this->kindOf() . ']');
241
            return 0;
242
        }
243
    }
244
245
    /**
246
     * Returns a string containing either "struct", "array", "scalar" or "undef", describing the base type of the value.
247
     *
248
     * @return string
249
     */
250 549
    public function kindOf()
251
    {
252 549
        switch ($this->mytype) {
253 549
            case 3:
254 136
                return 'struct';
255 530
            case 2:
256 193
                return 'array';
257 510
            case 1:
258 510
                return 'scalar';
259
            default:
260
                return 'undef';
261
        }
262
    }
263
264
    /**
265
     * @param string typ
0 ignored issues
show
Bug introduced by
The type PhpXmlRpc\typ was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
266
     * @param Value[]|mixed $val
267
     * @param string $charsetEncoding
268
     * @return string
269
     */
270 599
    protected function serializedata($typ, $val, $charsetEncoding = '')
271
    {
272 599
        $rs = '';
273
274 599
        if (!isset(static::$xmlrpcTypes[$typ])) {
275 2
            return $rs;
276
        }
277
278 599
        switch (static::$xmlrpcTypes[$typ]) {
279 599
            case 1:
280
                switch ($typ) {
281 580
                    case static::$xmlrpcBase64:
282 21
                        $rs .= "<${typ}>" . base64_encode($val) . "</${typ}>";
0 ignored issues
show
Bug introduced by
It seems like $val can also be of type PhpXmlRpc\Value[]; however, parameter $string of base64_encode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

282
                        $rs .= "<${typ}>" . base64_encode(/** @scrutinizer ignore-type */ $val) . "</${typ}>";
Loading history...
283 21
                        break;
284 580
                    case static::$xmlrpcBoolean:
285 41
                        $rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
286 41
                        break;
287 561
                    case static::$xmlrpcString:
288
                        // Do NOT use htmlentities, since it will produce named html entities, which are invalid xml
289 480
                        $rs .= "<${typ}>" . $this->getCharsetEncoder()->encodeEntities($val, PhpXmlRpc::$xmlrpc_internalencoding, $charsetEncoding) . "</${typ}>";
290 480
                        break;
291 409
                    case static::$xmlrpcInt:
292 60
                    case static::$xmlrpcI4:
293 60
                    case static::$xmlrpcI8:
294 370
                        $rs .= "<${typ}>" . (int)$val . "</${typ}>";
295 370
                        break;
296 60
                    case static::$xmlrpcDouble:
297
                        // avoid using standard conversion of float to string because it is locale-dependent,
298
                        // and also because the xmlrpc spec forbids exponential notation.
299
                        // sprintf('%F') could be most likely ok but it fails eg. on 2e-14.
300
                        // The code below tries its best at keeping max precision while avoiding exp notation,
301
                        // but there is of course no limit in the number of decimal places to be used...
302 21
                        $rs .= "<${typ}>" . preg_replace('/\\.?0+$/', '', number_format((double)$val, PhpXmlRpc::$xmlpc_double_precision, '.', '')) . "</${typ}>";
303 21
                        break;
304 41
                    case static::$xmlrpcDateTime:
305 21
                        if (is_string($val)) {
306 21
                            $rs .= "<${typ}>${val}</${typ}>";
307 20
                        } elseif (is_a($val, 'DateTime')) {
308 20
                            $rs .= "<${typ}>" . $val->format('Ymd\TH:i:s') . "</${typ}>";
309 20
                        } elseif (is_int($val)) {
310 20
                            $rs .= "<${typ}>" . strftime("%Y%m%dT%H:%M:%S", $val) . "</${typ}>";
311
                        } else {
312
                            // not really a good idea here: but what shall we output anyway? left for backward compat...
313
                            $rs .= "<${typ}>${val}</${typ}>";
314
                        }
315 21
                        break;
316 21
                    case static::$xmlrpcNull:
317 21
                        if (PhpXmlRpc::$xmlrpc_null_apache_encoding) {
318 21
                            $rs .= "<ex:nil/>";
319
                        } else {
320 1
                            $rs .= "<nil/>";
321
                        }
322 21
                        break;
323
                    default:
324
                        // no standard type value should arrive here, but provide a possibility
325
                        // for xmlrpc values of unknown type...
326
                        $rs .= "<${typ}>${val}</${typ}>";
327
                }
328 580
                break;
329 197
            case 3:
330
                // struct
331 120
                if ($this->_php_class) {
332 1
                    $rs .= '<struct php_class="' . $this->_php_class . "\">\n";
333
                } else {
334 120
                    $rs .= "<struct>\n";
335
                }
336 120
                $charsetEncoder = $this->getCharsetEncoder();
337
                /** @var Value $val2 */
338 120
                foreach ($val as $key2 => $val2) {
339 101
                    $rs .= '<member><name>' . $charsetEncoder->encodeEntities($key2, PhpXmlRpc::$xmlrpc_internalencoding, $charsetEncoding) . "</name>\n";
340
                    //$rs.=$this->serializeval($val2);
341 101
                    $rs .= $val2->serialize($charsetEncoding);
342 101
                    $rs .= "</member>\n";
343
                }
344 120
                $rs .= '</struct>';
345 120
                break;
346 139
            case 2:
347
                // array
348 139
                $rs .= "<array>\n<data>\n";
349
                /** @var Value $element */
350 139
                foreach ($val as $element) {
351
                    //$rs.=$this->serializeval($val[$i]);
352 139
                    $rs .= $element->serialize($charsetEncoding);
353
                }
354 139
                $rs .= "</data>\n</array>";
355 139
                break;
356
            default:
357
                break;
358
        }
359
360 599
        return $rs;
361
    }
362
363
    /**
364
     * Returns the xml representation of the value. XML prologue not included.
365
     *
366
     * @param string $charsetEncoding the charset to be used for serialization. if null, US-ASCII is assumed
367
     *
368
     * @return string
369
     */
370 599
    public function serialize($charsetEncoding = '')
371
    {
372 599
        $val = reset($this->me);
373 599
        $typ = key($this->me);
374
375 599
        return '<value>' . $this->serializedata($typ, $val, $charsetEncoding) . "</value>\n";
376
    }
377
378
    /**
379
     * Checks whether a struct member with a given name is present.
380
     *
381
     * Works only on xmlrpc values of type struct.
382
     *
383
     * @param string $key the name of the struct member to be looked up
384
     *
385
     * @return boolean
386
     *
387
     * @deprecated use array access, e.g. isset($val[$key])
388
     */
389 2
    public function structmemexists($key)
390
    {
391
        //trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
392
393 2
        return array_key_exists($key, $this->me['struct']);
394
    }
395
396
    /**
397
     * Returns the value of a given struct member (an xmlrpc value object in itself).
398
     * Will raise a php warning if struct member of given name does not exist.
399
     *
400
     * @param string $key the name of the struct member to be looked up
401
     *
402
     * @return Value
403
     *
404
     * @deprecated use array access, e.g. $val[$key]
405
     */
406 27
    public function structmem($key)
407
    {
408
        //trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
409
410 27
        return $this->me['struct'][$key];
411
    }
412
413
    /**
414
     * Reset internal pointer for xmlrpc values of type struct.
415
     * @deprecated iterate directly over the object using foreach instead
416
     */
417
    public function structreset()
418
    {
419
        //trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
420
421
        reset($this->me['struct']);
422
    }
423
424
    /**
425
     * Return next member element for xmlrpc values of type struct.
426
     *
427
     * @return Value
428
     * @throws \Error starting with php 8.0, this function should not be used, as it will always throw
429
     *
430
     * @deprecated iterate directly over the object using foreach instead
431
     */
432
    public function structeach()
433
    {
434
        //trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
435
436
        return @each($this->me['struct']);
0 ignored issues
show
Bug Best Practice introduced by
The expression return @each($this->me['struct']) returns the type array which is incompatible with the documented return type PhpXmlRpc\Value.
Loading history...
437
    }
438
439
    /**
440
     * Returns the value of a scalar xmlrpc value (base 64 decoding is automatically handled here)
441
     *
442
     * @return mixed
443
     */
444 562
    public function scalarval()
445
    {
446 562
        $b = reset($this->me);
447
448 562
        return $b;
449
    }
450
451
    /**
452
     * Returns the type of the xmlrpc value.
453
     *
454
     * For integers, 'int' is always returned in place of 'i4'. 'i8' is considered a separate type and returned as such
455
     *
456
     * @return string
457
     */
458 393
    public function scalartyp()
459
    {
460 393
        reset($this->me);
461 393
        $a = key($this->me);
462 393
        if ($a == static::$xmlrpcI4) {
463
            $a = static::$xmlrpcInt;
464
        }
465
466 393
        return $a;
467
    }
468
469
    /**
470
     * Returns the m-th member of an xmlrpc value of array type.
471
     *
472
     * @param integer $key the index of the value to be retrieved (zero based)
473
     *
474
     * @return Value
475
     *
476
     * @deprecated use array access, e.g. $val[$key]
477
     */
478 39
    public function arraymem($key)
479
    {
480
        //trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
481
482 39
        return $this->me['array'][$key];
483
    }
484
485
    /**
486
     * Returns the number of members in an xmlrpc value of array type.
487
     *
488
     * @return integer
489
     *
490
     * @deprecated use count() instead
491
     */
492 40
    public function arraysize()
493
    {
494
        //trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
495
496 40
        return count($this->me['array']);
497
    }
498
499
    /**
500
     * Returns the number of members in an xmlrpc value of struct type.
501
     *
502
     * @return integer
503
     *
504
     * @deprecated use count() instead
505
     */
506 21
    public function structsize()
507
    {
508
        //trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
509
510 21
        return count($this->me['struct']);
511
    }
512
513
    /**
514
     * Returns the number of members in an xmlrpc value:
515
     * - 0 for uninitialized values
516
     * - 1 for scalar values
517
     * - the number of elements for struct and array values
518
     *
519
     * @return integer
520
     */
521 22
    public function count()
522
    {
523 22
        switch ($this->mytype) {
524 22
            case 3:
525
                return count($this->me['struct']);
526 22
            case 2:
527 22
                return count($this->me['array']);
528
            case 1:
529
                return 1;
530
            default:
531
                return 0;
532
        }
533
    }
534
535
    /**
536
     * Implements the IteratorAggregate interface
537
     *
538
     * @return \ArrayIterator
539
     * @internal required to be public to implement an Interface
540
     */
541 233
    public function getIterator()
542
    {
543 233
        switch ($this->mytype) {
544 233
            case 3:
545 59
                return new \ArrayIterator($this->me['struct']);
546 194
            case 2:
547 194
                return new \ArrayIterator($this->me['array']);
548
            case 1:
549
                return new \ArrayIterator($this->me);
550
            default:
551
                return new \ArrayIterator();
552
        }
553
    }
554
555
    /**
556
     * @internal required to be public to implement an Interface
557
     * @param mixed $offset
558
     * @param mixed $value
559
     * @throws \Exception
560
     */
561 20
    public function offsetSet($offset, $value)
562
    {
563 20
        switch ($this->mytype) {
564 20
            case 3:
565
                if (!($value instanceof \PhpXmlRpc\Value)) {
566
                    throw new \Exception('It is only possible to add Value objects to an XML-RPC Struct');
567
                }
568
                if (is_null($offset)) {
569
                    // disallow struct members with empty names
570
                    throw new \Exception('It is not possible to add anonymous members to an XML-RPC Struct');
571
                } else {
572
                    $this->me['struct'][$offset] = $value;
573
                }
574
                return;
575 20
            case 2:
576 20
                if (!($value instanceof \PhpXmlRpc\Value)) {
577
                    throw new \Exception('It is only possible to add Value objects to an XML-RPC Array');
578
                }
579 20
                if (is_null($offset)) {
580 20
                    $this->me['array'][] = $value;
581
                } else {
582
                    // nb: we are not checking that $offset is above the existing array range...
583
                    $this->me['array'][$offset] = $value;
584
                }
585 20
                return;
586
            case 1:
587
// todo: handle i4 vs int
588
                reset($this->me);
589
                $type = key($this->me);
590
                if ($type != $offset) {
591
                    throw new \Exception('');
592
                }
593
                $this->me[$type] = $value;
594
                return;
595
            default:
596
                // it would be nice to allow empty values to be be turned into non-empty ones this way, but we miss info to do so
597
                throw new \Exception("XML-RPC Value is of type 'undef' and its value can not be set using array index");
598
        }
599
    }
600
601
    /**
602
     * @internal required to be public to implement an Interface
603
     * @param mixed $offset
604
     * @return bool
605
     */
606
    public function offsetExists($offset)
607
    {
608
        switch ($this->mytype) {
609
            case 3:
610
                return isset($this->me['struct'][$offset]);
611
            case 2:
612
                return isset($this->me['array'][$offset]);
613
            case 1:
614
// todo: handle i4 vs int
615
                return $offset == $this->scalartyp();
616
            default:
617
                return false;
618
        }
619
    }
620
621
    /**
622
     * @internal required to be public to implement an Interface
623
     * @param mixed $offset
624
     * @throws \Exception
625
     */
626
    public function offsetUnset($offset)
627
    {
628
        switch ($this->mytype) {
629
            case 3:
630
                unset($this->me['struct'][$offset]);
631
                return;
632
            case 2:
633
                unset($this->me['array'][$offset]);
634
                return;
635
            case 1:
636
                // can not remove value from a scalar
637
                throw new \Exception("XML-RPC Value is of type 'scalar' and its value can not be unset using array index");
638
            default:
639
                throw new \Exception("XML-RPC Value is of type 'undef' and its value can not be unset using array index");
640
        }
641
    }
642
643
    /**
644
     * @internal required to be public to implement an Interface
645
     * @param mixed $offset
646
     * @return mixed|Value|null
647
     * @throws \Exception
648
     */
649 139
    public function offsetGet($offset)
650
    {
651 139
        switch ($this->mytype) {
652 139
            case 3:
653 138
                return isset($this->me['struct'][$offset]) ? $this->me['struct'][$offset] : null;
654 21
            case 2:
655 21
                return isset($this->me['array'][$offset]) ? $this->me['array'][$offset] : null;
656
            case 1:
657
// on bad type: null or exception?
658
                $value = reset($this->me);
659
                $type = key($this->me);
660
                return $type == $offset ? $value : null;
661
            default:
662
// return null or exception?
663
                throw new \Exception("XML-RPC Value is of type 'undef' and can not be accessed using array index");
664
        }
665
    }
666
}
667