Completed
Push — master ( 72ab76...096673 )
by Stéphane
11:37
created

Entity::__get()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 2
b 0
f 0
nc 4
nop 1
dl 0
loc 16
ccs 8
cts 8
cp 1
crap 4
rs 9.2
1
<?php namespace Rocket\Entities;
2
3
use InvalidArgumentException;
4
use RuntimeException;
5
6
/**
7
 * Entity manager
8
 *
9
 * @property int $id The content ID
10
 * @property int $language_id The language in which this entity is
11
 * @property-read \DateTime $created_at
12
 * @property-read \DateTime $updated_at
13
 */
14
abstract class Entity
15
{
16
    public static $types;
17
18
    /**
19
     * The content represented by this entity
20
     *
21
     * @var Content
22
     */
23
    protected $content; //id, created_at
24
25
    /**
26
     * The revision represented by this entity
27
     *
28
     * @var Revision
29
     */
30
    protected $revision; //language_id, updated_at
31
32
    /**
33
     * The fields in this entity
34
     *
35
     * @var array<FieldCollection>
36
     */
37
    protected $data;
38
39 39
    public function __construct($data = [])
40
    {
41 39
        $fields = $this->getFields();
42
43 39
        $this->initialize($fields);
44
45 33
        if ($data !== null) {
46 33
            $this->hydrate($data);
47 33
        }
48 33
    }
49
50 39
    protected function initialize(array $fields)
51
    {
52 39
        $this->content = new Content;
53 39
        $this->revision = new Revision;
54
55 39
        foreach ($fields as $field => $settings) {
56 36
            $this->data[$field] = $this->initializeField($field, $settings);
57 33
        }
58 33
    }
59
60 36
    protected function initializeField($field, $settings)
61
    {
62 36
        if ($this->isContentField($field) || $this->isRevisionField($field)) {
63 3
            throw new InvalidArgumentException(
64 3
                "The field '$field' cannot be used in '" . get_class($this) . "' as it is a reserved name"
65 3
            );
66
        }
67
68 33
        $type = $settings['type'];
69
70 33
        if (!array_key_exists($type, self::$types)) {
71 3
            throw new RuntimeException("Unkown type '$type' in '" . get_class($this) . "'");
72
        }
73
74 30
        $settings['type'] = self::$types[$settings['type']];
75
76 30
        return FieldCollection::initField($settings);
77
    }
78
79 33
    protected function hydrate($data)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
80
    {
81
        //TODO :: populate data
82 33
    }
83
84
    abstract protected function getFields();
85
86
    /**
87
     * Create a new revision based on the same content ID but without the content.
88
     * Very useful if you want to add a new language
89
     *
90
     * @param int $language_id
91
     * @return static
92
     */
93 3
    public function newRevision($language_id = null)
94
    {
95 3
        $created = new static();
96 3
        $created->content = $this->content;
97
98 3
        if ($language_id !== null) {
99 3
            $created->language_id = $language_id;
100 3
        }
101
102 3
        return $created;
103
    }
104
105
    /**
106
     * Check if the field is related to the content
107
     *
108
     * @param string $field
109
     * @return bool
110
     */
111 36
    protected function isContentField($field)
112
    {
113 36
        return in_array($field, ['id', 'created_at']);
114
    }
115
116
    /**
117
     * Check if the field exists on the entity
118
     *
119
     * @param string $field
120
     * @return bool
121
     */
122 24
    public function hasField($field)
123
    {
124 24
        return array_key_exists($field, $this->data);
125
    }
126
127
    /**
128
     * @param string $field
129
     * @return FieldCollection
130
     */
131 18
    public function getField($field)
132
    {
133 18
        return $this->data[$field];
134
    }
135
136
    /**
137
     * Check if the field is related to the revision
138
     *
139
     * @param string $field
140
     * @return bool
141
     */
142 33
    protected function isRevisionField($field)
143
    {
144 33
        return in_array($field, ['language_id', 'updated_at']);
145
    }
146
147
    /**
148
     * Dynamically retrieve attributes on the model.
149
     *
150
     * @param string $key
151
     * @throws RuntimeException
152
     * @return $this|bool|\Carbon\Carbon|\DateTime|mixed|static
153
     */
154 24
    public function __get($key)
155
    {
156 24
        if ($this->isContentField($key)) {
157 3
            return $this->content->getAttribute($key);
158
        }
159
160 24
        if ($this->isRevisionField($key)) {
161 6
            return $this->revision->getAttribute($key);
162
        }
163
164 21
        if ($this->hasField($key)) {
165 18
            return $this->getField($key);
166
        }
167
168 3
        throw new RuntimeException("Field '$key' doesn't exist in '" . get_class($this) . "'");
169
    }
170
171
    /**
172
     * Dynamically set attributes on the model.
173
     *
174
     * @param string $key
175
     * @param mixed $value
176
     * @throws RuntimeException
177
     */
178 18
    public function __set($key, $value)
179
    {
180 18
        if ($this->isContentField($key)) {
181 3
            $this->content->setAttribute($key, $value);
182
183 3
            return;
184
        }
185
186 18
        if ($this->isRevisionField($key)) {
187 12
            $this->revision->setAttribute($key, $value);
188
189 12
            return;
190
        }
191
192 15
        if ($this->hasField($key)) {
193 12
            if ($value == []) {
194 9
                $this->getField($key)->clear();
195
196 9
                return;
197
            }
198
199 3
            $this->getField($key)->offsetSet(0, $value);
200
201 3
            return;
202
        }
203
204 3
        throw new RuntimeException("Field '$key' doesn't exist in '" . get_class($this) . "'");
205
    }
206
207
    /**
208
     * Convert the Entity to an array.
209
     *
210
     * @return array
211
     */
212
    public function toArray()
213
    {
214
        $content = [];
215
216
        $content['_content'] = $this->content->toArray();
217
        $content['_revision'] = $this->revision->toArray();
218
219
        foreach ($this->data as $field => $data) {
220
            $content[$field] = $data->toArray();
221
        }
222
223
        return $content;
224
    }
225
}
226