NativeParser::parse()   C
last analyzed

Complexity

Conditions 15
Paths 44

Size

Total Lines 49
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 0
Metric Value
dl 0
loc 49
ccs 0
cts 42
cp 0
rs 5.1257
c 0
b 0
f 0
cc 15
eloc 30
nc 44
nop 1
crap 240

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 Fxmlrpc\Serialization\Parser;
4
5
use Fxmlrpc\Serialization\Exception\FaultException;
6
use Fxmlrpc\Serialization\Exception\ParserException;
7
use Fxmlrpc\Serialization\Parser;
8
use Fxmlrpc\Serialization\Value\Base64Value;
9
use Fxmlrpc\Serialization\XmlChecker;
10
11
/**
12
 * Parser to parse XML responses into its PHP representation using XML RPC extension.
13
 *
14
 * @author Lars Strojny <[email protected]>
15
 */
16
final class NativeParser implements Parser
17
{
18
    const LIBXML_PARSEHUGE_THRESHOLD = 1024 * 1024 * 10;
19
20
    /**
21
     * @var bool
22
     */
23
    private $validateResponse;
24
25
    /**
26
     * @param bool $validateResponse
27
     */
28
    public function __construct($validateResponse = true)
29
    {
30
        $this->validateResponse = $validateResponse;
31
    }
32
33
    /**
34
     * Check whether a given string is over the parse limit.
35
     *
36
     * @param string $xmlString
37
     *
38
     * @return bool
39
     */
40
    public static function isBiggerThanParseLimit($xmlString)
41
    {
42
        return strlen($xmlString) > static::LIBXML_PARSEHUGE_THRESHOLD;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function parse($xmlString)
49
    {
50
        if ($this->validateResponse) {
51
            XmlChecker::isValid($xmlString);
52
        }
53
54
        $result = xmlrpc_decode($xmlString, 'UTF-8');
55
56
        if ($result === null && self::isBiggerThanParseLimit($xmlString)) {
57
            throw ParserException::xmlrpcExtensionLibxmlParsehugeNotSupported();
58
        }
59
60
        $toBeVisited = [&$result];
61
        while (isset($toBeVisited[0]) && $value = &$toBeVisited[0]) {
62
            $type = gettype($value);
63
            if ($type === 'object') {
64
                $xmlRpcType = $value->{'xmlrpc_type'};
65
                if ($xmlRpcType === 'datetime') {
66
                    $value = \DateTime::createFromFormat(
67
                        'Ymd\TH:i:s',
68
                        $value->scalar,
69
                        isset($timezone) ? $timezone : $timezone = new \DateTimeZone('UTC')
70
                    );
71
                } elseif ($xmlRpcType === 'base64') {
72
                    if ($value->scalar !== '') {
73
                        $value = Base64Value::serialize($value->scalar);
74
                    } else {
75
                        $value = null;
76
                    }
77
                }
78
            } elseif ($type === 'array') {
79
                foreach ($value as &$element) {
80
                    $toBeVisited[] = &$element;
81
                }
82
            }
83
84
            array_shift($toBeVisited);
85
        }
86
87
        if (is_array($result)) {
88
            reset($result);
89
90
            if (xmlrpc_is_fault($result)) {
91
                throw FaultException::createFromResponse($result);
92
            }
93
        }
94
95
        return $result;
96
    }
97
}
98