Completed
Pull Request — master (#23)
by Evan
05:32 queued 02:29
created

Model::make()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 2
eloc 4
c 2
b 0
f 1
nc 2
nop 0
dl 0
loc 8
rs 9.4285
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\Contracts\BuildsQueries
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
     * @return static
65
     */
66
    public static function make()
67
    {
68
        if ($arguments = func_get_args()) {
69
            return (new \ReflectionClass(static::class))->newInstanceArgs($arguments);
70
        }
71
72
        return new static;
73
    }
74
75
    /**
76
     * Fill the model with an array of attributes.
77
     *
78
     * @param  array  $attributes
79
     *
80
     * @return $this
81
     */
82
    public function fill(array $attributes)
83
    {
84
        foreach ($attributes as $key => $value) {
85
            if ($this->expandAlias($key)) {
86
                $this->aliasSet($key, $value);
87
                continue;
88
            }
89
90
            $this->object->$key = $value;
91
        }
92
93
        return $this;
94
    }
95
96
    /**
97
     * Create a new model of the model's type, and save it to the database.
98
     *
99
     * @param  array $attributes
100
     *
101
     * @return static
102
     */
103
    public static function create($attributes = [])
104
    {
105
        $model = new static($attributes);
0 ignored issues
show
Unused Code introduced by
The call to Model::__construct() has too many arguments starting with $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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

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