Completed
Push — master ( 38ffd4...ed5eea )
by Evan
03:02
created

Model::meta()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 10
Ratio 100 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 2
b 0
f 0
nc 2
nop 1
dl 10
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 Illuminate\Support\Collection;
9
use Silk\Query\Builder;
10
use Silk\Meta\TypeMeta;
11
use Silk\Exception\WP_ErrorException;
12
use Silk\Post\Exception\PostNotFoundException;
13
use Silk\Post\Exception\ModelPostTypeMismatchException;
14
15
/**
16
 * @property-read WP_Post $post
17
 * @property-read int     $id
18
 * 
19
 * @property int    $ID
20
 * @property int    $comment_count
21
 * @property string $comment_status
22
 * @property string $filter
23
 * @property string $guid
24
 * @property int    $menu_order
25
 * @property string $ping_status
26
 * @property string $pinged
27
 * @property int    $post_author
28
 * @property string $post_content
29
 * @property string $post_content_filtered
30
 * @property string $post_date
31
 * @property string $post_date_gmt
32
 * @property string $post_excerpt
33
 * @property string $post_mime_type
34
 * @property string $post_modified
35
 * @property string $post_modified_gmt
36
 * @property string $post_name
37
 * @property int    $post_parent
38
 * @property string $post_password
39
 * @property string $post_status
40
 * @property string $post_title
41
 * @property string $post_type
42
 * @property string $to_ping
43
 */
