Completed
Push — master ( 35728e...5c8980 )
by Gareth
03:35
created

Type::getNonNullItems()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6.2163

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
ccs 9
cts 11
cp 0.8182
rs 8.8571
cc 6
eloc 8
nc 6
nop 1
crap 6.2163
1
<?php
2
/**
3
 * Contains \garethp\ews\API\Type.
4
 */
5
6
namespace garethp\ews\API;
7
8
use garethp\ews\Caster;
9
10
/**
11
 * Base class for Exchange Web Service Types.
12
 *
13
 * @package php-ews\Type
14
 */
15
class Type
16
{
17
    use MagicMethodsTrait;
18
19
    /**
20
     * @var string
21
     */
22
    public $_ = '';
23
24
    public $_value = null;
25
26 25
    public function getNonNullItems($includeHiddenValue = false)
27
    {
28 25
        $items = get_object_vars($this);
29
30 25
        foreach ($items as $key => $item) {
31 25
            if (substr($key, 0, 1) == "_" || $item === null) {
32 25
                unset($items[$key]);
33 25
            }
34 25
        }
35
36 25
        if ($includeHiddenValue && $this->_value !== null) {
37
            $items['_value'] = $this->_value;
38
        }
39
40 25
        return $items;
41
    }
42
43
    /**
44
     * @param $array
45
     * @return static
46
     */
47 30
    public static function buildFromArray($array)
48
    {
49 30
        if (!is_array($array)) {
50 2
            return $array;
51
        }
52
53 30
        if (!self::arrayIsAssoc($array)) {
54 15
            return self::buildArrayFromArray($array);
55
        } else {
56 30
            return self::buildObjectFromArray($array);
57
        }
58
    }
59
60 30
    protected static function buildObjectFromArray($array)
61
    {
62 30
        $object = new static();
63 30
        foreach ($array as $key => $value) {
64 30
            if (is_array($value)) {
65 26
                $value = self::buildFromArray($value);
66 26
            }
67
68
            //I think _value is a more expressive way to set string value, but Soap needs _
69 30
            if ($key === "_value") {
70 3
                $key = "_";
71 3
            }
72
73 30
            $object->$key = $value;
74 30
        }
75
76 30
        return $object;
77
    }
78
79 15
    public static function buildArrayFromArray($array)
80
    {
81 15
        foreach ($array as $key => $value) {
82 15
            $array[$key] = self::buildFromArray($value);
83 15
        }
84
85 15
        return $array;
86
    }
87
88 25
    public function toXmlObject()
89
    {
90 25
        $objectToReturn = new self();
91 25
        $objectToReturn->_ = (string) $this;
92
93 25
        $properties = $this->getNonNullItems(true);
94
95 25
        foreach ($properties as $name => $property) {
96
            //I think _value is a more expressive way to set string value, but Soap needs _
97 25
            if ($name == "_value") {
98
                $name = "_";
99
            }
100
101 25
            $name = ucfirst($name);
102 25
            $objectToReturn->$name = $this->propertyToXml($name, $property);
103 25
        }
104
105 25
        return $objectToReturn;
106
    }
107
108
    /**
109
     * @param $name
110
     * @param $property
111
     * @return array|Type|null
112
     */
113 25
    protected function propertyToXml($name, $property)
114
    {
115 25
        if (isset($this->_typeMap[lcfirst($name)])) {
116
            $property = $this->castToExchange($property, $this->_typeMap[lcfirst($name)]);
117
        }
118
119 25
        if ($property instanceof Type) {
120 25
            $property = $property->toXmlObject();
121 25
        }
122
123 25
        if (is_array($property) && $this->arrayIsAssoc($property)) {
124
            $property = $this->buildFromArray($property);
125
        }
126
127 25
        if (is_array($property)) {
128 13
            foreach ($property as $key => $value) {
129 13
                if ($value instanceof Type) {
130 13
                    $property[$key] = $value->toXmlObject();
131 13
                }
132 13
            }
133
134 13
            return $property;
135
        }
136
137 25
        return $property;
138
    }
139
140 35
    public static function arrayIsAssoc($array)
141
    {
142 35
        return (bool) count(array_filter(array_keys($array), 'is_string'));
143
    }
144
145
    /**
146
     * Clones any object properties on a type object when it is cloned. Allows
147
     * for a deep clone required when using object to represent data types when
148
     * making a SOAP call.
149
     */
150 1
    public function __clone()
151
    {
152
        // Iterate over all properties on the current object.
153 1
        foreach (get_object_vars($this) as $property => $value) {
154
            // If the value of the property is an object then clone it.
155 1
            if (is_object($value)) {
156 1
                $this->$property = clone $value;
157 1
            } elseif (is_array($value)) {
158
                // The value is an array that may use objects as values. Iterate
159
                // over the array and clone any values that are objects into a
160
                // new array.
161
                // For some reason, if we try to set $this->$property to an
162
                // empty array then update it as we go it ends up being empty.
163
                // If we use a new array that we then set as the value of
164
                // $this->$property all is well.
165 1
                $new_value = array();
166 1
                foreach ($value as $index => $array_value) {
167 1
                    $new_value[$index] = (is_object($array_value) ? clone $array_value : $array_value);
168 1
                }
169
170
                // Set the property to the new array.
171 1
                $this->$property = $new_value;
172 1
            }
173 1
        }
174 1
    }
175
176 30
    public function __toString()
177
    {
178 30
        if (!is_string($this->_)) {
179 4
            return '';
180
        }
181
182 26
        return $this->_;
183
    }
184
}
185