|
1 <?php |
|
2 /** |
|
3 * Taxonomy API: WP_Taxonomy class |
|
4 * |
|
5 * @package WordPress |
|
6 * @subpackage Taxonomy |
|
7 * @since 4.7.0 |
|
8 */ |
|
9 |
|
10 /** |
|
11 * Core class used for interacting with taxonomies. |
|
12 * |
|
13 * @since 4.7.0 |
|
14 */ |
|
15 final class WP_Taxonomy { |
|
16 /** |
|
17 * Taxonomy key. |
|
18 * |
|
19 * @since 4.7.0 |
|
20 * @var string |
|
21 */ |
|
22 public $name; |
|
23 |
|
24 /** |
|
25 * Name of the taxonomy shown in the menu. Usually plural. |
|
26 * |
|
27 * @since 4.7.0 |
|
28 * @var string |
|
29 */ |
|
30 public $label; |
|
31 |
|
32 /** |
|
33 * An array of labels for this taxonomy. |
|
34 * |
|
35 * @since 4.7.0 |
|
36 * @var object |
|
37 */ |
|
38 public $labels = array(); |
|
39 |
|
40 /** |
|
41 * A short descriptive summary of what the taxonomy is for. |
|
42 * |
|
43 * @since 4.7.0 |
|
44 * @var string |
|
45 */ |
|
46 public $description = ''; |
|
47 |
|
48 /** |
|
49 * Whether a taxonomy is intended for use publicly either via the admin interface or by front-end users. |
|
50 * |
|
51 * @since 4.7.0 |
|
52 * @var bool |
|
53 */ |
|
54 public $public = true; |
|
55 |
|
56 /** |
|
57 * Whether the taxonomy is publicly queryable. |
|
58 * |
|
59 * @since 4.7.0 |
|
60 * @var bool |
|
61 */ |
|
62 public $publicly_queryable = true; |
|
63 |
|
64 /** |
|
65 * Whether the taxonomy is hierarchical. |
|
66 * |
|
67 * @since 4.7.0 |
|
68 * @var bool |
|
69 */ |
|
70 public $hierarchical = false; |
|
71 |
|
72 /** |
|
73 * Whether to generate and allow a UI for managing terms in this taxonomy in the admin. |
|
74 * |
|
75 * @since 4.7.0 |
|
76 * @var bool |
|
77 */ |
|
78 public $show_ui = true; |
|
79 |
|
80 /** |
|
81 * Whether to show the taxonomy in the admin menu. |
|
82 * |
|
83 * If true, the taxonomy is shown as a submenu of the object type menu. If false, no menu is shown. |
|
84 * |
|
85 * @since 4.7.0 |
|
86 * @var bool |
|
87 */ |
|
88 public $show_in_menu = true; |
|
89 |
|
90 /** |
|
91 * Whether the taxonomy is available for selection in navigation menus. |
|
92 * |
|
93 * @since 4.7.0 |
|
94 * @var bool |
|
95 */ |
|
96 public $show_in_nav_menus = true; |
|
97 |
|
98 /** |
|
99 * Whether to list the taxonomy in the tag cloud widget controls. |
|
100 * |
|
101 * @since 4.7.0 |
|
102 * @var bool |
|
103 */ |
|
104 public $show_tagcloud = true; |
|
105 |
|
106 /** |
|
107 * Whether to show the taxonomy in the quick/bulk edit panel. |
|
108 * |
|
109 * @since 4.7.0 |
|
110 * @var bool |
|
111 */ |
|
112 public $show_in_quick_edit = true; |
|
113 |
|
114 /** |
|
115 * Whether to display a column for the taxonomy on its post type listing screens. |
|
116 * |
|
117 * @since 4.7.0 |
|
118 * @var bool |
|
119 */ |
|
120 public $show_admin_column = false; |
|
121 |
|
122 /** |
|
123 * The callback function for the meta box display. |
|
124 * |
|
125 * @since 4.7.0 |
|
126 * @var bool|callable |
|
127 */ |
|
128 public $meta_box_cb = null; |
|
129 |
|
130 /** |
|
131 * An array of object types this taxonomy is registered for. |
|
132 * |
|
133 * @since 4.7.0 |
|
134 * @var array |
|
135 */ |
|
136 public $object_type = null; |
|
137 |
|
138 /** |
|
139 * Capabilities for this taxonomy. |
|
140 * |
|
141 * @since 4.7.0 |
|
142 * @var array |
|
143 */ |
|
144 public $cap; |
|
145 |
|
146 /** |
|
147 * Rewrites information for this taxonomy. |
|
148 * |
|
149 * @since 4.7.0 |
|
150 * @var array|false |
|
151 */ |
|
152 public $rewrite; |
|
153 |
|
154 /** |
|
155 * Query var string for this taxonomy. |
|
156 * |
|
157 * @since 4.7.0 |
|
158 * @var string|false |
|
159 */ |
|
160 public $query_var; |
|
161 |
|
162 /** |
|
163 * Function that will be called when the count is updated. |
|
164 * |
|
165 * @since 4.7.0 |
|
166 * @var callable |
|
167 */ |
|
168 public $update_count_callback; |
|
169 |
|
170 /** |
|
171 * Whether this taxonomy should appear in the REST API. |
|
172 * |
|
173 * Default false. If true, standard endpoints will be registered with |
|
174 * respect to $rest_base and $rest_controller_class. |
|
175 * |
|
176 * @since 4.7.4 |
|
177 * @var bool $show_in_rest |
|
178 */ |
|
179 public $show_in_rest; |
|
180 |
|
181 /** |
|
182 * The base path for this taxonomy's REST API endpoints. |
|
183 * |
|
184 * @since 4.7.4 |
|
185 * @var string|bool $rest_base |
|
186 */ |
|
187 public $rest_base; |
|
188 |
|
189 /** |
|
190 * The controller for this taxonomy's REST API endpoints. |
|
191 * |
|
192 * Custom controllers must extend WP_REST_Controller. |
|
193 * |
|
194 * @since 4.7.4 |
|
195 * @var string|bool $rest_controller_class |
|
196 */ |
|
197 public $rest_controller_class; |
|
198 |
|
199 /** |
|
200 * Whether it is a built-in taxonomy. |
|
201 * |
|
202 * @since 4.7.0 |
|
203 * @var bool |
|
204 */ |
|
205 public $_builtin; |
|
206 |
|
207 /** |
|
208 * Constructor. |
|
209 * |
|
210 * @since 4.7.0 |
|
211 * |
|
212 * @global WP $wp WP instance. |
|
213 * |
|
214 * @param string $taxonomy Taxonomy key, must not exceed 32 characters. |
|
215 * @param array|string $object_type Name of the object type for the taxonomy object. |
|
216 * @param array|string $args Optional. Array or query string of arguments for registering a taxonomy. |
|
217 * Default empty array. |
|
218 */ |
|
219 public function __construct( $taxonomy, $object_type, $args = array() ) { |
|
220 $this->name = $taxonomy; |
|
221 |
|
222 $this->set_props( $object_type, $args ); |
|
223 } |
|
224 |
|
225 /** |
|
226 * Sets taxonomy properties. |
|
227 * |
|
228 * @since 4.7.0 |
|
229 * |
|
230 * @param array|string $object_type Name of the object type for the taxonomy object. |
|
231 * @param array|string $args Array or query string of arguments for registering a taxonomy. |
|
232 */ |
|
233 public function set_props( $object_type, $args ) { |
|
234 $args = wp_parse_args( $args ); |
|
235 |
|
236 /** |
|
237 * Filters the arguments for registering a taxonomy. |
|
238 * |
|
239 * @since 4.4.0 |
|
240 * |
|
241 * @param array $args Array of arguments for registering a taxonomy. |
|
242 * @param string $taxonomy Taxonomy key. |
|
243 * @param array $object_type Array of names of object types for the taxonomy. |
|
244 */ |
|
245 $args = apply_filters( 'register_taxonomy_args', $args, $this->name, (array) $object_type ); |
|
246 |
|
247 $defaults = array( |
|
248 'labels' => array(), |
|
249 'description' => '', |
|
250 'public' => true, |
|
251 'publicly_queryable' => null, |
|
252 'hierarchical' => false, |
|
253 'show_ui' => null, |
|
254 'show_in_menu' => null, |
|
255 'show_in_nav_menus' => null, |
|
256 'show_tagcloud' => null, |
|
257 'show_in_quick_edit' => null, |
|
258 'show_admin_column' => false, |
|
259 'meta_box_cb' => null, |
|
260 'capabilities' => array(), |
|
261 'rewrite' => true, |
|
262 'query_var' => $this->name, |
|
263 'update_count_callback' => '', |
|
264 'show_in_rest' => false, |
|
265 'rest_base' => false, |
|
266 'rest_controller_class' => false, |
|
267 '_builtin' => false, |
|
268 ); |
|
269 |
|
270 $args = array_merge( $defaults, $args ); |
|
271 |
|
272 // If not set, default to the setting for public. |
|
273 if ( null === $args['publicly_queryable'] ) { |
|
274 $args['publicly_queryable'] = $args['public']; |
|
275 } |
|
276 |
|
277 if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) ) { |
|
278 if ( true === $args['query_var'] ) { |
|
279 $args['query_var'] = $this->name; |
|
280 } else { |
|
281 $args['query_var'] = sanitize_title_with_dashes( $args['query_var'] ); |
|
282 } |
|
283 } else { |
|
284 // Force query_var to false for non-public taxonomies. |
|
285 $args['query_var'] = false; |
|
286 } |
|
287 |
|
288 if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { |
|
289 $args['rewrite'] = wp_parse_args( $args['rewrite'], array( |
|
290 'with_front' => true, |
|
291 'hierarchical' => false, |
|
292 'ep_mask' => EP_NONE, |
|
293 ) ); |
|
294 |
|
295 if ( empty( $args['rewrite']['slug'] ) ) { |
|
296 $args['rewrite']['slug'] = sanitize_title_with_dashes( $this->name ); |
|
297 } |
|
298 } |
|
299 |
|
300 // If not set, default to the setting for public. |
|
301 if ( null === $args['show_ui'] ) { |
|
302 $args['show_ui'] = $args['public']; |
|
303 } |
|
304 |
|
305 // If not set, default to the setting for show_ui. |
|
306 if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) { |
|
307 $args['show_in_menu'] = $args['show_ui']; |
|
308 } |
|
309 |
|
310 // If not set, default to the setting for public. |
|
311 if ( null === $args['show_in_nav_menus'] ) { |
|
312 $args['show_in_nav_menus'] = $args['public']; |
|
313 } |
|
314 |
|
315 // If not set, default to the setting for show_ui. |
|
316 if ( null === $args['show_tagcloud'] ) { |
|
317 $args['show_tagcloud'] = $args['show_ui']; |
|
318 } |
|
319 |
|
320 // If not set, default to the setting for show_ui. |
|
321 if ( null === $args['show_in_quick_edit'] ) { |
|
322 $args['show_in_quick_edit'] = $args['show_ui']; |
|
323 } |
|
324 |
|
325 $default_caps = array( |
|
326 'manage_terms' => 'manage_categories', |
|
327 'edit_terms' => 'manage_categories', |
|
328 'delete_terms' => 'manage_categories', |
|
329 'assign_terms' => 'edit_posts', |
|
330 ); |
|
331 |
|
332 $args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] ); |
|
333 unset( $args['capabilities'] ); |
|
334 |
|
335 $args['object_type'] = array_unique( (array) $object_type ); |
|
336 |
|
337 // If not set, use the default meta box |
|
338 if ( null === $args['meta_box_cb'] ) { |
|
339 if ( $args['hierarchical'] ) { |
|
340 $args['meta_box_cb'] = 'post_categories_meta_box'; |
|
341 } else { |
|
342 $args['meta_box_cb'] = 'post_tags_meta_box'; |
|
343 } |
|
344 } |
|
345 |
|
346 $args['name'] = $this->name; |
|
347 |
|
348 foreach ( $args as $property_name => $property_value ) { |
|
349 $this->$property_name = $property_value; |
|
350 } |
|
351 |
|
352 $this->labels = get_taxonomy_labels( $this ); |
|
353 $this->label = $this->labels->name; |
|
354 } |
|
355 |
|
356 /** |
|
357 * Adds the necessary rewrite rules for the taxonomy. |
|
358 * |
|
359 * @since 4.7.0 |
|
360 * |
|
361 * @global WP $wp Current WordPress environment instance. |
|
362 */ |
|
363 public function add_rewrite_rules() { |
|
364 /* @var WP $wp */ |
|
365 global $wp; |
|
366 |
|
367 // Non-publicly queryable taxonomies should not register query vars, except in the admin. |
|
368 if ( false !== $this->query_var && $wp ) { |
|
369 $wp->add_query_var( $this->query_var ); |
|
370 } |
|
371 |
|
372 if ( false !== $this->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) { |
|
373 if ( $this->hierarchical && $this->rewrite['hierarchical'] ) { |
|
374 $tag = '(.+?)'; |
|
375 } else { |
|
376 $tag = '([^/]+)'; |
|
377 } |
|
378 |
|
379 add_rewrite_tag( "%$this->name%", $tag, $this->query_var ? "{$this->query_var}=" : "taxonomy=$this->name&term=" ); |
|
380 add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $this->rewrite ); |
|
381 } |
|
382 } |
|
383 |
|
384 /** |
|
385 * Removes any rewrite rules, permastructs, and rules for the taxonomy. |
|
386 * |
|
387 * @since 4.7.0 |
|
388 * |
|
389 * @global WP $wp Current WordPress environment instance. |
|
390 */ |
|
391 public function remove_rewrite_rules() { |
|
392 /* @var WP $wp */ |
|
393 global $wp; |
|
394 |
|
395 // Remove query var. |
|
396 if ( false !== $this->query_var ) { |
|
397 $wp->remove_query_var( $this->query_var ); |
|
398 } |
|
399 |
|
400 // Remove rewrite tags and permastructs. |
|
401 if ( false !== $this->rewrite ) { |
|
402 remove_rewrite_tag( "%$this->name%" ); |
|
403 remove_permastruct( $this->name ); |
|
404 } |
|
405 } |
|
406 |
|
407 /** |
|
408 * Registers the ajax callback for the meta box. |
|
409 * |
|
410 * @since 4.7.0 |
|
411 */ |
|
412 public function add_hooks() { |
|
413 add_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' ); |
|
414 } |
|
415 |
|
416 /** |
|
417 * Removes the ajax callback for the meta box. |
|
418 * |
|
419 * @since 4.7.0 |
|
420 */ |
|
421 public function remove_hooks() { |
|
422 remove_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' ); |
|
423 } |
|
424 } |