Model   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 257
rs 10
c 0
b 0
f 0
wmc 22

14 Methods

Rating   Name   Duplication   Size   Complexity  
A fill() 0 12 3
A create() 0 5 1
A getAliasedObject() 0 3 1
A query() 0 3 1
A meta() 0 9 2
A __call() 0 5 1
A __get() 0 20 4
A objectAliases() 0 3 1
A setObject() 0 5 1
A __set() 0 7 2
A __isset() 0 3 1
A make() 0 7 2
A __callStatic() 0 3 1
A setId() 0 5 1
1
<?php
2
3
namespace Silk\Type;
4
5
use Silk\Meta\ObjectMeta;
6
7
/**
8
 * @property-read int    $id
9
 * @property-read object $object
10
 */
11
abstract class Model
12
{
13
    use ObjectAliases;
14
15
    /**
16
     * The core model object
17
     * @var object
18
     */
19
    protected $object;
20
21
    /**
22
     * The object type in WordPress
23
     */
24
    const OBJECT_TYPE = '';
25
26
    /**
27
     * The name of the primary ID property on the object
28
     */
29
    const ID_PROPERTY = '';
30
31
    /**
32
     * Get a new query builder for the model.
33
     *
34
     * @return \Silk\Query\Builder
35
     */
36
    abstract public function newQuery();
37
38
    /**
39
     * Save the changes to the database.
40
     *
41
     * @return $this
42
     */
43
    abstract public function save();
44
45
    /**
46
     * Delete the modeled record from the database.
47
     *
48
     * @return $this
49
     */
50
    abstract public function delete();
51
52
    /**
53
     * Reload the object from the database.
54
     *
55
     * @return $this
56
     */
57
    abstract public function refresh();
58
59
    /**
60
     * Make new instance.
61
     *
62
     * All provided arguments are forwarded to the constructor of the called class.
63
     *
64
     * @throws \ReflectionException
65
     *
66
     * @return object|Model
67
     */
68
    public static function make()
69
    {
70
        if ($arguments = func_get_args()) {
71
            return (new \ReflectionClass(static::class))->newInstanceArgs($arguments);
72
        }
73
74
        return new static;
75
    }
76
77
    /**
78
     * Fill the model with an array of attributes.
79
     *
80
     * @param  array  $attributes
81
     *
82
     * @return $this
83
     */
84
    public function fill(array $attributes)
85
    {
86
        foreach ($attributes as $key => $value) {
87
            if ($this->expandAlias($key)) {
88
                $this->aliasSet($key, $value);
89
                continue;
90
            }
91
92
            $this->object->$key = $value;
93
        }
94
95
        return $this;
96
    }
97
98
    /**
99
     * Create a new model of the model's type, and save it to the database.
100
     *
101
     * @param  array $attributes
102
     *
103
     * @return static
104
     */
105
    public static function create($attributes = [])
106
    {
107
        $model = new static($attributes);
0 ignored issues
show
Unused Code introduced by
The call to Silk\Type\Model::__construct() has too many arguments starting with $attributes. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
        $model = /** @scrutinizer ignore-call */ new static($attributes);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
108
109
        return $model->save();
110
    }
111
112
    /**
113
     * Create a new query builder instance for this model type.
114
     *
115
     * @return \Silk\Query\Builder
116
     */
117
    public static function query()
118
    {
119
        return (new static)->newQuery();
120
    }
121
122
    /**
123
     * Meta API for this type
124
     *
125
     * @param  string $key  Meta key to retrieve or empty to retrieve all.
126
     *
127
     * @return ObjectMeta|\Silk\Meta\Meta
128
     */
129
    public function meta($key = '')
130
    {
131
        $meta = new ObjectMeta(static::OBJECT_TYPE, $this->id);
132
133
        if ($key) {
134
            return $meta->get($key);
135
        }
136
137
        return $meta;
138
    }
139
140
    /**
141
     * Set the primary ID on the model.
142
     *
143
     * @param string|int $id  The model's ID
144
     *
145
     * @return $this
146
     */
147
    protected function setId($id)
148
    {
149
        $this->object->{static::ID_PROPERTY} = (int) $id;
150
151
        return $this;
152
    }
153
154
    /**
155
     * Set the object for the model.
156
     *
157
     * @param $object
158
     *
159
     * @return $this
160
     */
161
    protected function setObject($object)
162
    {
163
        $this->object = $object;
0 ignored issues
show
Bug introduced by
The property object is declared read-only in Silk\Type\Model.
Loading history...
164
165
        return $this;
166
    }
167
168
    /**
169
     * @return array
170
     */
171
    protected function objectAliases()
172
    {
173
        return [];
174
    }
175
176
    /**
177
     * @return object
178
     */
179
    protected function getAliasedObject()
180
    {
181
        return $this->object;
182
    }
183
184
    /**
185
     * Magic getter.
186
     *
187
     * @param  string $property
188
     *
189
     * @return mixed
190
     */
191
    public function __get($property)
192
    {
193
        if ($property == 'id') {
194
            return $this->object->{static::ID_PROPERTY};
195
        }
196
197
        if (in_array($property, ['object', static::OBJECT_TYPE])) {
198
            return $this->object;
199
        }
200
201
        if (! is_null($aliased = $this->aliasGet($property))) {
202
            return $aliased;
203
        }
204
205
        /**
206
         * Finally, hand-off the request to the wrapped object.
207
         * We don't check for existence as we leverage the magic __get
208
         * on the wrapped object as well.
209
         */
210
        return $this->object->$property;
211
    }
212
213
    /**
214
     * Magic Isset Checker.
215
     *
216
     * @param $property
217
     *
218
     * @return bool
219
     */
220
    public function __isset($property)
221
    {
222
        return ! is_null($this->__get($property));
223
    }
224
225
    /**
226
     * Magic setter.
227
     *
228
     * @param string $property  The property name
229
     * @param mixed  $value     The new property value
230
     */
231
    public function __set($property, $value)
232
    {
233
        if ($this->aliasSet($property, $value)) {
234
            return;
235
        }
236
237
        $this->object->$property = $value;
238
    }
239
240
    /**
241
     * Handle dynamic method calls into the model.
242
     *
243
     * @param  string $method
244
     * @param  array $arguments
245
     *
246
     * @return mixed
247
     */
248
    public function __call($method, $arguments)
249
    {
250
        $query = $this->newQuery();
251
252
        return call_user_func_array([$query, $method], $arguments);
253
    }
254
255
    /**
256
     * Handle dynamic static method calls on the model class.
257
     *
258
     * Proxies calls to direct method calls on a new instance
259
     *
260
     * @param string $method
261
     * @param array $arguments
262
     *
263
     * @return mixed
264
     */
265
    public static function __callStatic($method, array $arguments)
266
    {
267
        return call_user_func_array([new static, $method], $arguments);
268
    }
269
}
270