Completed
Push — master ( ca910a...8ffcad )
by Evan
02:52
created

Model::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 10
rs 9.4285
1
<?php
2
3
namespace Silk\Post;
4
5
use stdClass;
6
use WP_Post;
7
use WP_Query;
8
use Silk\Query\Builder;
9
use Silk\Meta\ObjectMeta;
10
use Silk\Exception\WP_ErrorException;
11
use Silk\Post\Exception\PostNotFoundException;
12
use Silk\Post\Exception\ModelPostTypeMismatchException;
13
14
abstract class Model
15
{
16
    /**
17
     * The post
18
     * @var WP_Post
19
     */
20
    protected $post;
21
22
    /**
23
     * Post ID
24
     * @var int
25
     */
26
    protected $id;
27
28
    /**
29
     * The post type of the post this model wraps
30
     * @var string
31
     */
32
    const POST_TYPE = 'post';
33
34
35
    /**
36
     * [__construct description]
37
     * @param WP_Post $post [description]
38
     */
39
    public function __construct(WP_Post $post = null)
40
    {
41
        if (! $post) {
42
            $post = new WP_Post(new stdClass);
43
            $post->post_type = static::POST_TYPE;
44
        }
45
46
        $this->post = $post;
47
        $this->id   = $post->ID;
48
    }
49
50
    public static function fromWpPost(WP_Post $post)
51
    {
52
        if ($post->post_type !== static::POST_TYPE) {
53
            throw new ModelPostTypeMismatchException(static::class, $post);
54
        }
55
56
        return new static($post);
57
    }
58
59
    /**
60
     * Make new instance from a Post with the given ID
61
     *
62
     * @param  int|string $id [description]
63
     *
64
     * @return static
65
     */
66
    public static function fromID($id)
67
    {
68
        $post = WP_Post::get_instance($id);
69
70
        if (false === $post) {
71
            throw new PostNotFoundException("No post found with ID {$id}");
72
        }
73
74
        return static::fromWpPost($post);
75
    }
76
77
    /**
78
     * Make new instance from a Post slug
79
     *
80
     * @param  string $slug  the post slug
81
     *
82
     * @return static
83
     */
84
    public static function fromSlug($slug)
85
    {
86
        $posts = (array) get_posts([
87
            'name'           => $slug,
88
            'post_type'      => static::POST_TYPE,
89
            'posts_per_page' => 1
90
        ]);
91
92
        if (! $post = reset($posts)) {
93
            throw new PostNotFoundException("No post found with slug {$slug}");
94
        }
95
96
        return static::fromWpPost($post);
97
    }
98
99
    /**
100
     * Make new instance from the global $post
101
     *
102
     * @return static
103
     */
104
    public static function fromGlobal()
105
    {
106
        $post = get_post();
107
108
        if (! $post instanceof WP_Post) {
1 ignored issue
show
Bug introduced by
The class WP_Post does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
109
            throw new PostNotFoundException('Global $post not an instance of WP_Post');
110
        }
111
112
        return static::fromWpPost($post);
113
    }
114
115
    /**
116
     * Create a new post of the model's type
117
     *
118
     * @param  [type] $attributes [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
119
     * @return [type]             [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
120
     */
121
    public static function create($attributes = [])
122
    {
123
        $attributes = (object) collect($attributes)->except('ID')
124
            ->put('post_type', static::POST_TYPE)->all();
125
126
        $post = new WP_Post($attributes);
127
        $model = static::fromWpPost($post);
128
129
        return $model->save();
130
    }
131
132
    /**
133
     * Meta API for this post
134
     *
135
     * @param  string $key [description]
136
     *
137
     * @return object
138
     */
139
    public function meta($key = '')
140
    {
141
        $meta = new ObjectMeta('post', $this->id);
142
143
        if ($key) {
144
            return $meta->get($key);
145
        }
146
147
        return $meta;
148
    }
149
150
    /**
151
     * Send the post to the trash
152
     *
153
     * If trash is disabled, the post or page is permanently deleted.
154
     *
155
     * @return false|array|WP_Post|null Post data array, otherwise false.
156
     */
157
    public function trash()
158
    {
159
        if (wp_trash_post($this->id)) {
160
            $this->refresh();
161
        }
162
163
        return $this;
164
    }
165
166
    /**
167
     * Restore a post or page from the Trash
168
     *
169
     * @return WP_Post|false WP_Post object. False on failure.
170
     */
171
    public function untrash()
172
    {
173
        if (wp_untrash_post($this->id)) {
174
            $this->refresh();
175
        }
176
177
        return $this;
178
    }
179
180
    /**
181
     * Permanently deletes the post and related objects
182
     *
183
     * When the post and page is permanently deleted, everything that is
184
     * tied to it is deleted also. This includes comments, post meta fields,
185
     * and terms associated with the post.
186
     *
187
     * @return [type] [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
188
     */
189
    public function delete()
190
    {
191
        if (wp_delete_post($this->id, true)) {
192
            $this->refresh();
193
        }
194
195
        return $this;
196
    }
197
198
    /**
199
     * Refresh the post object from cache/database
200
     *
201
     * @return static
202
     */
203
    public function refresh()
204
    {
205
        $this->post = WP_Post::get_instance($this->id);
206
207
        return $this;
208
    }
209
210
    /**
211
     * Update the post in the database
212
     *
213
     * @return [type] [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
214
     */
215
    public function save()
216
    {
217
        if (! $this->id) {
218
            $result = wp_insert_post($this->post->to_array(), true);
219
        } else {
220
            $result = wp_update_post($this->post, true);
221
        }
222
223
        if (is_wp_error($result)) {
224
            throw new WP_ErrorException($result);
225
        }
226
227
        $this->id = (int) $result;
228
229
        return $this->refresh();
230
    }
231
232
    public static function all()
233
    {
234
        return static::query()->limit(-1);
235
    }
236
237
    /**
238
     * Get a new query builder for the model.
239
     *
240
     * @return Builder
241
     */
242
    public function newQuery()
243
    {
244
        return (new Builder(new WP_Query))->setModel($this);
245
    }
246
247
    /**
248
     * Create a new query builder instance for this model type.
249
     * @return Builder
250
     */
251
    public static function query()
252
    {
253
        return (new static)->newQuery();
254
    }
255
256
    /**
257
     * Magic getter
258
     * @param  string $property
259
     * @return mixed
260
     */
261
    public function __get($property)
262
    {
263
        if ('id' === $property) {
264
            return $this->id;
265
        }
266
267
        if (isset($this->$property)) {
268
            return $this->$property;
269
        }
270
271
        /**
272
         * WP_Post translates non-existent properties to single post meta get
273
         */
274
        return $this->post->$property;
275
    }
276
277
    /**
278
     * Magic setter
279
     * @param string $property
280
     * @param mixed $value
281
     */
282
    public function __set($property, $value)
283
    {
284
        if (isset($this->post->$property)) {
285
            $this->post->$property = $value;
286
        }
287
    }
288
289
    /**
290
     * Handle dynamic static method calls on the model class.
291
     *
292
     * Proxies calls to direct method calls on a new instance
293
     *
294
     * @param       $method
295
     * @param array $arguments
296
     *
297
     * @return mixed
298
     */
299
    public static function __callStatic($method, array $arguments)
300
    {
301
        return call_user_func_array([new static, $method], $arguments);
302
    }
303
304
    /**
305
     * Handle dynamic method calls into the model.
306
     *
307
     * @param  string  $method
308
     * @param  array  $arguments
309
     * @return mixed
310
     */
311
    public function __call($method, $arguments)
312
    {
313
        $query = $this->newQuery();
314
315
        return call_user_func_array([$query, $method], $arguments);
316
    }
317
318
}
319