44
abstract class Model
45
{
46
    /**
47
     * The post
48
     * @var WP_Post
49
     */
50
    protected $post;
51
52
    /**
53
     * Post ID
54
     * @var int
55
     */
56
    protected $id;
57
58
    /**
59
     * The post type of the post this model wraps
60
     * @var string
61
     */
62
    const POST_TYPE = '';
63
64
    /**
65
     * The object type in WordPress
66
     * @var string
67
     */
68
    const OBJECT_TYPE = 'post';
69
70
    use TypeMeta;
71
72
    /**
73
     * Create a new instance
74
     *
75
     * @param WP_Post $post  Post object to model
76
     */
77
    public function __construct(WP_Post $post = null)
78
    {
79
        if (! $post) {
80
            $post = new WP_Post(new stdClass);
81
            $post->post_type = static::postTypeId();
82
        }
83
84
        $this->post = $post;
85
        $this->id   = $post->ID;
86
    }
87
88
    /**
89
     * Create a new instance from the given WP_Post object
90
     *
91
     * @param  WP_Post $post
92
     *
93
     * @return static
94
     */
95
    public static function fromWpPost(WP_Post $post)
96
    {
97
        if ($post->post_type !== static::postTypeId()) {
98
            throw new ModelPostTypeMismatchException(static::class, $post);
99
        }
100
101
        return new static($post);
102
    }
103
104
    /**
105
     * Create a new instance from a Post with the given ID
106
     *
107
     * @param  int|string $id  Post ID of post to create the instance from
108
     *
109
     * @return static
110
     */
111
    public static function fromID($id)
112
    {
113
        $post = WP_Post::get_instance($id);
114
115
        if (false === $post) {
116
            throw new PostNotFoundException("No post found with ID {$id}");
117
        }
118
119
        return static::fromWpPost($post);
120
    }
121
122
    /**
123
     * Create a new instance from a Post with the given slug
124
     *
125
     * @param  string $slug  the post slug
126
     *
127
     * @return static
128
     */
129
    public static function fromSlug($slug)
130
    {
131
        $found = static::whereSlug($slug)->limit(1)->results();
132
133
        if ($found->isEmpty()) {
134
            throw new PostNotFoundException("No post found with slug {$slug}");
135
        }
136
137
        return $found->first();
138
    }
139
140
    /**
141
     * Create a new instance from the global $post
142
     *
143
     * @return static
144
     */
145
    public static function fromGlobal()
1 ignored issue
show
Coding Style introduced by
fromGlobal uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
146
    {
147
        if (! $GLOBALS['post'] instanceof WP_Post) {
148
            throw new PostNotFoundException('Global $post not an instance of WP_Post');
149
        }
150
151
        return static::fromWpPost($GLOBALS['post']);
152
    }
153
154
    /**
155
     * Create a new post of the model's type
156
     *
157
     * @param  array $attributes
158
     *
159
     * @return static
160
     */
161
    public static function create($attributes = [])
162
    {
163
        $post = new WP_Post((object)
164
            Collection::make($attributes)
165
                ->except('ID')
166
                ->put('post_type', static::postTypeId())
167
                ->all()
168
        );
169
170
        return static::fromWpPost($post)->save();
171
    }
172
173
    /**
174
     * Get the post type identifier for this model
175
     *
176
     * @return string post type identifier (slug)
177
     */
178
    public static function postTypeId()
179
    {
180
        return static::POST_TYPE;
181
    }
182
183
    /**
184
     * Get the post type API
185
     *
186
     * @return mixed        Loads an existing type as a new PostType,
187
     *                      or returns a new PostTypeBuilder for registering a new type.
188
     */
189
    public static function postType()
190
    {
191
        return PostType::make(static::postTypeId());
192
    }
193
194
    /**
195
     * Send the post to the trash
196
     *
197
     * If trash is disabled, the post or page is permanently deleted.
198
     *
199
     * @return $this
200
     */
201
    public function trash()
202
    {
203
        if (wp_trash_post($this->id)) {
204
            $this->refresh();
205
        }
206
207
        return $this;
208
    }
209
210
    /**
211
     * Restore a post or page from the Trash
212
     *
213
     * @return $this
214
     */
215
    public function untrash()
216
    {
217
        if (wp_untrash_post($this->id)) {
218
            $this->refresh();
219
        }
220
221
        return $this;
222
    }
223
224
    /**
225
     * Permanently deletes the post and related objects
226
     *
227
     * When the post and page is permanently deleted, everything that is
228
     * tied to it is deleted also. This includes comments, post meta fields,
229
     * and terms associated with the post.
230
     *
231
     * @return $this
232
     */
233
    public function delete()
234
    {
235
        if (wp_delete_post($this->id, true)) {
236
            $this->refresh();
237
        }
238
239
        return $this;
240
    }
241
242
    /**
243
     * Refresh the post object from cache/database
244
     *
245
     * @return $this
246
     */
247
    public function refresh()
248
    {
249
        $this->post = WP_Post::get_instance($this->id);
250
251
        return $this;
252
    }
253
254
    /**
255
     * Update the post in the database
256
     *
257
     * @return $this
258
     */
259
    public function save()
260
    {
261
        if (! $this->id) {
262
            $result = wp_insert_post($this->post->to_array(), true);
263
        } else {
264
            $result = wp_update_post($this->post, true);
265
        }
266
267
        if (is_wp_error($result)) {
268
            throw new WP_ErrorException($result);
269
        }
270
271
        $this->id = (int) $result;
272
273
        return $this->refresh();
274
    }
275
276
    /**
277
     * Get a new query builder for the model.
278
     *
279
     * @return Builder
280
     */
281
    public function newQuery()
282
    {
283
        return (new Builder(new WP_Query))->setModel($this);
284
    }
285
286
    /**
287
     * Create a new query builder instance for this model type.
288
     *
289
     * @return Builder
290
     */
291
    public static function query()
292
    {
293
        return (new static)->newQuery();
294
    }
295
296
    /**
297
     * Magic getter
298
     *
299
     * @param  string $property
300
     *
301
     * @return mixed
302
     */
303
    public function __get($property)
304
    {
305
        if (property_exists($this, $property)) {
306
            return $this->$property;
307
        }
308
309
        /**
310
         * WP_Post translates non-existent properties to single post meta get
311
         */
312
        return $this->post->$property;
313
    }
314
315
    /**
316
     * Magic setter
317
     *
318
     * @param string $property
319
     * @param mixed $value
320
     */
321
    public function __set($property, $value)
322
    {
323
        if (isset($this->post->$property)) {
324
            $this->post->$property = $value;
325
        }
326
    }
327
328
    /**
329
     * Handle dynamic static method calls on the model class.
330
     *
331
     * Proxies calls to direct method calls on a new instance
332
     *
333
     * @param string $method
334
     * @param array $arguments
335
     *
336
     * @return mixed
337
     */
338
    public static function __callStatic($method, array $arguments)
339
    {
340
        return call_user_func_array([new static, $method], $arguments);
341
    }
342
343
    /**
344
     * Handle dynamic method calls into the model.
345
     *
346
     * @param  string $method
347
     * @param  array $arguments
348
     *
349
     * @return mixed
350
     */
351
    public function __call($method, $arguments)
352
    {
353
        $query = $this->newQuery();
354
355
        return call_user_func_array([$query, $method], $arguments);
356
    }
357
358
}
359