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 (#55)
by Arthur
02:05
created

DataTransferObject::boot()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 47
rs 7.6008
c 0
b 0
f 0
cc 9
nc 12
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
 * @package Spatie\DataTransferObject
13
 */
14
abstract class DataTransferObject
15
{
16
    /** @var array */
17
    protected $exceptKeys = [];
18
19
    /** @var array */
20
    protected $onlyKeys = [];
21
22
    /** @var Property[] | array */
23
    protected $properties = [];
24
25
    /** @var bool */
26
    protected $immutable;
27
28
    /**
29
     * @param array $parameters
30
     *
31
     * @return \Spatie\DataTransferObject\ImmutableDataTransferObject|static
32
     */
33
    public static function mutable(array $parameters): self
34
    {
35
        return new static($parameters, false);
36
    }
37
38
    /**
39
     * @param array $parameters
40
     *
41
     * @return \Spatie\DataTransferObject\ImmutableDataTransferObject|static
42
     */
43
    public static function immutable(array $parameters): self
44
    {
45
        return new static($parameters, true);
46
    }
47
48
    /**
49
     * DataTransferObject constructor.
50
     * @param array $parameters
51
     */
52
    final public function __construct(array $parameters, $immutable = true)
53
    {
54
        $this->immutable = $immutable;
55
        $this->boot($parameters);
56
    }
57
58
    /**
59
     * @param array $parameters
60
     */
61
    protected function boot(array $parameters): void
62
    {
63
        foreach ($this->getPublicProperties() as $property) {
64
65
            /* Setting the default value of the property */
66
            $property->setDefault($property->getValue($this));
67
68
            /* If a attribute method is set on the dto process it */
69
            if (method_exists($this, $method = $property->getName())) {
70
                $property = $this->$method(new Attribute($property))->getProperty();
71
            }
72
73
            /* Check if property passes the basic conditions */
74
            if (!array_key_exists($property->getName(), $parameters)
75
                && $property->isRequired()
76
                && is_null($property->getDefault())
77
                && !$property->isNullable()
78
            ) {
79
                throw DataTransferObjectError::uninitialized($property);
80
            }
81
82
            /* set the value if it's present in the array and mark it as uninitialized otherwise */
83
            if (array_key_exists($property->getName(), $parameters)) {
84
                $property->set($parameters[$property->getName()]);
85
            } else {
86
                $property->setUninitialized();
87
            }
88
89
            /* add the property to an associative array with the name as key */
90
            $this->properties[$property->getName()] = $property;
91
92
            /* remove the property from the parameters array  */
93
            unset($parameters[$property->getName()]);
94
            /* remove the property from the dto  */
95
            unset($this->{$property->getName()});
96
        }
97
98
        /* Check if there are additional parameters left.
99
         * Throw error if there are.
100
         * Additional properties are not allowed in a dto.
101
         */
102
        if (count($parameters)) {
103
            throw DataTransferObjectError::unknownProperties(array_keys($parameters), static::class);
104
        }
105
106
        $this->validate();
107
    }
108
109
    /**
110
     *
111
     */
112
    protected function validate()
113
    {
114
        //IMPLEMENT VALIDATION FUNCTIONALITY CHECK THE RULES & CONSTRAINTS
115
    }
116
117
118
    /**
119
     * @return array
120
     */
121
    public function all(): array
122
    {
123
        $data = [];
124
125
        foreach ($this->properties as $property) {
126
            $data[$property->getName()] = $property->getActualValue();
0 ignored issues
show
Documentation Bug introduced by
The method getName does not exist on object<Spatie\DataTransferObject\Property>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
127
        }
128
129
        return $data;
130
    }
131
132
    /**
133
     * Immutable behavior
134
     * Throw error if a user tries to set a property
135
     * @param $name
136
     * @param $value
137
     * @Throws DataTransferObjectError
138
     */
139
    public function __set($name, $value)
140
    {
141
        if ($this->immutable)
142
            throw DataTransferObjectError::immutable($name);
143
    }
144
145
    /**
146
     * Proxy through to the properties array
147
     * @param $name
148
     * @return mixed
149
     */
150
    public function __get($name)
151
    {
152
        return $this->properties[$name]->getActualValue();
153
    }
154
155
    /**
156
     * @param string ...$keys
157
     *
158
     * @return static
159
     */
160
    public function only(string ...$keys): DataTransferObject
161
    {
162
        $valueObject = clone $this;
163
164
        $valueObject->onlyKeys = array_merge($this->onlyKeys, $keys);
165
166
        return $valueObject;
167
    }
168
169
    /**
170
     * @param string ...$keys
171
     *
172
     * @return static
173
     */
174
    public function except(string ...$keys): DataTransferObject
175
    {
176
        $valueObject = clone $this;
177
178
        $valueObject->exceptKeys = array_merge($this->exceptKeys, $keys);
179
180
        return $valueObject;
181
    }
182
183
    /**
184
     * @return array
185
     */
186
    public function toArray(): array
187
    {
188
        if (count($this->onlyKeys)) {
189
            $array = Arr::only($this->all(), $this->onlyKeys);
190
        } else {
191
            $array = Arr::except($this->all(), $this->exceptKeys);
192
        }
193
194
        $array = $this->parseArray($array);
195
196
        return $array;
197
    }
198
199
    /**
200
     * @param array $array
201
     * @return array
202
     */
203
    protected function parseArray(array $array): array
204
    {
205
        foreach ($array as $key => $value) {
206
            if (
207
                $value instanceof DataTransferObject
208
                || $value instanceof DataTransferObjectCollection
209
            ) {
210
                $array[$key] = $value->toArray();
211
212
                continue;
213
            }
214
215
            if (!is_array($value)) {
216
                continue;
217
            }
218
219
            $array[$key] = $this->parseArray($value);
220
        }
221
222
        return $array;
223
    }
224
225
    /**
226
     * @param \ReflectionClass $class
0 ignored issues
show
Bug introduced by
There is no parameter named $class. 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...
227
     *
228
     * @return array|\Spatie\DataTransferObject\Property[]
229
     */
230
    protected function getPublicProperties(): array
231
    {
232
        $class = new ReflectionClass(static::class);
233
        $properties = [];
234
        foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $reflectionProperty) {
235
            $properties[$reflectionProperty->getName()] = Property::fromReflection($this, $reflectionProperty);
236
        }
237
238
        return $properties;
239
    }
240
241
}
242