Completed
Pull Request — 23 (#431)
by Harald
10:27
created

Generator::_createElementsFromArray()   D

Complexity

Conditions 10
Paths 7

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 25
nc 7
nop 2
dl 0
loc 37
rs 4.8196
c 0
b 0
f 0

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
namespace Braintree\Xml;
3
4
use DateTime;
5
use DateTimeZone;
6
use XMLWriter;
7
use Braintree\Util;
8
9
/**
10
 * PHP version 5
11
 *
12
 * @copyright  2015 Braintree, a division of PayPal, Inc.
13
 */
14
15
/**
16
 * Generates XML output from arrays using PHP's
17
 * built-in XMLWriter
18
 *
19
 * @copyright  2015 Braintree, a division of PayPal, Inc.
20
 */
21
class Generator
22
{
23
    /**
24
     * arrays passed to this method should have a single root element
25
     * with an array as its value
26
     * @param array $aData the array of data
27
     * @return string XML string
28
     */
29
    public static function arrayToXml($aData)
30
    {
31
        $aData = Util::camelCaseToDelimiterArray($aData, '-');
32
        // set up the XMLWriter
33
        $writer = new XMLWriter();
34
        $writer->openMemory();
35
36
        $writer->setIndent(true);
37
        $writer->setIndentString(' ');
38
        $writer->startDocument('1.0', 'UTF-8');
39
40
        // get the root element name
41
        $aKeys = array_keys($aData);
42
        $rootElementName = $aKeys[0];
43
        // open the root element
44
        $writer->startElement($rootElementName);
45
        // create the body
46
        self::_createElementsFromArray($writer, $aData[$rootElementName], $rootElementName);
0 ignored issues
show
Unused Code introduced by
The call to Generator::_createElementsFromArray() has too many arguments starting with $rootElementName.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
47
48
        // close the root element and document
49
        $writer->endElement();
50
        $writer->endDocument();
51
52
        // send the output as string
53
        return $writer->outputMemory();
54
    }
55
56
    /**
57
     * Construct XML elements with attributes from an associative array.
58
     *
59
     * @access protected
60
     * @static
61
     * @param object $writer XMLWriter object
62
     * @param array $aData contains attributes and values
63
     * @return void
64
     */
65
    private static function _createElementsFromArray(&$writer, $aData)
66
    {
67
        if (!is_array($aData)) {
68
            if (is_bool($aData)) {
69
                $writer->text($aData ? 'true' : 'false');
70
            } else {
71
                $writer->text($aData);
72
            }
73
          return;
74
        }
75
        foreach ($aData AS $elementName => $element) {
76
            // handle child elements
77
            $writer->startElement($elementName);
78
            if (is_array($element)) {
79
                if (array_key_exists(0, $element) || empty($element)) {
80
                    $writer->writeAttribute('type', 'array');
81
                    foreach ($element AS $ignored => $itemInArray) {
82
                        $writer->startElement('item');
83
                        self::_createElementsFromArray($writer, $itemInArray);
84
                        $writer->endElement();
85
                    }
86
                }
87
                else {
88
                    self::_createElementsFromArray($writer, $element);
89
                }
90
            } else {
91
                // generate attributes as needed
92
                $attribute = self::_generateXmlAttribute($element);
93
                if (is_array($attribute)) {
94
                    $writer->writeAttribute($attribute[0], $attribute[1]);
95
                    $element = $attribute[2];
96
                }
97
                $writer->text($element);
98
            }
99
            $writer->endElement();
100
        }
101
    }
102
103
    /**
104
     * convert passed data into an array of attributeType, attributeName, and value
105
     * dates sent as DateTime objects will be converted to strings
106
     * @access protected
107
     * @param mixed $value
108
     * @return array attributes and element value
109
     */
110
    private static function _generateXmlAttribute($value)
111
    {
112
        if ($value instanceof DateTime) {
113
            return ['type', 'datetime', self::_dateTimeToXmlTimestamp($value)];
114
        }
115
        if (is_int($value)) {
116
            return ['type', 'integer', $value];
117
        }
118
        if (is_bool($value)) {
119
            return ['type', 'boolean', ($value ? 'true' : 'false')];
120
        }
121
        if ($value === NULL) {
122
            return ['nil', 'true', $value];
123
        }
124
    }
125
    /**
126
     * converts datetime back to xml schema format
127
     * @access protected
128
     * @param object $dateTime
129
     * @return string XML schema formatted timestamp
130
     */
131
    private static function _dateTimeToXmlTimestamp($dateTime)
132
    {
133
        $dateTimeForUTC = clone $dateTime;
134
135
        $dateTimeForUTC->setTimeZone(new DateTimeZone('UTC'));
136
        return ($dateTimeForUTC->format('Y-m-d\TH:i:s') . 'Z');
137
    }
138
139
    private static function _castDateTime($string)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
140
    {
141
        try {
142
            if (empty($string)) {
143
               return false;
144
            }
145
            $dateTime = new DateTime($string);
146
            return self::_dateTimeToXmlTimestamp($dateTime);
147
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class Braintree\Xml\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
148
            // not a datetime
149
            return false;
150
        }
151
    }
152
}
153
class_alias('Braintree\Xml\Generator', 'Braintree_Xml_Generator');
154