Completed
Push — master ( f84666...e52fc0 )
by Evan
01:46
created

src/Type/Model.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Query\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
     * @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
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...
108
109
        return $model->save();
110
    }
111
112
    /**
113
     * Create a new query builder instance for this model type.
114
     *
115
     * @return \Silk\Contracts\Query\BuildsQueries
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;
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