GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#56)
by Arthur
01:15
created

DataTransferObject::getPublicProperties()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spatie\DataTransferObject;
6
7
use ReflectionClass;
8
use ReflectionProperty;
9
10
/**
11
 * Class DataTransferObject.
12
 */
13
abstract class DataTransferObject implements DtoContract
14
{
15
    /** @var array */
16
    protected $exceptKeys = [];
17
18
    /** @var array */
19
    protected $onlyKeys = [];
20
21
    /** @var Property[] | array */
22
    protected $properties = [];
23
24
    /** @var bool */
25
    protected $immutable;
26
27
    public static function mutable(array $parameters): DtoContract
28
    {
29
        return new static($parameters, false);
30
    }
31
32
    public static function immutable(array $parameters): DtoContract
33
    {
34
        return new static($parameters, true);
35
    }
36
37
    public function __construct(array $parameters, bool $immutable = true)
38
    {
39
        $this->immutable = $immutable;
40
        $this->boot($parameters);
41
    }
42
43
    /**
44
     * Boot the dto and process all parameters.
45
     * @param array $parameters
46
     * @throws \ReflectionException | DataTransferObjectError
47
     */
48
    protected function boot(array $parameters): void
49
    {
50
        foreach ($this->getPublicProperties() as $property) {
51
52
            /*
53
             * Do not change the order of the following methods.
54
             * External packages rely on this order.
55
             */
56
57
            $this->setPropertyDefaultValue($property);
58
59
            $property = $this->mutateProperty($property);
60
61
            $this->validateProperty($property, $parameters);
62
63
            $this->setPropertyValue($property, $parameters);
64
65
            /* add the property to an associative array with the name as key */
66
            $this->properties[$property->getName()] = $property;
67
68
            /* remove the property from the parameters array  */
69
            unset($parameters[$property->getName()]);
70
71
            /* remove the property from the value object  */
72
            unset($this->{$property->getName()});
73
        }
74
75
        $this->processRemainingProperties($parameters);
76
    }
77
78
    /**
79
     * Get all public properties from the current object through reflection.
80
     * @return Property[]
81
     * @throws \ReflectionException
82
     */
83
    protected function getPublicProperties(): array
84
    {
85
        $class = new ReflectionClass(static::class);
86
        $properties = [];
87
        foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $reflectionProperty) {
88
            $properties[$reflectionProperty->getName()] = Property::fromReflection($reflectionProperty);
89
        }
90
91
        return $properties;
92
    }
93
94
    /**
95
     * Check if property passes the basic conditions.
96
     * @param Property $property
97
     * @param array $parameters
98
     */
99
    protected function validateProperty($property, array $parameters): void
100
    {
101
        if (! array_key_exists($property->getName(), $parameters)
102
            && is_null($property->getDefault())
103
            && ! $property->isNullable()
104
        ) {
105
            throw DataTransferObjectError::uninitialized($property);
106
        }
107
    }
108
109
    /**
110
     * Set the value if it's present in the array.
111
     * @param Property $property
112
     * @param array $parameters
113
     */
114
    protected function setPropertyValue($property, array $parameters): void
115
    {
116
        if (array_key_exists($property->getName(), $parameters)) {
117
            $property->set($parameters[$property->getName()]);
118
        }
119
    }
120
121
    /**
122
     * Set the value if it's present in the array.
123
     * @param Property $property
124
     * @param array $parameters
0 ignored issues
show
Bug introduced by
There is no parameter named $parameters. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
125
     */
126
    protected function setPropertyDefaultValue($property): void
127
    {
128
        $property->setDefault($property->getValueFromReflection($this));
129
    }
130
131
    /**
132
     * Allows to mutate the property before it gets processed.
133
     * @param Property $property
134
     * @param array $parameters
0 ignored issues
show
Bug introduced by
There is no parameter named $parameters. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
135
     * @return Property
136
     */
137
    protected function mutateProperty($property)
138
    {
139
        return $property;
140
    }
141
142
    /**
143
     * Check if there are additional parameters left.
144
     * Throw error if there are.
145
     * Additional properties are not allowed in a dto.
146
     * @throws DataTransferObjectError
147
     */
148
    protected function processRemainingProperties(array $parameters)
149
    {
150
        if (count($parameters)) {
151
            throw DataTransferObjectError::unknownProperties(array_keys($parameters), static::class);
152
        }
153
    }
154
155
    /**
156
     * Immutable behavior
157
     * Throw error if a user tries to set a property.
158
     * @param $name
159
     * @param $value
160
     * @Throws DataTransferObjectError
161
     */
162
    public function __set($name, $value)
163
    {
164
        if ($this->immutable) {
165
            throw DataTransferObjectError::immutable($name);
166
        }
167
        $this->$name = $value;
168
    }
169
170
    /**
171
     * Proxy through to the properties array.
172
     * @param $name
173
     * @return mixed
174
     */
175
    public function __get($name)
176
    {
177
        return $this->properties[$name]->getValue();
178
    }
179
180
    public function all(): array
181
    {
182
        $data = [];
183
184
        foreach ($this->properties as $property) {
185
            $data[$property->getName()] = $property->getValue();
186
        }
187
188
        return $data;
189
    }
190
191
    public function only(string ...$keys): DtoContract
192
    {
193
        $this->onlyKeys = array_merge($this->onlyKeys, $keys);
194
195
        return $this;
196
    }
197
198
    public function except(string ...$keys): DtoContract
199
    {
200
        $this->exceptKeys = array_merge($this->exceptKeys, $keys);
201
202
        return $this;
203
    }
204
205
    public function toArray(): array
206
    {
207
        if (count($this->onlyKeys)) {
208
            $array = Arr::only($this->all(), $this->onlyKeys);
209
        } else {
210
            $array = Arr::except($this->all(), $this->exceptKeys);
211
        }
212
213
        $array = $this->parseArray($array);
214
215
        return $array;
216
    }
217
218
    protected function parseArray(array $array): array
219
    {
220
        foreach ($array as $key => $value) {
221
            if (
222
                $value instanceof DataTransferObject
223
                || $value instanceof DataTransferObjectCollection
224
            ) {
225
                $array[$key] = $value->toArray();
226
227
                continue;
228
            }
229
230
            if (! is_array($value)) {
231
                continue;
232
            }
233
234
            $array[$key] = $this->parseArray($value);
235
        }
236
237
        return $array;
238
    }
239
}
240