1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Silk\Term; |
4
|
|
|
|
5
|
|
|
use stdClass; |
6
|
|
|
use WP_Term; |
7
|
|
|
use Silk\Meta\ObjectMeta; |
8
|
|
|
use Silk\Taxonomy\Taxonomy; |
9
|
|
|
use Silk\Query\QueryBuilder; |
10
|
|
|
use Illuminate\Support\Collection; |
11
|
|
|
use Silk\Exception\WP_ErrorException; |
12
|
|
|
use Silk\Term\Exception\TermNotFoundException; |
13
|
|
|
use Silk\Term\Exception\TaxonomyMismatchException; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* @property-read int $id |
17
|
|
|
* @property int $term_id |
18
|
|
|
* @property string $name |
19
|
|
|
* @property string $slug |
20
|
|
|
* @property string $term_group |
21
|
|
|
* @property int $term_taxonomy_id |
22
|
|
|
* @property string $taxonomy |
23
|
|
|
* @property string $description |
24
|
|
|
* @property int $parent |
25
|
|
|
* @property int $count |
26
|
|
|
*/ |
27
|
|
|
abstract class Model |
28
|
|
|
{ |
29
|
|
|
use QueryBuilder; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* The term's taxonomy |
33
|
|
|
* @var string |
34
|
|
|
*/ |
35
|
|
|
const TAXONOMY = ''; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* The term object |
39
|
|
|
* @var WP_Term |
40
|
|
|
*/ |
41
|
|
|
protected $term; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Model Constructor. |
45
|
|
|
* |
46
|
|
|
* @param mixed $term WP_Term to fill data from |
47
|
|
|
*/ |
48
|
|
|
public function __construct(WP_Term $term = null) |
49
|
|
|
{ |
50
|
|
|
if (! $term) { |
51
|
|
|
$term = new WP_Term(new stdClass); |
52
|
|
|
$term->taxonomy = static::TAXONOMY; |
53
|
|
|
} elseif ($term->taxonomy != static::TAXONOMY) { |
54
|
|
|
throw new TaxonomyMismatchException(); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
$this->term = $term; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Create a new instance from a WP_Term object. |
62
|
|
|
* |
63
|
|
|
* @param WP_Term $term [description] |
64
|
|
|
* |
65
|
|
|
* @return static |
66
|
|
|
*/ |
67
|
|
|
public static function fromWpTerm(WP_Term $term) |
68
|
|
|
{ |
69
|
|
|
return new static($term); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Create a new instance from a term ID. |
74
|
|
|
* |
75
|
|
|
* @param int|string $id Term ID |
76
|
|
|
* |
77
|
|
|
* @return static |
78
|
|
|
*/ |
79
|
|
View Code Duplication |
public static function fromID($id) |
|
|
|
|
80
|
|
|
{ |
81
|
|
|
if (! $term = get_term_by('id', (int) $id, static::TAXONOMY)) { |
82
|
|
|
throw new TermNotFoundException("No term found with ID $id."); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
return static::fromWpTerm($term); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Create a new instance from a slug. |
90
|
|
|
* |
91
|
|
|
* @param string $slug Term slug |
92
|
|
|
* |
93
|
|
|
* @return static |
94
|
|
|
*/ |
95
|
|
View Code Duplication |
public static function fromSlug($slug) |
|
|
|
|
96
|
|
|
{ |
97
|
|
|
if (! $term = get_term_by('slug', $slug, static::TAXONOMY)) { |
98
|
|
|
throw new TermNotFoundException("No term found with slug '$slug'."); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
return static::fromWpTerm($term); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Create a new instance from an array of attributes. |
106
|
|
|
* |
107
|
|
|
* @param array $attributes [description] |
108
|
|
|
* |
109
|
|
|
* @return static |
110
|
|
|
*/ |
111
|
|
|
public static function fromArray(array $attributes) |
112
|
|
|
{ |
113
|
|
|
return new static( |
114
|
|
|
new WP_Term((object) $attributes) |
115
|
|
|
); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Create a new term, and get the instance for it. |
120
|
|
|
* |
121
|
|
|
* @param array $attributes Term attributes |
122
|
|
|
* |
123
|
|
|
* @return static |
124
|
|
|
*/ |
125
|
|
|
public static function create(array $attributes = []) |
126
|
|
|
{ |
127
|
|
|
return static::fromArray( |
128
|
|
|
Collection::make($attributes) |
129
|
|
|
->except(['term_id', 'term_taxonomy_id']) |
130
|
|
|
->put('taxonomy', static::TAXONOMY) |
131
|
|
|
->toArray() |
132
|
|
|
)->save(); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Save or update the term instance in the database. |
137
|
|
|
* |
138
|
|
|
* @return $this |
139
|
|
|
*/ |
140
|
|
|
public function save() |
141
|
|
|
{ |
142
|
|
|
if ($this->exists()) { |
143
|
|
|
$ids = wp_update_term($this->id, static::TAXONOMY, $this->term->to_array()); |
144
|
|
|
} else { |
145
|
|
|
$ids = wp_insert_term($this->name, static::TAXONOMY, $this->term->to_array()); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
if (is_wp_error($ids)) { |
149
|
|
|
throw new WP_ErrorException($ids); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
foreach ($ids as $field => $id) { |
153
|
|
|
$this->term->$field = $id; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
return $this; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Delete the term from the database. |
161
|
|
|
* |
162
|
|
|
* @return $this |
163
|
|
|
*/ |
164
|
|
|
public function delete() |
165
|
|
|
{ |
166
|
|
|
if ($result = wp_delete_term($this->id, static::TAXONOMY)) { |
|
|
|
|
167
|
|
|
$this->term->term_id = null; |
168
|
|
|
$this->term->term_taxonomy_id = 0; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
return $this; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Check if this term exists in the database. |
176
|
|
|
* |
177
|
|
|
* @return boolean |
178
|
|
|
*/ |
179
|
|
|
public function exists() |
180
|
|
|
{ |
181
|
|
|
return (bool) term_exists((int) $this->id, static::TAXONOMY); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Check if this term exists in the database as the child of the given parent. |
186
|
|
|
* |
187
|
|
|
* @param int|string|object $parent integer Parent term ID |
188
|
|
|
* string Parent term slug or name |
189
|
|
|
* object The parent term object/model. |
190
|
|
|
* |
191
|
|
|
* @return boolean True if the this term and the parent |
192
|
|
|
* exist in the database, and the instance |
193
|
|
|
* is a child of the given parent; |
194
|
|
|
* otherwise false |
195
|
|
|
*/ |
196
|
|
|
public function isChildOf($parent) |
197
|
|
|
{ |
198
|
|
|
if (isset($parent->term_id)) { |
199
|
|
|
$parent = $parent->term_id; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
return (bool) term_exists((int) $this->id, static::TAXONOMY, $parent); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Get the parent term instance. |
207
|
|
|
* |
208
|
|
|
* @return static |
209
|
|
|
*/ |
210
|
|
|
public function parent() |
211
|
|
|
{ |
212
|
|
|
return static::fromID($this->term->parent); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Get all ancestors of this term as a collection. |
217
|
|
|
* |
218
|
|
|
* @return Collection |
219
|
|
|
*/ |
220
|
|
|
public function ancestors() |
221
|
|
|
{ |
222
|
|
|
return Collection::make(get_ancestors($this->id, static::TAXONOMY, 'taxonomy')) |
223
|
|
|
->map(function ($term_ID) { |
224
|
|
|
return static::fromID($term_ID); |
225
|
|
|
}); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* Meta API for this term |
230
|
|
|
* |
231
|
|
|
* @param string $key Meta key to retreive or empty to retreive all. |
232
|
|
|
* |
233
|
|
|
* @return object |
234
|
|
|
*/ |
235
|
|
View Code Duplication |
public function meta($key = '') |
|
|
|
|
236
|
|
|
{ |
237
|
|
|
$meta = new ObjectMeta('term', $this->id); |
238
|
|
|
|
239
|
|
|
if ($key) { |
240
|
|
|
return $meta->get($key); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
return $meta; |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Get the Taxonomy model. |
248
|
|
|
* |
249
|
|
|
* @return Taxonomy |
250
|
|
|
*/ |
251
|
|
|
public function taxonomy() |
252
|
|
|
{ |
253
|
|
|
return Taxonomy::make($this->taxonomy); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
/** |
257
|
|
|
* Start a new query for terms of this type. |
258
|
|
|
* |
259
|
|
|
* @return TermQueryBuilder |
260
|
|
|
*/ |
261
|
|
|
public function newQuery() |
262
|
|
|
{ |
263
|
|
|
return (new TermQueryBuilder)->setModel($this); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Magic Getter. |
268
|
|
|
* |
269
|
|
|
* @param string $property Property name accessed |
270
|
|
|
* |
271
|
|
|
* @return mixed |
272
|
|
|
*/ |
273
|
|
|
public function __get($property) |
274
|
|
|
{ |
275
|
|
|
if ('id' == strtolower($property)) { |
276
|
|
|
return $this->term->term_id; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
if (isset($this->term->$property)) { |
280
|
|
|
return $this->term->$property; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
return null; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* Magic set checker. |
288
|
|
|
* |
289
|
|
|
* @param string $property Property name queried |
290
|
|
|
* |
291
|
|
|
* @return boolean |
292
|
|
|
*/ |
293
|
|
|
public function __isset($property) |
294
|
|
|
{ |
295
|
|
|
return property_exists($this->term, $property); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* Magic Setter. |
300
|
|
|
* |
301
|
|
|
* @param string $property Property name assigned |
302
|
|
|
* @param mixed $value Assigned property value |
303
|
|
|
*/ |
304
|
|
|
public function __set($property, $value) |
305
|
|
|
{ |
306
|
|
|
$this->term->$property = $value; |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.