Model::url()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Silk\Term;
4
5
use stdClass;
6
use WP_Term;
7
use Silk\Taxonomy\Taxonomy;
8
use Silk\Type\Model as BaseModel;
9
use Silk\Support\Collection;
10
use Silk\Exception\WP_ErrorException;
11
use Silk\Term\Exception\TermNotFoundException;
12
use Silk\Term\Exception\TaxonomyMismatchException;
13
14
/**
15
 * @property-read WP_Term $term
16
 * @property int    $term_id
17
 * @property string $name
18
 * @property string $slug
19
 * @property string $term_group
20
 * @property int    $term_taxonomy_id
21
 * @property string $taxonomy
22
 * @property string $description
23
 * @property int    $parent
24
 * @property int    $count
25
 */
26
abstract class Model extends BaseModel
27
{
28
    /**
29
     * The term's taxonomy
30
     * @var string
31
     */
32
    const TAXONOMY = '';
33
34
    /**
35
     * The object type in WordPress
36
     * @var string
37
     */
38
    const OBJECT_TYPE = 'term';
39
40
    /**
41
     * The primary ID property on the object
42
     */
43
    const ID_PROPERTY = 'term_id';
44
45
    /**
46
     * Model Constructor.
47
     *
48
     * @param array|WP_Term $term  WP_Term
49
     *
50
     * @throws TaxonomyMismatchException
51
     */
52
    public function __construct($term = [])
53
    {
54
        $attributes = is_array($term) ? $term : [];
55
56
        if (! $term instanceof WP_Term) {
57
            $term = new WP_Term(new stdClass);
58
            $term->taxonomy = static::TAXONOMY;
59
        } elseif ($term->taxonomy != static::TAXONOMY) {
60
            throw new TaxonomyMismatchException();
61
        }
62
63
        $this->setObject($term);
64
65
        $this->fill($attributes);
66
    }
67
68
    /**
69
     * Retrieve a new instance by the ID.
70
     *
71
     * @param int|string $id Primary ID
72
     *
73
     * @return null|static
74
     */
75
    public static function find($id)
76
    {
77
        try {
78
            return static::fromID($id);
79
        } catch (\Exception $e) {
80
            return null;
81
        }
82
    }
83
84
    /**
85
     * Create a new instance from a term ID.
86
     *
87
     * @param  int|string $id  Term ID
88
     *
89
     * @throws TermNotFoundException
90
     *
91
     * @return static
92
     */
93
    public static function fromID($id)
94
    {
95
        if (! $term = WP_Term::get_instance($id, static::TAXONOMY)) {
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type string; however, parameter $term_id of WP_Term::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

95
        if (! $term = WP_Term::get_instance(/** @scrutinizer ignore-type */ $id, static::TAXONOMY)) {
Loading history...
96
            throw new TermNotFoundException("No term found with ID $id.");
97
        }
98
99
        return new static($term);
0 ignored issues
show
Bug introduced by
It seems like $term can also be of type WP_Error; however, parameter $term of Silk\Term\Model::__construct() does only seem to accept WP_Term|array, 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

99
        return new static(/** @scrutinizer ignore-type */ $term);
Loading history...
100
    }
101
102
    /**
103
     * Create a new instance from a slug.
104
     *
105
     * @param  string $slug  Term slug
106
     *
107
     * @throws TermNotFoundException
108
     *
109
     * @return static
110
     */
111
    public static function fromSlug($slug)
112
    {
113
        if (! $term = get_term_by('slug', $slug, static::TAXONOMY)) {
114
            throw new TermNotFoundException("No term found with slug '$slug'.");
115
        }
116
117
        return new static($term);
118
    }
119
120
    /**
121
     * Check if this term exists in the database.
122
     *
123
     * @return boolean
124
     */
125
    public function exists()
126
    {
127
        return $this->id && ((bool) term_exists((int) $this->id, static::TAXONOMY));
128
    }
129
130
    /**
131
     * Check if this term exists in the database as the child of the given parent.
132
     *
133
     * @param  int|string|object  $parent  integer Parent term ID
134
     *                                     string  Parent term slug or name
135
     *                                     object  The parent term object/model.
136
     *
137
     * @return boolean                     True if the this term and the parent
138
     *                                     exist in the database, and the instance
139
     *                                     is a child of the given parent;
140
     *                                     otherwise false
141
     */
142
    public function isChildOf($parent)
143
    {
144
        if (isset($parent->term_id)) {
145
            $parent = $parent->term_id;
146
        }
147
148
        return (bool) term_exists((int) $this->id, static::TAXONOMY, $parent);
149
    }
150
151
    /**
152
     * Get the parent term instance.
153
     *
154
     * @return static
155
     */
156
    public function parent()
157
    {
158
        return static::fromID($this->object->parent);
159
    }
160
161
    /**
162
     * Get all ancestors of this term as a collection.
163
     *
164
     * @return Collection
165
     */
166
    public function ancestors()
167
    {
168
        return Collection::make(get_ancestors($this->id, static::TAXONOMY, 'taxonomy'))
169
            ->map([static::class, 'fromID']);
170
    }
171
172
    /**
173
     * Get all children of this term as a collection.
174
     *
175
     * @return Collection
176
     */
177
    public function children()
178
    {
179
        return Collection::make(get_term_children($this->id, static::TAXONOMY))
180
             ->map([static::class, 'fromID']);
181
    }
182
183
    /**
184
     * Get the Taxonomy model.
185
     *
186
     * @return Taxonomy|\Silk\Taxonomy\Builder
187
     */
188
    public static function taxonomy()
189
    {
190
        return Taxonomy::make(static::TAXONOMY);
191
    }
192
193
    /**
194
     * Get the URL for this term.
195
     *
196
     * @return string|bool
197
     */
198
    public function url()
199
    {
200
        $url = get_term_link($this->id, $this->taxonomy);
201
202
        if (is_wp_error($url)) {
203
            throw new WP_ErrorException($url);
0 ignored issues
show
Bug introduced by
It seems like $url can also be of type string; 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

203
            throw new WP_ErrorException(/** @scrutinizer ignore-type */ $url);
Loading history...
204
        }
205
206
        return $url;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $url also could return the type WP_Error which is incompatible with the documented return type string|boolean.
Loading history...
207
    }
208
209
    /**
210
     * Start a new query for terms of this type.
211
     *
212
     * @return QueryBuilder
213
     */
214
    public function newQuery()
215
    {
216
        return QueryBuilder::make()->setModel($this);
217
    }
218
219
    /**
220
     * Save the term to the database.
221
     *
222
     * @throws WP_ErrorException
223
     *
224
     * @return $this
225
     */
226
    public function save()
227
    {
228
        if ($this->id) {
229
            $ids = wp_update_term($this->id, $this->taxonomy, $this->object->to_array());
230
        } else {
231
            $ids = wp_insert_term($this->name, $this->taxonomy, $this->object->to_array());
232
        }
233
234
        if (is_wp_error($ids)) {
235
            throw new WP_ErrorException($ids);
0 ignored issues
show
Bug introduced by
It seems like $ids can also be of type array; 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

235
            throw new WP_ErrorException(/** @scrutinizer ignore-type */ $ids);
Loading history...
236
        }
237
238
        $this->setId($ids['term_id'])->refresh();
239
240
        return $this;
241
    }
242
243
    /**
244
     * Delete the term from the database.
245
     *
246
     * @return $this
247
     */
248
    public function delete()
249
    {
250
        if (wp_delete_term($this->id, $this->taxonomy)) {
251
            $this->setObject(new WP_Term(new stdClass));
252
        }
253
254
        return $this;
255
    }
256
257
    /**
258
     * Reload the term object from the database.
259
     *
260
     * @return $this
261
     */
262
    public function refresh()
263
    {
264
        $this->setObject(WP_Term::get_instance($this->id, $this->taxonomy));
265
266
        return $this;
267
    }
268
}
269