Model   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 227
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 50
dl 0
loc 227
rs 10
c 0
b 0
f 0
wmc 26

14 Methods

Rating   Name   Duplication   Size   Complexity  
A fromID() 0 9 2
A fromGlobal() 0 7 2
A delete() 0 7 2
A untrash() 0 7 2
A newQuery() 0 3 1
A postType() 0 3 1
A save() 0 15 3
A trash() 0 7 2
A url() 0 3 1
A find() 0 6 2
A postTypeId() 0 3 1
A __construct() 0 14 4
A fromSlug() 0 9 2
A refresh() 0 5 1
1
<?php
2
3
namespace Silk\Post;
4
5
use stdClass;
6
use WP_Post;
7
use Silk\Type\Model as BaseModel;
8
use Silk\PostType\PostType;
9
use Silk\Exception\WP_ErrorException;
10
use Silk\Post\Exception\PostNotFoundException;
11
use Silk\Post\Exception\ModelPostTypeMismatchException;
12
13
/**
14
 * @property-read WP_Post $post
15
 * @property-read int     $id
16
 *
17
 * @property int    $ID
18
 * @property int    $comment_count
19
 * @property string $comment_status
20
 * @property string $filter
21
 * @property string $guid
22
 * @property int    $menu_order
23
 * @property string $ping_status
24
 * @property string $pinged
25
 * @property int    $post_author
26
 * @property string $post_content
27
 * @property string $post_content_filtered
28
 * @property string $post_date
29
 * @property string $post_date_gmt
30
 * @property string $post_excerpt
31
 * @property string $post_mime_type
32
 * @property string $post_modified
33
 * @property string $post_modified_gmt
34
 * @property string $post_name
35
 * @property int    $post_parent
36
 * @property string $post_password
37
 * @property string $post_status
38
 * @property string $post_title
39
 * @property string $post_type
40
 * @property string $to_ping
41
 */
