AbstractObject::exportValue()   C
last analyzed

Complexity

Conditions 15
Paths 26

Size

Total Lines 54
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 15.0092

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 15
eloc 29
c 1
b 1
f 0
nc 26
nop 1
dl 0
loc 54
rs 5.9166
ccs 28
cts 29
cp 0.9655
crap 15.0092

How to fix   Long Method    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 erasys\OpenApi\Spec\v3;
4
5
use ArrayAccess;
6
use erasys\OpenApi\Exceptions\ArrayKeyConflictException;
7
use erasys\OpenApi\Exceptions\UndefinedPropertyException;
8
use erasys\OpenApi\Exceptions\UnsupportedTypeException;
9
use erasys\OpenApi\ExtensionProperty;
10
use erasys\OpenApi\RawValue;
11
use Illuminate\Contracts\Support\Arrayable;
12
use Illuminate\Contracts\Support\Jsonable;
13
use JsonSerializable;
14
use stdClass;
15
use Symfony\Component\Yaml\Yaml;
16
17
/**
18
 * Base class for all Open API models.
19
 *
20
 * Note that defining or accessing properties dynamically is not supported by design
21
 * to avoid invalid schema generation. If you need to use specification extensions,
22
 * you can always extend the classes and add there your own properties.
23
 *
24
 */
25
abstract class AbstractObject implements ArrayAccess, Arrayable, Jsonable, JsonSerializable
26
{
27
    /**
28
     * @param array $properties
29
     */
30 132
    public function __construct(array $properties = [])
31
    {
32 132
        foreach ($properties as $k => $v) {
33 39
            $this->$k = $v;
34
        }
35 129
    }
36
37
    /**
38
     * @param string $name
39
     */
40 6
    final public function __get($name)
41
    {
42 6
        throw new UndefinedPropertyException(static::class . "::\${$name}", 1);
43
    }
44
45
    /**
46
     * @param string $name
47
     * @param mixed  $value
48
     */
49 9
    final public function __set($name, $value)
50
    {
51 9
        throw new UndefinedPropertyException(static::class . "::\${$name}", 2);
52
    }
53
54
    /**
55
     * @param string $offset
56
     *
57
     * @return bool
58
     */
59 6
    final public function offsetExists($offset)
60
    {
61 6
        return isset($this->$offset);
62
    }
63
64
    /**
65
     * @param string $offset
66
     *
67
     * @return mixed
68
     */
69 3
    final public function offsetGet($offset)
70
    {
71 3
        return $this->$offset;
72
    }
73
74
    /**
75
     * @param string $offset
76
     * @param mixed  $value
77
     */
78 3
    final public function offsetSet($offset, $value)
79
    {
80 3
        $this->$offset = $value;
81
    }
82
83
    /**
84
     * @param string $offset
85
     */
86 3
    final public function offsetUnset($offset)
87
    {
88 3
        unset($this->$offset);
89 3
    }
90
91
    /**
92
     * @param mixed $value
93
     *
94
     * @return array|mixed
95
     */
96 48
    private function exportValue($value)
97
    {
98 48
        if ($value instanceof RawValue) {
99
            // Unwrap value and return it raw, as it is.
100 3
            return $value->getValue();
101
        }
102
103 48
        if ($value instanceof AbstractObject) {
104 12
            return $value->toArray();
105
        }
106
107 48
        if ($value instanceof ExtensionProperty) {
108
            return [
109
                $value->getName() => $this->exportValue($value->getValue()),
110
            ];
111
        }
112
113 48
        if (is_array($value)) {
114 48
            $result = [];
115 48
            foreach ($value as $k => $v) {
116
                // Take key and value from extension property definition
117 48
                if ($v instanceof ExtensionProperty) {
118 3
                    $k = $v->getName();
119 3
                    $v = $this->exportValue($v->getValue());
120
                }
121
                // Ignore null properties
122 48
                if (is_null($v)) {
123 27
                    continue;
124
                }
125 48
                if (in_array($k, ['xml'])) {
126 3
                    $result[$k] = $this->exportValue($v);
127 3
                    continue;
128
                }
129
                // Transform extension property names using the 'x-respecT_caseFormat'
130 48
                if (preg_match('/^x/i', $k)) {
131 12
                    $k = 'x-' . preg_replace('/^(x[-]?)/i', '', str_replace('_', '-', $k));
132
                }
133
                // Transform reference property names
134 48
                if ($k === 'ref') {
135 3
                    $k = '$ref';
136
                }
137 48
                if (isset($result[$k])) {
138 3
                    throw new ArrayKeyConflictException($k);
139
                }
140 48
                $result[$k] = $this->exportValue($v);
141
            }
142 42
            return $result;
143
        }
144
145 48
        if (!is_null($value) && !is_scalar($value)) {
146 3
            throw new UnsupportedTypeException(is_object($value) ? get_class($value) : gettype($value));
147
        }
148
149 45
        return $value;
150
    }
151
152
    /**
153
     * @return array
154
     */
155
    public function toArray()
156
    {
157 48
        $vars = (function ($that) {
158
            // Only public variables
159 48
            return get_object_vars($that);
160 48
        })->bindTo(null, null)($this);
161
162 48
        return $this->exportValue($vars);
163
    }
164
165
    /**
166
     * @param int $options
167
     *
168
     * @return string
169
     */
170 15
    public function toJson($options = 0)
171
    {
172 15
        return json_encode($this, $options);
173
    }
174
175
    /**
176
     * Returns a plain object
177
     *
178
     * @return object|stdClass
179
     */
180 9
    public function toObject(): stdClass
181
    {
182 9
        return json_decode($this->toJson());
183
    }
184
185
    /**
186
     * @param int $inline
187
     * @param int $indentation
188
     * @param int $flags
189
     * @return string
190
     */
191 3
    public function toYaml(
192
        int $inline = 10,
193
        int $indentation = 2,
194
        int $flags = 0
195
    ): string {
196 3
        return Yaml::dump($this->toArray(), $inline, $indentation, $flags);
197
    }
198
199
    /**
200
     * Returns a value that is suitable for JSON serialization,
201
     * in order to be able to export empty objects correctly, so they
202
     * won't be treated as empty arrays.
203
     *
204
     * @return array|stdClass
205
     */
206 15
    public function jsonSerialize()
207
    {
208 15
        $properties = $this->toArray();
209 15
        return empty($properties) ? new stdClass() : $properties;
210
    }
211
212 3
    public function __toString()
213
    {
214 3
        return $this->toJson();
215
    }
216
}
217