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:56
created

DataTransferObject::__get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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
28
    public static function mutable(array $parameters): DtoContract
29
    {
30
        return new static($parameters, false);
31
    }
32
33
34
    public static function immutable(array $parameters): DtoContract
35
    {
36
        return new static($parameters, true);
37
    }
38
39
40
    public function __construct(array $parameters, bool $immutable = true)
41
    {
42
        $this->immutable = $immutable;
43
        $this->boot($parameters);
44
    }
45
46
    /**
47
     * Boot the dto and process all parameters
48
     * @param array $parameters
49
     * @throws \ReflectionException | DataTransferObjectError
50
     */
51
    protected function boot(array $parameters): void
52
    {
53
        foreach ($this->getPublicProperties() as $property) {
54
55
            /**
56
             * Do not change the order of the following methods.
57
             * External packages rely on this order.
58
             */
59
60
            $this->setPropertyDefaultValue($property);
61
62
            $property = $this->mutateProperty($property);
63
64
            $this->validateProperty($property, $parameters);
65
66
            $this->setPropertyValue($property, $parameters);
67
68
            /* add the property to an associative array with the name as key */
69
            $this->properties[$property->getName()] = $property;
70
71
            /* remove the property from the parameters array  */
72
            unset($parameters[$property->getName()]);
73
74
            /* remove the property from the value object  */
75
            unset($this->{$property->getName()});
76
        }
77
78
79
        $this->processRemainingProperties($parameters);
80
    }
81
82
    /**
83
     * Get all public properties from the current object through reflection
84
     * @return Property[]
85
     * @throws \ReflectionException
86
     */
87
    protected function getPublicProperties(): array
88
    {
89
        $class = new ReflectionClass(static::class);
90
        $properties = [];
91
        foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $reflectionProperty) {
92
            $properties[$reflectionProperty->getName()] = Property::fromReflection($reflectionProperty);
93
        }
94
95
        return $properties;
96
    }
97
98
    /**
99
     * Check if property passes the basic conditions
100
     * @param Property $property
101
     * @param array $parameters
102
     */
103 View Code Duplication
    protected function validateProperty($property, array $parameters): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
    {
105
        if (!array_key_exists($property->getName(), $parameters)
106
            && is_null($property->getDefault())
107
            && !$property->isNullable()
108
        ) {
109
            throw DataTransferObjectError::uninitialized($property);
110
        }
111
    }
112
113
    /**
114
     * Set the value if it's present in the array
115
     * @param Property $property
116
     * @param array $parameters
117
     */
118
    protected function setPropertyValue($property, array $parameters): void
119
    {
120
        if (array_key_exists($property->getName(), $parameters)) {
121
            $property->set($parameters[$property->getName()]);
122
        }
123
    }
124
125
    /**
126
     * Set the value if it's present in the array
127
     * @param Property $property
128
     * @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...
129
     */
130
    protected function setPropertyDefaultValue($property): void
131
    {
132
        $property->setDefault($property->getValueFromReflection($this));
133
    }
134
135
    /**
136
     * Allows to mutate the property before it gets processed
137
     * @param Property $property
138
     * @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...
139
     * @return Property
140
     */
141
    protected function mutateProperty($property)
142
    {
143
        return $property;
144
    }
145
146
147
    /**
148
     * Check if there are additional parameters left.
149
     * Throw error if there are.
150
     * Additional properties are not allowed in a dto.
151
     * @throws DataTransferObjectError
152
     */
153
    protected function processRemainingProperties(array $parameters)
154
    {
155
        if (count($parameters)) {
156
            throw DataTransferObjectError::unknownProperties(array_keys($parameters), static::class);
157
        }
158
    }
159
160
    /**
161
     * Immutable behavior
162
     * Throw error if a user tries to set a property.
163
     * @param $name
164
     * @param $value
165
     * @Throws DataTransferObjectError
166
     */
167
    public function __set($name, $value)
168
    {
169
        if ($this->immutable) {
170
            throw DataTransferObjectError::immutable($name);
171
        }
172
        $this->$name = $value;
173
    }
174
175
    /**
176
     * Proxy through to the properties array.
177
     * @param $name
178
     * @return mixed
179
     */
180
    public function __get($name)
181
    {
182
        return $this->properties[$name]->getValue();
183
    }
184
185
    public function all(): array
186
    {
187
        $data = [];
188
189
        foreach ($this->properties as $property) {
190
            $data[$property->getName()] = $property->getValue();
191
        }
192
193
        return $data;
194
    }
195
196
    public function only(string ...$keys): DtoContract
197
    {
198
        $this->onlyKeys = array_merge($this->onlyKeys, $keys);
199
200
        return $this;
201
    }
202
203
    public function except(string ...$keys): DtoContract
204
    {
205
        $this->exceptKeys = array_merge($this->exceptKeys, $keys);
206
207
        return $this;
208
    }
209
210
    public function toArray(): array
211
    {
212
        if (count($this->onlyKeys)) {
213
            $array = Arr::only($this->all(), $this->onlyKeys);
214
        } else {
215
            $array = Arr::except($this->all(), $this->exceptKeys);
216
        }
217
218
        $array = $this->parseArray($array);
219
220
        return $array;
221
    }
222
223
    protected function parseArray(array $array): array
224
    {
225
        foreach ($array as $key => $value) {
226
            if (
227
                $value instanceof DataTransferObject
228
                || $value instanceof DataTransferObjectCollection
229
            ) {
230
                $array[$key] = $value->toArray();
231
232
                continue;
233
            }
234
235
            if (!is_array($value)) {
236
                continue;
237
            }
238
239
            $array[$key] = $this->parseArray($value);
240
        }
241
242
        return $array;
243
    }
244
}
245