42
abstract class Model extends BaseModel
43
{
44
    /**
45
     * The post type of the post this model wraps
46
     * @var string
47
     */
48
    const POST_TYPE = '';
49
50
    /**
51
     * The object type in WordPress
52
     * @var string
53
     */
54
    const OBJECT_TYPE = 'post';
55
56
    /**
57
     * The primary ID property on the object
58
     */
59
    const ID_PROPERTY = 'ID';
60
61
    /**
62
     * Create a new instance
63
     *
64
     * @param array|WP_Post $post  Post object or array of attributes
65
     *
66
     * @throws ModelPostTypeMismatchException
67
     */
68
    public function __construct($post = [])
69
    {
70
        $attributes = is_array($post) ? $post : [];
71
72
        if (! $post instanceof WP_Post) {
73
            $post = new WP_Post(new stdClass);
74
            $post->post_type = static::postTypeId();
75
        } elseif ($post->post_type !== static::postTypeId()) {
76
            throw new ModelPostTypeMismatchException(static::class, $post);
77
        }
78
79
        $this->setObject($post);
80
81
        $this->fill($attributes);
82
    }
83
84
    /**
85
     * Retrieve a new instance by the ID.
86
     *
87
     * @param int|string $id Primary ID
88
     *
89
     * @return null|static
90
     */
91
    public static function find($id)
92
    {
93
        try {
94
            return static::fromID($id);
95
        } catch (\Exception $e) {
96
            return null;
97
        }
98
    }
99
100
    /**
101
     * Create a new instance from a Post with the given ID
102
     *
103
     * @param  int|string $id  Post ID of post to create the instance from
104
     *
105
     * @return static
106
     */
107
    public static function fromID($id)
108
    {
109
        $post = WP_Post::get_instance($id);
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type string; however, parameter $post_id of WP_Post::get_instance() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

109
        $post = WP_Post::get_instance(/** @scrutinizer ignore-type */ $id);
Loading history...
110
111
        if (false === $post) {
112
            throw new PostNotFoundException("No post found with ID {$id}");
113
        }
114
115
        return new static($post);
116
    }
117
118
    /**
119
     * Create a new instance from a Post with the given slug
120
     *
121
     * @param  string $slug  the post slug
122
     *
123
     * @return static
124
     */
125
    public static function fromSlug($slug)
126
    {
127
        $found = static::whereSlug($slug)->limit(1)->results();
0 ignored issues
show
Bug introduced by
The method whereSlug() does not exist on Silk\Post\Model. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

127
        $found = static::/** @scrutinizer ignore-call */ whereSlug($slug)->limit(1)->results();
Loading history...
128
129
        if ($found->isEmpty()) {
130
            throw new PostNotFoundException("No post found with slug {$slug}");
131
        }
132
133
        return $found->first();
134
    }
135
136
    /**
137
     * Create a new instance from the global $post
138
     *
139
     * @return static
140
     */
141
    public static function fromGlobal()
142
    {
143
        if (! $GLOBALS['post'] instanceof WP_Post) {
144
            throw new PostNotFoundException('Global $post not an instance of WP_Post');
145
        }
146
147
        return new static($GLOBALS['post']);
148
    }
149
150
    /**
151
     * Get the post type identifier for this model
152
     *
153
     * @return string post type identifier (slug)
154
     */
155
    public static function postTypeId()
156
    {
157
        return static::POST_TYPE;
158
    }
159
160
    /**
161
     * Get the post type API
162
     *
163
     * @return mixed        Loads an existing type as a new PostType,
164
     *                      or returns a new PostTypeBuilder for registering a new type.
165
     */
166
    public static function postType()
167
    {
168
        return PostType::make(static::postTypeId());
169
    }
170
171
    /**
172
     * Get the permalink URL.
173
     *
174
     * @return string|bool  The permalink URL, or false if the post does not exist.
175
     */
176
    public function url()
177
    {
178
        return get_permalink($this->id);
179
    }
180
181
    /**
182
     * Send the post to the trash
183
     *
184
     * If trash is disabled, the post or page is permanently deleted.
185
     *
186
     * @return $this
187
     */
188
    public function trash()
189
    {
190
        if (wp_trash_post($this->id)) {
191
            $this->refresh();
192
        }
193
194
        return $this;
195
    }
196
197
    /**
198
     * Restore a post or page from the Trash
199
     *
200
     * @return $this
201
     */
202
    public function untrash()
203
    {
204
        if (wp_untrash_post($this->id)) {
205
            $this->refresh();
206
        }
207
208
        return $this;
209
    }
210
211
    /**
212
     * Get a new query builder for the model.
213
     *
214
     * @return QueryBuilder
215
     */
216
    public function newQuery()
217
    {
218
        return QueryBuilder::make()->setModel($this);
219
    }
220
221
    /**
222
     * Save the post to the database.
223
     *
224
     * @throws WP_ErrorException
225
     *
226
     * @return $this
227
     */
228
    public function save()
229
    {
230
        if (! $this->id) {
231
            $result = wp_insert_post($this->object->to_array(), true);
232
        } else {
233
            $result = wp_update_post($this->object, true);
234
        }
235
236
        if (is_wp_error($result)) {
237
            throw new WP_ErrorException($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type integer; however, parameter $error of Silk\Exception\WP_ErrorException::__construct() does only seem to accept WP_Error, maybe add an additional type check? ( Ignorable by Annotation )

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

237
            throw new WP_ErrorException(/** @scrutinizer ignore-type */ $result);
Loading history...
238
        }
239
240
        $this->setId($result)->refresh();
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type WP_Error; however, parameter $id of Silk\Type\Model::setId() does only seem to accept integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

240
        $this->setId(/** @scrutinizer ignore-type */ $result)->refresh();
Loading history...
241
242
        return $this;
243
    }
244
245
    /**
246
     * Permanently delete the post from the database.
247
     *
248
     * @return $this
249
     */
250
    public function delete()
251
    {
252
        if (wp_delete_post($this->id, true)) {
253
            $this->refresh();
254
        }
255
256
        return $this;
257
    }
258
259
    /**
260
     * Update the modeled object with the current state from the database.
261
     *
262
     * @return $this
263
     */
264
    public function refresh()
265
    {
266
        $this->setObject(WP_Post::get_instance($this->id));
267
268
        return $this;
269
    }
270
}
271