Completed
Push — master ( 5b0125...766181 )
by Svilen
01:05 queued 10s
created

DataTransferObject::isReservedPropertyName()   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 Codebooth\DataTransferObject;
6
7
namespace CodeBooth\DataTransferObject;
8
9
use CodeBooth\DataTransferObject\Exceptions\DataException;
10
use ReflectionClass;
11
use ReflectionProperty;
12
13
abstract class DataTransferObject
14
{
15
    /**
16
     * Array of casts to be performed. Keys are attribute names, values are type casts.
17
     *
18
     * @var array
19
     */
20
    public $casts = [];
21
22
    /**
23
     * DataTransferObject constructor.
24
     *
25
     * @param array $attributes
26
     *
27
     * @throws \ReflectionException
28
     * @throws \CodeBooth\DataTransferObject\Exceptions\DataException
29
     */
30
    public function __construct(array $attributes)
31
    {
32
        $class = new ReflectionClass(static::class);
33
34
        $properties = $this->getProperties($class);
35
36
        foreach ($properties as $property) {
37
            $propertyName = $property->getName();
38
39
            if ($this->isReservedPropertyName($property->getName())) {
40
                continue;
41
            }
42
43
            if (! isset($attributes[$propertyName])) {
44
                throw new DataException("Property `{$property->getName()}` has not been initialized");
45
            }
46
47
            $property->value($attributes[$propertyName] ?? $property->getValue());
48
49
            unset($attributes[$propertyName]);
50
        }
51
52
        if (! empty($attributes)) {
53
            throw new DataException('No mapping properties provided');
54
        }
55
    }
56
57
    /**
58
     * Returns list of all properties and their value.
59
     *
60
     * @return array
61
     * @throws \ReflectionException
62
     */
63
    public function all()
64
    {
65
        $data = [];
66
67
        $class = new ReflectionClass(static::class);
68
69
        $properties = $class->getProperties(ReflectionProperty::IS_PUBLIC);
70
71
        foreach ($properties as $reflectionProperty) {
72
            if ($this->isReservedPropertyName($reflectionProperty->getName())) {
73
                continue;
74
            }
75
76
            $data[$reflectionProperty->getName()] = $reflectionProperty->getValue($this);
77
        }
78
79
        return $data;
80
    }
81
82
    /**
83
     * @param \ReflectionClass $class
84
     *
85
     * @return array|\CodeBooth\DataTransferObject\Property[]
86
     * @throws \ReflectionException
87
     */
88
    protected function getProperties(ReflectionClass $class)
89
    {
90
        $properties = [];
91
92
        foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
93
            $properties[$property->getName()] = new Property($this, $property);
94
        }
95
96
        return $properties;
97
    }
98
99
    /**
100
     * Check if the property name is reserved.
101
     *
102
     * @param string $propertyName
103
     *
104
     * @return bool
105
     */
106
    protected function isReservedPropertyName(string $propertyName)
107
    {
108
        return in_array($propertyName, ['casts']);
109
    }
110
}
111