Projects : mp-wp : mp-wp_genesis
1 | <?php |
2 | /** |
3 | * Taxonomy API |
4 | * |
5 | * @package WordPress |
6 | * @subpackage Taxonomy |
7 | * @since 2.3.0 |
8 | */ |
9 | |
10 | // |
11 | // Taxonomy Registration |
12 | // |
13 | |
14 | /** |
15 | * Default Taxonomy Objects |
16 | * @since 2.3.0 |
17 | * @global array $wp_taxonomies |
18 | */ |
19 | $wp_taxonomies = array(); |
20 | $wp_taxonomies['category'] = (object) array('name' => 'category', 'object_type' => 'post', 'hierarchical' => true, 'update_count_callback' => '_update_post_term_count'); |
21 | $wp_taxonomies['post_tag'] = (object) array('name' => 'post_tag', 'object_type' => 'post', 'hierarchical' => false, 'update_count_callback' => '_update_post_term_count'); |
22 | $wp_taxonomies['link_category'] = (object) array('name' => 'link_category', 'object_type' => 'link', 'hierarchical' => false); |
23 | |
24 | /** |
25 | * Return all of the taxonomy names that are of $object_type. |
26 | * |
27 | * It appears that this function can be used to find all of the names inside of |
28 | * $wp_taxonomies global variable. |
29 | * |
30 | * <code><?php $taxonomies = get_object_taxonomies('post'); ?></code> Should |
31 | * result in <code>Array('category', 'post_tag')</code> |
32 | * |
33 | * @package WordPress |
34 | * @subpackage Taxonomy |
35 | * @since 2.3.0 |
36 | * |
37 | * @uses $wp_taxonomies |
38 | * |
39 | * @param array|string|object $object Name of the type of taxonomy object, or an object (row from posts) |
40 | * @return array The names of all taxonomy of $object_type. |
41 | */ |
42 | function get_object_taxonomies($object) { |
43 | global $wp_taxonomies; |
44 | |
45 | if ( is_object($object) ) { |
46 | if ( $object->post_type == 'attachment' ) |
47 | return get_attachment_taxonomies($object); |
48 | $object = $object->post_type; |
49 | } |
50 | |
51 | $object = (array) $object; |
52 | |
53 | $taxonomies = array(); |
54 | foreach ( (array) $wp_taxonomies as $taxonomy ) { |
55 | if ( array_intersect($object, (array) $taxonomy->object_type) ) |
56 | $taxonomies[] = $taxonomy->name; |
57 | } |
58 | |
59 | return $taxonomies; |
60 | } |
61 | |
62 | /** |
63 | * Retrieves the taxonomy object of $taxonomy. |
64 | * |
65 | * The get_taxonomy function will first check that the parameter string given |
66 | * is a taxonomy object and if it is, it will return it. |
67 | * |
68 | * @package WordPress |
69 | * @subpackage Taxonomy |
70 | * @since 2.3.0 |
71 | * |
72 | * @uses $wp_taxonomies |
73 | * @uses is_taxonomy() Checks whether taxonomy exists |
74 | * |
75 | * @param string $taxonomy Name of taxonomy object to return |
76 | * @return object|bool The Taxonomy Object or false if $taxonomy doesn't exist |
77 | */ |
78 | function get_taxonomy( $taxonomy ) { |
79 | global $wp_taxonomies; |
80 | |
81 | if ( ! is_taxonomy($taxonomy) ) |
82 | return false; |
83 | |
84 | return $wp_taxonomies[$taxonomy]; |
85 | } |
86 | |
87 | /** |
88 | * Checks that the taxonomy name exists. |
89 | * |
90 | * @package WordPress |
91 | * @subpackage Taxonomy |
92 | * @since 2.3.0 |
93 | * |
94 | * @uses $wp_taxonomies |
95 | * |
96 | * @param string $taxonomy Name of taxonomy object |
97 | * @return bool Whether the taxonomy exists or not. |
98 | */ |
99 | function is_taxonomy( $taxonomy ) { |
100 | global $wp_taxonomies; |
101 | |
102 | return isset($wp_taxonomies[$taxonomy]); |
103 | } |
104 | |
105 | /** |
106 | * Whether the taxonomy object is hierarchical. |
107 | * |
108 | * Checks to make sure that the taxonomy is an object first. Then Gets the |
109 | * object, and finally returns the hierarchical value in the object. |
110 | * |
111 | * A false return value might also mean that the taxonomy does not exist. |
112 | * |
113 | * @package WordPress |
114 | * @subpackage Taxonomy |
115 | * @since 2.3.0 |
116 | * |
117 | * @uses is_taxonomy() Checks whether taxonomy exists |
118 | * @uses get_taxonomy() Used to get the taxonomy object |
119 | * |
120 | * @param string $taxonomy Name of taxonomy object |
121 | * @return bool Whether the taxonomy is hierarchical |
122 | */ |
123 | function is_taxonomy_hierarchical($taxonomy) { |
124 | if ( ! is_taxonomy($taxonomy) ) |
125 | return false; |
126 | |
127 | $taxonomy = get_taxonomy($taxonomy); |
128 | return $taxonomy->hierarchical; |
129 | } |
130 | |
131 | /** |
132 | * Create or modify a taxonomy object. Do not use before init. |
133 | * |
134 | * A simple function for creating or modifying a taxonomy object based on the |
135 | * parameters given. The function will accept an array (third optional |
136 | * parameter), along with strings for the taxonomy name and another string for |
137 | * the object type. |
138 | * |
139 | * Nothing is returned, so expect error maybe or use is_taxonomy() to check |
140 | * whether taxonomy exists. |
141 | * |
142 | * Optional $args contents: |
143 | * |
144 | * hierarachical - has some defined purpose at other parts of the API and is a |
145 | * boolean value. |
146 | * |
147 | * update_count_callback - works much like a hook, in that it will be called |
148 | * when the count is updated. |
149 | * |
150 | * rewrite - false to prevent rewrite, or array('slug'=>$slug) to customize |
151 | * permastruct; default will use $taxonomy as slug. |
152 | * |
153 | * query_var - false to prevent queries, or string to customize query var |
154 | * (?$query_var=$term); default will use $taxonomy as query var. |
155 | * |
156 | * @package WordPress |
157 | * @subpackage Taxonomy |
158 | * @since 2.3.0 |
159 | * @uses $wp_taxonomies Inserts new taxonomy object into the list |
160 | * @uses $wp_rewrite Adds rewrite tags and permastructs |
161 | * @uses $wp Adds query vars |
162 | * |
163 | * @param string $taxonomy Name of taxonomy object |
164 | * @param array|string $object_type Name of the object type for the taxonomy object. |
165 | * @param array|string $args See above description for the two keys values. |
166 | */ |
167 | function register_taxonomy( $taxonomy, $object_type, $args = array() ) { |
168 | global $wp_taxonomies, $wp_rewrite, $wp; |
169 | |
170 | $defaults = array('hierarchical' => false, 'update_count_callback' => '', 'rewrite' => true, 'query_var' => true); |
171 | $args = wp_parse_args($args, $defaults); |
172 | |
173 | if ( false !== $args['query_var'] && !empty($wp) ) { |
174 | if ( true === $args['query_var'] ) |
175 | $args['query_var'] = $taxonomy; |
176 | $args['query_var'] = sanitize_title_with_dashes($args['query_var']); |
177 | $wp->add_query_var($args['query_var']); |
178 | } |
179 | |
180 | if ( false !== $args['rewrite'] && !empty($wp_rewrite) ) { |
181 | if ( !is_array($args['rewrite']) ) |
182 | $args['rewrite'] = array(); |
183 | if ( !isset($args['rewrite']['slug']) ) |
184 | $args['rewrite']['slug'] = sanitize_title_with_dashes($taxonomy); |
185 | $wp_rewrite->add_rewrite_tag("%$taxonomy%", '([^/]+)', $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term=$term"); |
186 | $wp_rewrite->add_permastruct($taxonomy, "{$args['rewrite']['slug']}/%$taxonomy%"); |
187 | } |
188 | |
189 | $args['name'] = $taxonomy; |
190 | $args['object_type'] = $object_type; |
191 | $wp_taxonomies[$taxonomy] = (object) $args; |
192 | } |
193 | |
194 | // |
195 | // Term API |
196 | // |
197 | |
198 | /** |
199 | * Retrieve object_ids of valid taxonomy and term. |
200 | * |
201 | * The strings of $taxonomies must exist before this function will continue. On |
202 | * failure of finding a valid taxonomy, it will return an WP_Error class, kind |
203 | * of like Exceptions in PHP 5, except you can't catch them. Even so, you can |
204 | * still test for the WP_Error class and get the error message. |
205 | * |
206 | * The $terms aren't checked the same as $taxonomies, but still need to exist |
207 | * for $object_ids to be returned. |
208 | * |
209 | * It is possible to change the order that object_ids is returned by either |
210 | * using PHP sort family functions or using the database by using $args with |
211 | * either ASC or DESC array. The value should be in the key named 'order'. |
212 | * |
213 | * @package WordPress |
214 | * @subpackage Taxonomy |
215 | * @since 2.3.0 |
216 | * |
217 | * @uses $wpdb |
218 | * @uses wp_parse_args() Creates an array from string $args. |
219 | * |
220 | * @param string|array $terms String of term or array of string values of terms that will be used |
221 | * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names |
222 | * @param array|string $args Change the order of the object_ids, either ASC or DESC |
223 | * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success |
224 | * the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found. |
225 | */ |
226 | function get_objects_in_term( $terms, $taxonomies, $args = array() ) { |
227 | global $wpdb; |
228 | |
229 | if ( !is_array( $terms) ) |
230 | $terms = array($terms); |
231 | |
232 | if ( !is_array($taxonomies) ) |
233 | $taxonomies = array($taxonomies); |
234 | |
235 | foreach ( (array) $taxonomies as $taxonomy ) { |
236 | if ( ! is_taxonomy($taxonomy) ) |
237 | return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); |
238 | } |
239 | |
240 | $defaults = array('order' => 'ASC'); |
241 | $args = wp_parse_args( $args, $defaults ); |
242 | extract($args, EXTR_SKIP); |
243 | |
244 | $order = ( 'desc' == strtolower($order) ) ? 'DESC' : 'ASC'; |
245 | |
246 | $terms = array_map('intval', $terms); |
247 | |
248 | $taxonomies = "'" . implode("', '", $taxonomies) . "'"; |
249 | $terms = "'" . implode("', '", $terms) . "'"; |
250 | |
251 | $object_ids = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($terms) ORDER BY tr.object_id $order"); |
252 | |
253 | if ( ! $object_ids ) |
254 | return array(); |
255 | |
256 | return $object_ids; |
257 | } |
258 | |
259 | /** |
260 | * Get all Term data from database by Term ID. |
261 | * |
262 | * The usage of the get_term function is to apply filters to a term object. It |
263 | * is possible to get a term object from the database before applying the |
264 | * filters. |
265 | * |
266 | * $term ID must be part of $taxonomy, to get from the database. Failure, might |
267 | * be able to be captured by the hooks. Failure would be the same value as $wpdb |
268 | * returns for the get_row method. |
269 | * |
270 | * There are two hooks, one is specifically for each term, named 'get_term', and |
271 | * the second is for the taxonomy name, 'term_$taxonomy'. Both hooks gets the |
272 | * term object, and the taxonomy name as parameters. Both hooks are expected to |
273 | * return a Term object. |
274 | * |
275 | * 'get_term' hook - Takes two parameters the term Object and the taxonomy name. |
276 | * Must return term object. Used in get_term() as a catch-all filter for every |
277 | * $term. |
278 | * |
279 | * 'get_$taxonomy' hook - Takes two parameters the term Object and the taxonomy |
280 | * name. Must return term object. $taxonomy will be the taxonomy name, so for |
281 | * example, if 'category', it would be 'get_category' as the filter name. Useful |
282 | * for custom taxonomies or plugging into default taxonomies. |
283 | * |
284 | * @package WordPress |
285 | * @subpackage Taxonomy |
286 | * @since 2.3.0 |
287 | * |
288 | * @uses $wpdb |
289 | * @uses sanitize_term() Cleanses the term based on $filter context before returning. |
290 | * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. |
291 | * |
292 | * @param int|object $term If integer, will get from database. If object will apply filters and return $term. |
293 | * @param string $taxonomy Taxonomy name that $term is part of. |
294 | * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N |
295 | * @param string $filter Optional, default is raw or no WordPress defined filter will applied. |
296 | * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not |
297 | * exist then WP_Error will be returned. |
298 | */ |
299 | function &get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { |
300 | global $wpdb; |
301 | |
302 | if ( empty($term) ) { |
303 | $error = new WP_Error('invalid_term', __('Empty Term')); |
304 | return $error; |
305 | } |
306 | |
307 | if ( ! is_taxonomy($taxonomy) ) { |
308 | $error = new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); |
309 | return $error; |
310 | } |
311 | |
312 | if ( is_object($term) && empty($term->filter) ) { |
313 | wp_cache_add($term->term_id, $term, $taxonomy); |
314 | $_term = $term; |
315 | } else { |
316 | if ( is_object($term) ) |
317 | $term = $term->term_id; |
318 | $term = (int) $term; |
319 | if ( ! $_term = wp_cache_get($term, $taxonomy) ) { |
320 | $_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND t.term_id = %s LIMIT 1", $taxonomy, $term) ); |
321 | wp_cache_add($term, $_term, $taxonomy); |
322 | } |
323 | } |
324 | |
325 | $_term = apply_filters('get_term', $_term, $taxonomy); |
326 | $_term = apply_filters("get_$taxonomy", $_term, $taxonomy); |
327 | $_term = sanitize_term($_term, $taxonomy, $filter); |
328 | |
329 | if ( $output == OBJECT ) { |
330 | return $_term; |
331 | } elseif ( $output == ARRAY_A ) { |
332 | $__term = get_object_vars($_term); |
333 | return $__term; |
334 | } elseif ( $output == ARRAY_N ) { |
335 | $__term = array_values(get_object_vars($_term)); |
336 | return $__term; |
337 | } else { |
338 | return $_term; |
339 | } |
340 | } |
341 | |
342 | /** |
343 | * Get all Term data from database by Term field and data. |
344 | * |
345 | * Warning: $value is not escaped for 'name' $field. You must do it yourself, if |
346 | * required. |
347 | * |
348 | * The default $field is 'id', therefore it is possible to also use null for |
349 | * field, but not recommended that you do so. |
350 | * |
351 | * If $value does not exist, the return value will be false. If $taxonomy exists |
352 | * and $field and $value combinations exist, the Term will be returned. |
353 | * |
354 | * @package WordPress |
355 | * @subpackage Taxonomy |
356 | * @since 2.3.0 |
357 | * |
358 | * @uses $wpdb |
359 | * @uses sanitize_term() Cleanses the term based on $filter context before returning. |
360 | * @see sanitize_term_field() The $context param lists the available values for get_term_by() $filter param. |
361 | * |
362 | * @param string $field Either 'slug', 'name', or 'id' |
363 | * @param string|int $value Search for this term value |
364 | * @param string $taxonomy Taxonomy Name |
365 | * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N |
366 | * @param string $filter Optional, default is raw or no WordPress defined filter will applied. |
367 | * @return mixed Term Row from database. Will return false if $taxonomy does not exist or $term was not found. |
368 | */ |
369 | function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw') { |
370 | global $wpdb; |
371 | |
372 | if ( ! is_taxonomy($taxonomy) ) |
373 | return false; |
374 | |
375 | if ( 'slug' == $field ) { |
376 | $field = 't.slug'; |
377 | $value = sanitize_title($value); |
378 | if ( empty($value) ) |
379 | return false; |
380 | } else if ( 'name' == $field ) { |
381 | // Assume already escaped |
382 | $value = stripslashes($value); |
383 | $field = 't.name'; |
384 | } else { |
385 | $field = 't.term_id'; |
386 | $value = (int) $value; |
387 | } |
388 | |
389 | $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND $field = %s LIMIT 1", $taxonomy, $value) ); |
390 | if ( !$term ) |
391 | return false; |
392 | |
393 | wp_cache_add($term->term_id, $term, $taxonomy); |
394 | |
395 | $term = sanitize_term($term, $taxonomy, $filter); |
396 | |
397 | if ( $output == OBJECT ) { |
398 | return $term; |
399 | } elseif ( $output == ARRAY_A ) { |
400 | return get_object_vars($term); |
401 | } elseif ( $output == ARRAY_N ) { |
402 | return array_values(get_object_vars($term)); |
403 | } else { |
404 | return $term; |
405 | } |
406 | } |
407 | |
408 | /** |
409 | * Merge all term children into a single array. |
410 | * |
411 | * This recursive function will merge all of the children of $term into the same |
412 | * array. Only useful for taxonomies which are hierarchical. |
413 | * |
414 | * Will return an empty array if $term does not exist in $taxonomy. |
415 | * |
416 | * @package WordPress |
417 | * @subpackage Taxonomy |
418 | * @since 2.3.0 |
419 | * |
420 | * @uses $wpdb |
421 | * @uses _get_term_hierarchy() |
422 | * @uses get_term_children() Used to get the children of both $taxonomy and the parent $term |
423 | * |
424 | * @param string $term Name of Term to get children |
425 | * @param string $taxonomy Taxonomy Name |
426 | * @return array|WP_Error List of Term Objects. WP_Error returned if $taxonomy does not exist |
427 | */ |
428 | function get_term_children( $term, $taxonomy ) { |
429 | if ( ! is_taxonomy($taxonomy) ) |
430 | return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); |
431 | |
432 | $terms = _get_term_hierarchy($taxonomy); |
433 | |
434 | if ( ! isset($terms[$term]) ) |
435 | return array(); |
436 | |
437 | $children = $terms[$term]; |
438 | |
439 | foreach ( (array) $terms[$term] as $child ) { |
440 | if ( isset($terms[$child]) ) |
441 | $children = array_merge($children, get_term_children($child, $taxonomy)); |
442 | } |
443 | |
444 | return $children; |
445 | } |
446 | |
447 | /** |
448 | * Get sanitized Term field. |
449 | * |
450 | * Does checks for $term, based on the $taxonomy. The function is for contextual |
451 | * reasons and for simplicity of usage. See sanitize_term_field() for more |
452 | * information. |
453 | * |
454 | * @package WordPress |
455 | * @subpackage Taxonomy |
456 | * @since 2.3.0 |
457 | * |
458 | * @uses sanitize_term_field() Passes the return value in sanitize_term_field on success. |
459 | * |
460 | * @param string $field Term field to fetch |
461 | * @param int $term Term ID |
462 | * @param string $taxonomy Taxonomy Name |
463 | * @param string $context Optional, default is display. Look at sanitize_term_field() for available options. |
464 | * @return mixed Will return an empty string if $term is not an object or if $field is not set in $term. |
465 | */ |
466 | function get_term_field( $field, $term, $taxonomy, $context = 'display' ) { |
467 | $term = (int) $term; |
468 | $term = get_term( $term, $taxonomy ); |
469 | if ( is_wp_error($term) ) |
470 | return $term; |
471 | |
472 | if ( !is_object($term) ) |
473 | return ''; |
474 | |
475 | if ( !isset($term->$field) ) |
476 | return ''; |
477 | |
478 | return sanitize_term_field($field, $term->$field, $term->term_id, $taxonomy, $context); |
479 | } |
480 | |
481 | /** |
482 | * Sanitizes Term for editing. |
483 | * |
484 | * Return value is sanitize_term() and usage is for sanitizing the term for |
485 | * editing. Function is for contextual and simplicity. |
486 | * |
487 | * @package WordPress |
488 | * @subpackage Taxonomy |
489 | * @since 2.3.0 |
490 | * |
491 | * @uses sanitize_term() Passes the return value on success |
492 | * |
493 | * @param int|object $id Term ID or Object |
494 | * @param string $taxonomy Taxonomy Name |
495 | * @return mixed|null|WP_Error Will return empty string if $term is not an object. |
496 | */ |
497 | function get_term_to_edit( $id, $taxonomy ) { |
498 | $term = get_term( $id, $taxonomy ); |
499 | |
500 | if ( is_wp_error($term) ) |
501 | return $term; |
502 | |
503 | if ( !is_object($term) ) |
504 | return ''; |
505 | |
506 | return sanitize_term($term, $taxonomy, 'edit'); |
507 | } |
508 | |
509 | /** |
510 | * Retrieve the terms in a given taxonomy or list of taxonomies. |
511 | * |
512 | * You can fully inject any customizations to the query before it is sent, as |
513 | * well as control the output with a filter. |
514 | * |
515 | * The 'get_terms' filter will be called when the cache has the term and will |
516 | * pass the found term along with the array of $taxonomies and array of $args. |
517 | * This filter is also called before the array of terms is passed and will pass |
518 | * the array of terms, along with the $taxonomies and $args. |
519 | * |
520 | * The 'list_terms_exclusions' filter passes the compiled exclusions along with |
521 | * the $args. |
522 | * |
523 | * The list of arguments that $args can contain, which will overwrite the defaults: |
524 | * |
525 | * orderby - Default is 'name'. Can be name, count, or nothing (will use |
526 | * term_id). |
527 | * |
528 | * order - Default is ASC. Can use DESC. |
529 | * |
530 | * hide_empty - Default is true. Will not return empty terms, which means |
531 | * terms whose count is 0 according to the given taxonomy. |
532 | * |
533 | * exclude - Default is an empty string. A comma- or space-delimited string |
534 | * of term ids to exclude from the return array. If 'include' is non-empty, |
535 | * 'exclude' is ignored. |
536 | * |
537 | * include - Default is an empty string. A comma- or space-delimited string |
538 | * of term ids to include in the return array. |
539 | * |
540 | * number - The maximum number of terms to return. Default is empty. |
541 | * |
542 | * offset - The number by which to offset the terms query. |
543 | * |
544 | * fields - Default is 'all', which returns an array of term objects. |
545 | * If 'fields' is 'ids' or 'names', returns an array of |
546 | * integers or strings, respectively. |
547 | * |
548 | * slug - Returns terms whose "slug" matches this value. Default is empty string. |
549 | * |
550 | * hierarchical - Whether to include terms that have non-empty descendants |
551 | * (even if 'hide_empty' is set to true). |
552 | * |
553 | * search - Returned terms' names will contain the value of 'search', |
554 | * case-insensitive. Default is an empty string. |
555 | * |
556 | * name__like - Returned terms' names will begin with the value of 'name__like', |
557 | * case-insensitive. Default is empty string. |
558 | * |
559 | * The argument 'pad_counts', if set to true will include the quantity of a term's |
560 | * children in the quantity of each term's "count" object variable. |
561 | * |
562 | * The 'get' argument, if set to 'all' instead of its default empty string, |
563 | * returns terms regardless of ancestry or whether the terms are empty. |
564 | * |
565 | * The 'child_of' argument, when used, should be set to the integer of a term ID. Its default |
566 | * is 0. If set to a non-zero value, all returned terms will be descendants |
567 | * of that term according to the given taxonomy. Hence 'child_of' is set to 0 |
568 | * if more than one taxonomy is passed in $taxonomies, because multiple taxonomies |
569 | * make term ancestry ambiguous. |
570 | * |
571 | * The 'parent' argument, when used, should be set to the integer of a term ID. Its default is |
572 | * the empty string '', which has a different meaning from the integer 0. |
573 | * If set to an integer value, all returned terms will have as an immediate |
574 | * ancestor the term whose ID is specified by that integer according to the given taxonomy. |
575 | * The 'parent' argument is different from 'child_of' in that a term X is considered a 'parent' |
576 | * of term Y only if term X is the father of term Y, not its grandfather or great-grandfather, etc. |
577 | * |
578 | * @package WordPress |
579 | * @subpackage Taxonomy |
580 | * @since 2.3.0 |
581 | * |
582 | * @uses $wpdb |
583 | * @uses wp_parse_args() Merges the defaults with those defined by $args and allows for strings. |
584 | * |
585 | * @param string|array Taxonomy name or list of Taxonomy names |
586 | * @param string|array $args The values of what to search for when returning terms |
587 | * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist. |
588 | */ |
589 | function &get_terms($taxonomies, $args = '') { |
590 | global $wpdb; |
591 | $empty_array = array(); |
592 | |
593 | $single_taxonomy = false; |
594 | if ( !is_array($taxonomies) ) { |
595 | $single_taxonomy = true; |
596 | $taxonomies = array($taxonomies); |
597 | } |
598 | |
599 | foreach ( (array) $taxonomies as $taxonomy ) { |
600 | if ( ! is_taxonomy($taxonomy) ) |
601 | return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); |
602 | } |
603 | |
604 | $in_taxonomies = "'" . implode("', '", $taxonomies) . "'"; |
605 | |
606 | $defaults = array('orderby' => 'name', 'order' => 'ASC', |
607 | 'hide_empty' => true, 'exclude' => '', 'include' => '', |
608 | 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', |
609 | 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', |
610 | 'pad_counts' => false, 'offset' => '', 'search' => ''); |
611 | $args = wp_parse_args( $args, $defaults ); |
612 | $args['number'] = absint( $args['number'] ); |
613 | $args['offset'] = absint( $args['offset'] ); |
614 | if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || |
615 | '' != $args['parent'] ) { |
616 | $args['child_of'] = 0; |
617 | $args['hierarchical'] = false; |
618 | $args['pad_counts'] = false; |
619 | } |
620 | |
621 | if ( 'all' == $args['get'] ) { |
622 | $args['child_of'] = 0; |
623 | $args['hide_empty'] = 0; |
624 | $args['hierarchical'] = false; |
625 | $args['pad_counts'] = false; |
626 | } |
627 | extract($args, EXTR_SKIP); |
628 | |
629 | if ( $child_of ) { |
630 | $hierarchy = _get_term_hierarchy($taxonomies[0]); |
631 | if ( !isset($hierarchy[$child_of]) ) |
632 | return $empty_array; |
633 | } |
634 | |
635 | if ( $parent ) { |
636 | $hierarchy = _get_term_hierarchy($taxonomies[0]); |
637 | if ( !isset($hierarchy[$parent]) ) |
638 | return $empty_array; |
639 | } |
640 | |
641 | // $args can be whatever, only use the args defined in defaults to compute the key |
642 | $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : ''; |
643 | $key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key ); |
644 | $last_changed = wp_cache_get('last_changed', 'terms'); |
645 | if ( !$last_changed ) { |
646 | $last_changed = time(); |
647 | wp_cache_set('last_changed', $last_changed, 'terms'); |
648 | } |
649 | $cache_key = "get_terms:$key:$last_changed"; |
650 | |
651 | if ( $cache = wp_cache_get( $cache_key, 'terms' ) ) { |
652 | $terms = apply_filters('get_terms', $cache, $taxonomies, $args); |
653 | return $terms; |
654 | } |
655 | |
656 | if ( 'count' == $orderby ) |
657 | $orderby = 'tt.count'; |
658 | else if ( 'name' == $orderby ) |
659 | $orderby = 't.name'; |
660 | else if ( 'slug' == $orderby ) |
661 | $orderby = 't.slug'; |
662 | else if ( 'term_group' == $orderby ) |
663 | $orderby = 't.term_group'; |
664 | else |
665 | $orderby = 't.term_id'; |
666 | |
667 | $where = ''; |
668 | $inclusions = ''; |
669 | if ( !empty($include) ) { |
670 | $exclude = ''; |
671 | $interms = preg_split('/[\s,]+/',$include); |
672 | if ( count($interms) ) { |
673 | foreach ( (array) $interms as $interm ) { |
674 | if (empty($inclusions)) |
675 | $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' '; |
676 | else |
677 | $inclusions .= ' OR t.term_id = ' . intval($interm) . ' '; |
678 | } |
679 | } |
680 | } |
681 | |
682 | if ( !empty($inclusions) ) |
683 | $inclusions .= ')'; |
684 | $where .= $inclusions; |
685 | |
686 | $exclusions = ''; |
687 | if ( !empty($exclude) ) { |
688 | $exterms = preg_split('/[\s,]+/',$exclude); |
689 | if ( count($exterms) ) { |
690 | foreach ( (array) $exterms as $exterm ) { |
691 | if (empty($exclusions)) |
692 | $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; |
693 | else |
694 | $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' '; |
695 | } |
696 | } |
697 | } |
698 | |
699 | if ( !empty($exclusions) ) |
700 | $exclusions .= ')'; |
701 | $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args ); |
702 | $where .= $exclusions; |
703 | |
704 | if ( !empty($slug) ) { |
705 | $slug = sanitize_title($slug); |
706 | $where .= " AND t.slug = '$slug'"; |
707 | } |
708 | |
709 | if ( !empty($name__like) ) |
710 | $where .= " AND t.name LIKE '{$name__like}%'"; |
711 | |
712 | if ( '' != $parent ) { |
713 | $parent = (int) $parent; |
714 | $where .= " AND tt.parent = '$parent'"; |
715 | } |
716 | |
717 | if ( $hide_empty && !$hierarchical ) |
718 | $where .= ' AND tt.count > 0'; |
719 | |
720 | if ( !empty($number) ) { |
721 | if( $offset ) |
722 | $number = 'LIMIT ' . $offset . ',' . $number; |
723 | else |
724 | $number = 'LIMIT ' . $number; |
725 | |
726 | } else |
727 | $number = ''; |
728 | |
729 | if ( !empty($search) ) { |
730 | $search = like_escape($search); |
731 | $where .= " AND (t.name LIKE '%$search%')"; |
732 | } |
733 | |
734 | $select_this = ''; |
735 | if ( 'all' == $fields ) |
736 | $select_this = 't.*, tt.*'; |
737 | else if ( 'ids' == $fields ) |
738 | $select_this = 't.term_id, tt.parent, tt.count'; |
739 | else if ( 'names' == $fields ) |
740 | $select_this = 't.term_id, tt.parent, tt.count, t.name'; |
741 | |
742 | $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ($in_taxonomies) $where ORDER BY $orderby $order $number"; |
743 | |
744 | if ( 'all' == $fields ) { |
745 | $terms = $wpdb->get_results($query); |
746 | update_term_cache($terms); |
747 | } else if ( ('ids' == $fields) || ('names' == $fields) ) { |
748 | $terms = $wpdb->get_results($query); |
749 | } |
750 | |
751 | if ( empty($terms) ) { |
752 | $cache[ $key ] = array(); |
753 | wp_cache_set( 'get_terms', $cache, 'terms' ); |
754 | $terms = apply_filters('get_terms', array(), $taxonomies, $args); |
755 | return $terms; |
756 | } |
757 | |
758 | if ( $child_of ) { |
759 | $children = _get_term_hierarchy($taxonomies[0]); |
760 | if ( ! empty($children) ) |
761 | $terms = & _get_term_children($child_of, $terms, $taxonomies[0]); |
762 | } |
763 | |
764 | // Update term counts to include children. |
765 | if ( $pad_counts && 'all' == $fields ) |
766 | _pad_term_counts($terms, $taxonomies[0]); |
767 | |
768 | // Make sure we show empty categories that have children. |
769 | if ( $hierarchical && $hide_empty && is_array($terms) ) { |
770 | foreach ( $terms as $k => $term ) { |
771 | if ( ! $term->count ) { |
772 | $children = _get_term_children($term->term_id, $terms, $taxonomies[0]); |
773 | if( is_array($children) ) |
774 | foreach ( $children as $child ) |
775 | if ( $child->count ) |
776 | continue 2; |
777 | |
778 | // It really is empty |
779 | unset($terms[$k]); |
780 | } |
781 | } |
782 | } |
783 | reset ( $terms ); |
784 | |
785 | $_terms = array(); |
786 | if ( 'ids' == $fields ) { |
787 | while ( $term = array_shift($terms) ) |
788 | $_terms[] = $term->term_id; |
789 | $terms = $_terms; |
790 | } elseif ( 'names' == $fields ) { |
791 | while ( $term = array_shift($terms) ) |
792 | $_terms[] = $term->name; |
793 | $terms = $_terms; |
794 | } |
795 | |
796 | wp_cache_add( $cache_key, $terms, 'terms' ); |
797 | |
798 | $terms = apply_filters('get_terms', $terms, $taxonomies, $args); |
799 | return $terms; |
800 | } |
801 | |
802 | /** |
803 | * Check if Term exists. |
804 | * |
805 | * Returns the index of a defined term, or 0 (false) if the term doesn't exist. |
806 | * |
807 | * @package WordPress |
808 | * @subpackage Taxonomy |
809 | * @since 2.3.0 |
810 | * |
811 | * @uses $wpdb |
812 | * |
813 | * @param int|string $term The term to check |
814 | * @param string $taxonomy The taxonomy name to use |
815 | * @return mixed Get the term id or Term Object, if exists. |
816 | */ |
817 | function is_term($term, $taxonomy = '') { |
818 | global $wpdb; |
819 | |
820 | $select = "SELECT term_id FROM $wpdb->terms as t WHERE "; |
821 | $tax_select = "SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE "; |
822 | |
823 | if ( is_int($term) ) { |
824 | if ( 0 == $term ) |
825 | return 0; |
826 | $where = 't.term_id = %d'; |
827 | if ( !empty($taxonomy) ) |
828 | return $wpdb->get_row( $wpdb->prepare( $tax_select . $where . " AND tt.taxonomy = %s", $term, $taxonomy ), ARRAY_A ); |
829 | else |
830 | return $wpdb->get_var( $wpdb->prepare( $select . $where, $term ) ); |
831 | } |
832 | |
833 | if ( '' === $slug = sanitize_title($term) ) |
834 | return 0; |
835 | |
836 | $where = 't.slug = %s'; |
837 | $else_where = 't.name = %s'; |
838 | |
839 | if ( !empty($taxonomy) ) { |
840 | if ( $result = $wpdb->get_row( $wpdb->prepare("SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $where AND tt.taxonomy = %s", $slug, $taxonomy), ARRAY_A) ) |
841 | return $result; |
842 | |
843 | return $wpdb->get_row( $wpdb->prepare("SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $else_where AND tt.taxonomy = %s", $term, $taxonomy), ARRAY_A); |
844 | } |
845 | |
846 | if ( $result = $wpdb->get_var( $wpdb->prepare("SELECT term_id FROM $wpdb->terms as t WHERE $where", $slug) ) ) |
847 | return $result; |
848 | |
849 | return $wpdb->get_var( $wpdb->prepare("SELECT term_id FROM $wpdb->terms as t WHERE $else_where", $term) ); |
850 | } |
851 | |
852 | /** |
853 | * Sanitize Term all fields. |
854 | * |
855 | * Relys on sanitize_term_field() to sanitize the term. The difference is that |
856 | * this function will sanitize <strong>all</strong> fields. The context is based |
857 | * on sanitize_term_field(). |
858 | * |
859 | * The $term is expected to be either an array or an object. |
860 | * |
861 | * @package WordPress |
862 | * @subpackage Taxonomy |
863 | * @since 2.3.0 |
864 | * |
865 | * @uses sanitize_term_field Used to sanitize all fields in a term |
866 | * |
867 | * @param array|object $term The term to check |
868 | * @param string $taxonomy The taxonomy name to use |
869 | * @param string $context Default is 'display'. |
870 | * @return array|object Term with all fields sanitized |
871 | */ |
872 | function sanitize_term($term, $taxonomy, $context = 'display') { |
873 | |
874 | if ( 'raw' == $context ) |
875 | return $term; |
876 | |
877 | $fields = array('term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group'); |
878 | |
879 | $do_object = false; |
880 | if ( is_object($term) ) |
881 | $do_object = true; |
882 | |
883 | $term_id = $do_object ? $term->term_id : (isset($term['term_id']) ? $term['term_id'] : 0); |
884 | |
885 | foreach ( (array) $fields as $field ) { |
886 | if ( $do_object ) { |
887 | if ( isset($term->$field) ) |
888 | $term->$field = sanitize_term_field($field, $term->$field, $term_id, $taxonomy, $context); |
889 | } else { |
890 | if ( isset($term[$field]) ) |
891 | $term[$field] = sanitize_term_field($field, $term[$field], $term_id, $taxonomy, $context); |
892 | } |
893 | } |
894 | |
895 | if ( $do_object ) |
896 | $term->filter = $context; |
897 | else |
898 | $term['filter'] = $context; |
899 | |
900 | return $term; |
901 | } |
902 | |
903 | /** |
904 | * Cleanse the field value in the term based on the context. |
905 | * |
906 | * Passing a term field value through the function should be assumed to have |
907 | * cleansed the value for whatever context the term field is going to be used. |
908 | * |
909 | * If no context or an unsupported context is given, then default filters will |
910 | * be applied. |
911 | * |
912 | * There are enough filters for each context to support a custom filtering |
913 | * without creating your own filter function. Simply create a function that |
914 | * hooks into the filter you need. |
915 | * |
916 | * @package WordPress |
917 | * @subpackage Taxonomy |
918 | * @since 2.3.0 |
919 | * |
920 | * @uses $wpdb |
921 | * |
922 | * @param string $field Term field to sanitize |
923 | * @param string $value Search for this term value |
924 | * @param int $term_id Term ID |
925 | * @param string $taxonomy Taxonomy Name |
926 | * @param string $context Either edit, db, display, attribute, or js. |
927 | * @return mixed sanitized field |
928 | */ |
929 | function sanitize_term_field($field, $value, $term_id, $taxonomy, $context) { |
930 | if ( 'parent' == $field || 'term_id' == $field || 'count' == $field || 'term_group' == $field ) { |
931 | $value = (int) $value; |
932 | if ( $value < 0 ) |
933 | $value = 0; |
934 | } |
935 | |
936 | if ( 'raw' == $context ) |
937 | return $value; |
938 | |
939 | if ( 'edit' == $context ) { |
940 | $value = apply_filters("edit_term_$field", $value, $term_id, $taxonomy); |
941 | $value = apply_filters("edit_${taxonomy}_$field", $value, $term_id); |
942 | if ( 'description' == $field ) |
943 | $value = format_to_edit($value); |
944 | else |
945 | $value = attribute_escape($value); |
946 | } else if ( 'db' == $context ) { |
947 | $value = apply_filters("pre_term_$field", $value, $taxonomy); |
948 | $value = apply_filters("pre_${taxonomy}_$field", $value); |
949 | // Back compat filters |
950 | if ( 'slug' == $field ) |
951 | $value = apply_filters('pre_category_nicename', $value); |
952 | |
953 | } else if ( 'rss' == $context ) { |
954 | $value = apply_filters("term_${field}_rss", $value, $taxonomy); |
955 | $value = apply_filters("${taxonomy}_${field}_rss", $value); |
956 | } else { |
957 | // Use display filters by default. |
958 | $value = apply_filters("term_$field", $value, $term_id, $taxonomy, $context); |
959 | $value = apply_filters("${taxonomy}_$field", $value, $term_id, $context); |
960 | } |
961 | |
962 | if ( 'attribute' == $context ) |
963 | $value = attribute_escape($value); |
964 | else if ( 'js' == $context ) |
965 | $value = js_escape($value); |
966 | |
967 | return $value; |
968 | } |
969 | |
970 | /** |
971 | * Count how many terms are in Taxonomy. |
972 | * |
973 | * Default $args is 'ignore_empty' which can be <code>'ignore_empty=true'</code> |
974 | * or <code>array('ignore_empty' => true);</code>. |
975 | * |
976 | * @package WordPress |
977 | * @subpackage Taxonomy |
978 | * @since 2.3.0 |
979 | * |
980 | * @uses $wpdb |
981 | * @uses wp_parse_args() Turns strings into arrays and merges defaults into an array. |
982 | * |
983 | * @param string $taxonomy Taxonomy name |
984 | * @param array|string $args Overwrite defaults |
985 | * @return int How many terms are in $taxonomy |
986 | */ |
987 | function wp_count_terms( $taxonomy, $args = array() ) { |
988 | global $wpdb; |
989 | |
990 | $defaults = array('ignore_empty' => false); |
991 | $args = wp_parse_args($args, $defaults); |
992 | extract($args, EXTR_SKIP); |
993 | |
994 | $where = ''; |
995 | if ( $ignore_empty ) |
996 | $where = 'AND count > 0'; |
997 | |
998 | return $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE taxonomy = %s $where", $taxonomy) ); |
999 | } |
1000 | |
1001 | /** |
1002 | * Will unlink the term from the taxonomy. |
1003 | * |
1004 | * Will remove the term's relationship to the taxonomy, not the term or taxonomy |
1005 | * itself. The term and taxonomy will still exist. Will require the term's |
1006 | * object ID to perform the operation. |
1007 | * |
1008 | * @package WordPress |
1009 | * @subpackage Taxonomy |
1010 | * @since 2.3.0 |
1011 | * @uses $wpdb |
1012 | * |
1013 | * @param int $object_id The term Object Id that refers to the term |
1014 | * @param string|array $taxonomy List of Taxonomy Names or single Taxonomy name. |
1015 | */ |
1016 | function wp_delete_object_term_relationships( $object_id, $taxonomies ) { |
1017 | global $wpdb; |
1018 | |
1019 | $object_id = (int) $object_id; |
1020 | |
1021 | if ( !is_array($taxonomies) ) |
1022 | $taxonomies = array($taxonomies); |
1023 | |
1024 | foreach ( (array) $taxonomies as $taxonomy ) { |
1025 | $tt_ids = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids'); |
1026 | $in_tt_ids = "'" . implode("', '", $tt_ids) . "'"; |
1027 | $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id) ); |
1028 | wp_update_term_count($tt_ids, $taxonomy); |
1029 | } |
1030 | } |
1031 | |
1032 | /** |
1033 | * Removes a term from the database. |
1034 | * |
1035 | * If the term is a parent of other terms, then the children will be updated to |
1036 | * that term's parent. |
1037 | * |
1038 | * The $args 'default' will only override the terms found, if there is only one |
1039 | * term found. Any other and the found terms are used. |
1040 | * |
1041 | * @package WordPress |
1042 | * @subpackage Taxonomy |
1043 | * @since 2.3.0 |
1044 | * |
1045 | * @uses $wpdb |
1046 | * @uses do_action() Calls both 'delete_term' and 'delete_$taxonomy' action |
1047 | * hooks, passing term object, term id. 'delete_term' gets an additional |
1048 | * parameter with the $taxonomy parameter. |
1049 | * |
1050 | * @param int $term Term ID |
1051 | * @param string $taxonomy Taxonomy Name |
1052 | * @param array|string $args Optional. Change 'default' term id and override found term ids. |
1053 | * @return bool|WP_Error Returns false if not term; true if completes delete action. |
1054 | */ |
1055 | function wp_delete_term( $term, $taxonomy, $args = array() ) { |
1056 | global $wpdb; |
1057 | |
1058 | $term = (int) $term; |
1059 | |
1060 | if ( ! $ids = is_term($term, $taxonomy) ) |
1061 | return false; |
1062 | if ( is_wp_error( $ids ) ) |
1063 | return $ids; |
1064 | |
1065 | $tt_id = $ids['term_taxonomy_id']; |
1066 | |
1067 | $defaults = array(); |
1068 | $args = wp_parse_args($args, $defaults); |
1069 | extract($args, EXTR_SKIP); |
1070 | |
1071 | if ( isset($default) ) { |
1072 | $default = (int) $default; |
1073 | if ( ! is_term($default, $taxonomy) ) |
1074 | unset($default); |
1075 | } |
1076 | |
1077 | // Update children to point to new parent |
1078 | if ( is_taxonomy_hierarchical($taxonomy) ) { |
1079 | $term_obj = get_term($term, $taxonomy); |
1080 | if ( is_wp_error( $term_obj ) ) |
1081 | return $term_obj; |
1082 | $parent = $term_obj->parent; |
1083 | |
1084 | $wpdb->update( $wpdb->term_taxonomy, compact( 'parent' ), array( 'parent' => $term_obj->term_id) + compact( 'taxonomy' ) ); |
1085 | } |
1086 | |
1087 | $objects = $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $tt_id ) ); |
1088 | |
1089 | foreach ( (array) $objects as $object ) { |
1090 | $terms = wp_get_object_terms($object, $taxonomy, 'fields=ids'); |
1091 | if ( 1 == count($terms) && isset($default) ) |
1092 | $terms = array($default); |
1093 | else |
1094 | $terms = array_diff($terms, array($term)); |
1095 | $terms = array_map('intval', $terms); |
1096 | wp_set_object_terms($object, $terms, $taxonomy); |
1097 | } |
1098 | |
1099 | $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $tt_id ) ); |
1100 | |
1101 | // Delete the term if no taxonomies use it. |
1102 | if ( !$wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE term_id = %d", $term) ) ) |
1103 | $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->terms WHERE term_id = %d", $term) ); |
1104 | |
1105 | clean_term_cache($term, $taxonomy); |
1106 | |
1107 | do_action('delete_term', $term, $tt_id, $taxonomy); |
1108 | do_action("delete_$taxonomy", $term, $tt_id); |
1109 | |
1110 | return true; |
1111 | } |
1112 | |
1113 | /** |
1114 | * Retrieves the terms associated with the given object(s), in the supplied taxonomies. |
1115 | * |
1116 | * The following information has to do the $args parameter and for what can be |
1117 | * contained in the string or array of that parameter, if it exists. |
1118 | * |
1119 | * The first argument is called, 'orderby' and has the default value of 'name'. |
1120 | * The other value that is supported is 'count'. |
1121 | * |
1122 | * The second argument is called, 'order' and has the default value of 'ASC'. |
1123 | * The only other value that will be acceptable is 'DESC'. |
1124 | * |
1125 | * The final argument supported is called, 'fields' and has the default value of |
1126 | * 'all'. There are multiple other options that can be used instead. Supported |
1127 | * values are as follows: 'all', 'ids', 'names', and finally |
1128 | * 'all_with_object_id'. |
1129 | * |
1130 | * The fields argument also decides what will be returned. If 'all' or |
1131 | * 'all_with_object_id' is choosen or the default kept intact, then all matching |
1132 | * terms objects will be returned. If either 'ids' or 'names' is used, then an |
1133 | * array of all matching term ids or term names will be returned respectively. |
1134 | * |
1135 | * @package WordPress |
1136 | * @subpackage Taxonomy |
1137 | * @since 2.3.0 |
1138 | * @uses $wpdb |
1139 | * |
1140 | * @param int|array $object_id The id of the object(s) to retrieve. |
1141 | * @param string|array $taxonomies The taxonomies to retrieve terms from. |
1142 | * @param array|string $args Change what is returned |
1143 | * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if $taxonomy does not exist. |
1144 | */ |
1145 | function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { |
1146 | global $wpdb; |
1147 | |
1148 | if ( !is_array($taxonomies) ) |
1149 | $taxonomies = array($taxonomies); |
1150 | |
1151 | foreach ( (array) $taxonomies as $taxonomy ) { |
1152 | if ( ! is_taxonomy($taxonomy) ) |
1153 | return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); |
1154 | } |
1155 | |
1156 | if ( !is_array($object_ids) ) |
1157 | $object_ids = array($object_ids); |
1158 | $object_ids = array_map('intval', $object_ids); |
1159 | |
1160 | $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all'); |
1161 | $args = wp_parse_args( $args, $defaults ); |
1162 | |
1163 | $terms = array(); |
1164 | if ( count($taxonomies) > 1 ) { |
1165 | foreach ( $taxonomies as $index => $taxonomy ) { |
1166 | $t = get_taxonomy($taxonomy); |
1167 | if ( isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args) ) { |
1168 | unset($taxonomies[$index]); |
1169 | $terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args))); |
1170 | } |
1171 | } |
1172 | } else { |
1173 | $t = get_taxonomy($taxonomies[0]); |
1174 | if ( isset($t->args) && is_array($t->args) ) |
1175 | $args = array_merge($args, $t->args); |
1176 | } |
1177 | |
1178 | extract($args, EXTR_SKIP); |
1179 | |
1180 | if ( 'count' == $orderby ) |
1181 | $orderby = 'tt.count'; |
1182 | else if ( 'name' == $orderby ) |
1183 | $orderby = 't.name'; |
1184 | else if ( 'slug' == $orderby ) |
1185 | $orderby = 't.slug'; |
1186 | else if ( 'term_group' == $orderby ) |
1187 | $orderby = 't.term_group'; |
1188 | else if ( 'term_order' == $orderby ) |
1189 | $orderby = 'tr.term_order'; |
1190 | else |
1191 | $orderby = 't.term_id'; |
1192 | |
1193 | $taxonomies = "'" . implode("', '", $taxonomies) . "'"; |
1194 | $object_ids = implode(', ', $object_ids); |
1195 | |
1196 | $select_this = ''; |
1197 | if ( 'all' == $fields ) |
1198 | $select_this = 't.*, tt.*'; |
1199 | else if ( 'ids' == $fields ) |
1200 | $select_this = 't.term_id'; |
1201 | else if ( 'names' == $fields ) |
1202 | $select_this = 't.name'; |
1203 | else if ( 'all_with_object_id' == $fields ) |
1204 | $select_this = 't.*, tt.*, tr.object_id'; |
1205 | |
1206 | $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tr.object_id IN ($object_ids) ORDER BY $orderby $order"; |
1207 | |
1208 | if ( 'all' == $fields || 'all_with_object_id' == $fields ) { |
1209 | $terms = array_merge($terms, $wpdb->get_results($query)); |
1210 | update_term_cache($terms); |
1211 | } else if ( 'ids' == $fields || 'names' == $fields ) { |
1212 | $terms = array_merge($terms, $wpdb->get_col($query)); |
1213 | } else if ( 'tt_ids' == $fields ) { |
1214 | $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) ORDER BY tr.term_taxonomy_id $order"); |
1215 | } |
1216 | |
1217 | if ( ! $terms ) |
1218 | return array(); |
1219 | |
1220 | return $terms; |
1221 | } |
1222 | |
1223 | /** |
1224 | * Adds a new term to the database. Optionally marks it as an alias of an existing term. |
1225 | * |
1226 | * Error handling is assigned for the nonexistance of the $taxonomy and $term |
1227 | * parameters before inserting. If both the term id and taxonomy exist |
1228 | * previously, then an array will be returned that contains the term id and the |
1229 | * contents of what is returned. The keys of the array are 'term_id' and |
1230 | * 'term_taxonomy_id' containing numeric values. |
1231 | * |
1232 | * It is assumed that the term does not yet exist or the above will apply. The |
1233 | * term will be first added to the term table and then related to the taxonomy |
1234 | * if everything is well. If everything is correct, then several actions will be |
1235 | * run prior to a filter and then several actions will be run after the filter |
1236 | * is run. |
1237 | * |
1238 | * The arguments decide how the term is handled based on the $args parameter. |
1239 | * The following is a list of the available overrides and the defaults. |
1240 | * |
1241 | * 'alias_of'. There is no default, but if added, expected is the slug that the |
1242 | * term will be an alias of. Expected to be a string. |
1243 | * |
1244 | * 'description'. There is no default. If exists, will be added to the database |
1245 | * along with the term. Expected to be a string. |
1246 | * |
1247 | * 'parent'. Expected to be numeric and default is 0 (zero). Will assign value |
1248 | * of 'parent' to the term. |
1249 | * |
1250 | * 'slug'. Expected to be a string. There is no default. |
1251 | * |
1252 | * If 'slug' argument exists then the slug will be checked to see if it is not |
1253 | * a valid term. If that check succeeds (it is not a valid term), then it is |
1254 | * added and the term id is given. If it fails, then a check is made to whether |
1255 | * the taxonomy is hierarchical and the parent argument is not empty. If the |
1256 | * second check succeeds, the term will be inserted and the term id will be |
1257 | * given. |
1258 | * |
1259 | * @package WordPress |
1260 | * @subpackage Taxonomy |
1261 | * @since 2.3.0 |
1262 | * @uses $wpdb |
1263 | * |
1264 | * @uses do_action() Calls 'create_term' hook with the term id and taxonomy id as parameters. |
1265 | * @uses do_action() Calls 'create_$taxonomy' hook with term id and taxonomy id as parameters. |
1266 | * @uses apply_filters() Calls 'term_id_filter' hook with term id and taxonomy id as parameters. |
1267 | * @uses do_action() Calls 'created_term' hook with the term id and taxonomy id as parameters. |
1268 | * @uses do_action() Calls 'created_$taxonomy' hook with term id and taxonomy id as parameters. |
1269 | * |
1270 | * @param int|string $term The term to add or update. |
1271 | * @param string $taxonomy The taxonomy to which to add the term |
1272 | * @param array|string $args Change the values of the inserted term |
1273 | * @return array|WP_Error The Term ID and Term Taxonomy ID |
1274 | */ |
1275 | function wp_insert_term( $term, $taxonomy, $args = array() ) { |
1276 | global $wpdb; |
1277 | |
1278 | if ( ! is_taxonomy($taxonomy) ) |
1279 | return new WP_Error('invalid_taxonomy', __('Invalid taxonomy')); |
1280 | |
1281 | if ( is_int($term) && 0 == $term ) |
1282 | return new WP_Error('invalid_term_id', __('Invalid term ID')); |
1283 | |
1284 | if ( '' == trim($term) ) |
1285 | return new WP_Error('empty_term_name', __('A name is required for this term')); |
1286 | |
1287 | $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); |
1288 | $args = wp_parse_args($args, $defaults); |
1289 | $args['name'] = $term; |
1290 | $args['taxonomy'] = $taxonomy; |
1291 | $args = sanitize_term($args, $taxonomy, 'db'); |
1292 | extract($args, EXTR_SKIP); |
1293 | |
1294 | // expected_slashed ($name) |
1295 | $name = stripslashes($name); |
1296 | $description = stripslashes($description); |
1297 | |
1298 | if ( empty($slug) ) |
1299 | $slug = sanitize_title($name); |
1300 | |
1301 | $term_group = 0; |
1302 | if ( $alias_of ) { |
1303 | $alias = $wpdb->get_row( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $alias_of) ); |
1304 | if ( $alias->term_group ) { |
1305 | // The alias we want is already in a group, so let's use that one. |
1306 | $term_group = $alias->term_group; |
1307 | } else { |
1308 | // The alias isn't in a group, so let's create a new one and firstly add the alias term to it. |
1309 | $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1; |
1310 | $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->terms SET term_group = %d WHERE term_id = %d", $term_group, $alias->term_id ) ); |
1311 | } |
1312 | } |
1313 | |
1314 | if ( ! $term_id = is_term($slug) ) { |
1315 | if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) ) |
1316 | return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error); |
1317 | $term_id = (int) $wpdb->insert_id; |
1318 | } else if ( is_taxonomy_hierarchical($taxonomy) && !empty($parent) ) { |
1319 | // If the taxonomy supports hierarchy and the term has a parent, make the slug unique |
1320 | // by incorporating parent slugs. |
1321 | $slug = wp_unique_term_slug($slug, (object) $args); |
1322 | if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) ) |
1323 | return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error); |
1324 | $term_id = (int) $wpdb->insert_id; |
1325 | } |
1326 | |
1327 | if ( empty($slug) ) { |
1328 | $slug = sanitize_title($slug, $term_id); |
1329 | $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); |
1330 | } |
1331 | |
1332 | $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id ) ); |
1333 | |
1334 | if ( !empty($tt_id) ) |
1335 | return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); |
1336 | |
1337 | $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent') + array( 'count' => 0 ) ); |
1338 | $tt_id = (int) $wpdb->insert_id; |
1339 | |
1340 | do_action("create_term", $term_id, $tt_id); |
1341 | do_action("create_$taxonomy", $term_id, $tt_id); |
1342 | |
1343 | $term_id = apply_filters('term_id_filter', $term_id, $tt_id); |
1344 | |
1345 | clean_term_cache($term_id, $taxonomy); |
1346 | |
1347 | do_action("created_term", $term_id, $tt_id); |
1348 | do_action("created_$taxonomy", $term_id, $tt_id); |
1349 | |
1350 | return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); |
1351 | } |
1352 | |
1353 | /** |
1354 | * Create Term and Taxonomy Relationships. |
1355 | * |
1356 | * Relates an object (post, link etc) to a term and taxonomy type. Creates the |
1357 | * term and taxonomy relationship if it doesn't already exist. Creates a term if |
1358 | * it doesn't exist (using the slug). |
1359 | * |
1360 | * A relationship means that the term is grouped in or belongs to the taxonomy. |
1361 | * A term has no meaning until it is given context by defining which taxonomy it |
1362 | * exists under. |
1363 | * |
1364 | * @package WordPress |
1365 | * @subpackage Taxonomy |
1366 | * @since 2.3.0 |
1367 | * @uses $wpdb |
1368 | * |
1369 | * @param int $object_id The object to relate to. |
1370 | * @param array|int|string $term The slug or id of the term. |
1371 | * @param array|string $taxonomy The context in which to relate the term to the object. |
1372 | * @param bool $append If false will delete difference of terms. |
1373 | * @return array|WP_Error Affected Term IDs |
1374 | */ |
1375 | function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false) { |
1376 | global $wpdb; |
1377 | |
1378 | $object_id = (int) $object_id; |
1379 | |
1380 | if ( ! is_taxonomy($taxonomy) ) |
1381 | return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); |
1382 | |
1383 | if ( !is_array($terms) ) |
1384 | $terms = array($terms); |
1385 | |
1386 | if ( ! $append ) |
1387 | $old_tt_ids = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids'); |
1388 | |
1389 | $tt_ids = array(); |
1390 | $term_ids = array(); |
1391 | |
1392 | foreach ( (array) $terms as $term) { |
1393 | if ( !strlen(trim($term)) ) |
1394 | continue; |
1395 | |
1396 | if ( !$term_info = is_term($term, $taxonomy) ) |
1397 | $term_info = wp_insert_term($term, $taxonomy); |
1398 | if ( is_wp_error($term_info) ) |
1399 | return $term_info; |
1400 | $term_ids[] = $term_info['term_id']; |
1401 | $tt_id = $term_info['term_taxonomy_id']; |
1402 | $tt_ids[] = $tt_id; |
1403 | |
1404 | if ( $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", $object_id, $tt_id ) ) ) |
1405 | continue; |
1406 | $wpdb->insert( $wpdb->term_relationships, array( 'object_id' => $object_id, 'term_taxonomy_id' => $tt_id ) ); |
1407 | } |
1408 | |
1409 | wp_update_term_count($tt_ids, $taxonomy); |
1410 | |
1411 | if ( ! $append ) { |
1412 | $delete_terms = array_diff($old_tt_ids, $tt_ids); |
1413 | if ( $delete_terms ) { |
1414 | $in_delete_terms = "'" . implode("', '", $delete_terms) . "'"; |
1415 | $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_delete_terms)", $object_id) ); |
1416 | wp_update_term_count($delete_terms, $taxonomy); |
1417 | } |
1418 | } |
1419 | |
1420 | $t = get_taxonomy($taxonomy); |
1421 | if ( ! $append && isset($t->sort) && $t->sort ) { |
1422 | $values = array(); |
1423 | $term_order = 0; |
1424 | $final_tt_ids = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids'); |
1425 | foreach ( $tt_ids as $tt_id ) |
1426 | if ( in_array($tt_id, $final_tt_ids) ) |
1427 | $values[] = $wpdb->prepare( "(%d, %d, %d)", $object_id, $tt_id, ++$term_order); |
1428 | if ( $values ) |
1429 | $wpdb->query("INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . join(',', $values) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)"); |
1430 | } |
1431 | |
1432 | return $tt_ids; |
1433 | } |
1434 | |
1435 | /** |
1436 | * Will make slug unique, if it isn't already. |
1437 | * |
1438 | * The $slug has to be unique global to every taxonomy, meaning that one |
1439 | * taxonomy term can't have a matching slug with another taxonomy term. Each |
1440 | * slug has to be globally unique for every taxonomy. |
1441 | * |
1442 | * The way this works is that if the taxonomy that the term belongs to is |
1443 | * heirarchical and has a parent, it will append that parent to the $slug. |
1444 | * |
1445 | * If that still doesn't return an unique slug, then it try to append a number |
1446 | * until it finds a number that is truely unique. |
1447 | * |
1448 | * The only purpose for $term is for appending a parent, if one exists. |
1449 | * |
1450 | * @package WordPress |
1451 | * @subpackage Taxonomy |
1452 | * @since 2.3.0 |
1453 | * @uses $wpdb |
1454 | * |
1455 | * @param string $slug The string that will be tried for a unique slug |
1456 | * @param object $term The term object that the $slug will belong too |
1457 | * @return string Will return a true unique slug. |
1458 | */ |
1459 | function wp_unique_term_slug($slug, $term) { |
1460 | global $wpdb; |
1461 | |
1462 | // If the taxonomy supports hierarchy and the term has a parent, make the slug unique |
1463 | // by incorporating parent slugs. |
1464 | if ( is_taxonomy_hierarchical($term->taxonomy) && !empty($term->parent) ) { |
1465 | $the_parent = $term->parent; |
1466 | while ( ! empty($the_parent) ) { |
1467 | $parent_term = get_term($the_parent, $term->taxonomy); |
1468 | if ( is_wp_error($parent_term) || empty($parent_term) ) |
1469 | break; |
1470 | $slug .= '-' . $parent_term->slug; |
1471 | if ( empty($parent_term->parent) ) |
1472 | break; |
1473 | $the_parent = $parent_term->parent; |
1474 | } |
1475 | } |
1476 | |
1477 | // If we didn't get a unique slug, try appending a number to make it unique. |
1478 | if ( !empty($args['term_id']) ) |
1479 | $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $args['term_id'] ); |
1480 | else |
1481 | $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug ); |
1482 | |
1483 | if ( $wpdb->get_var( $query ) ) { |
1484 | $num = 2; |
1485 | do { |
1486 | $alt_slug = $slug . "-$num"; |
1487 | $num++; |
1488 | $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); |
1489 | } while ( $slug_check ); |
1490 | $slug = $alt_slug; |
1491 | } |
1492 | |
1493 | return $slug; |
1494 | } |
1495 | |
1496 | /** |
1497 | * Update term based on arguments provided. |
1498 | * |
1499 | * The $args will indiscriminately override all values with the same field name. |
1500 | * Care must be taken to not override important information need to update or |
1501 | * update will fail (or perhaps create a new term, neither would be acceptable). |
1502 | * |
1503 | * Defaults will set 'alias_of', 'description', 'parent', and 'slug' if not |
1504 | * defined in $args already. |
1505 | * |
1506 | * 'alias_of' will create a term group, if it doesn't already exist, and update |
1507 | * it for the $term. |
1508 | * |
1509 | * If the 'slug' argument in $args is missing, then the 'name' in $args will be |
1510 | * used. It should also be noted that if you set 'slug' and it isn't unique then |
1511 | * a WP_Error will be passed back. If you don't pass any slug, then a unique one |
1512 | * will be created for you. |
1513 | * |
1514 | * For what can be overrode in $args, check the term scheme can contain and stay |
1515 | * away from the term keys. |
1516 | * |
1517 | * @package WordPress |
1518 | * @subpackage Taxonomy |
1519 | * @since 2.3.0 |
1520 | * |
1521 | * @uses $wpdb |
1522 | * @uses do_action() Will call both 'edit_term' and 'edit_$taxonomy' twice. |
1523 | * @uses apply_filters() Will call the 'term_id_filter' filter and pass the term |
1524 | * id and taxonomy id. |
1525 | * |
1526 | * @param int $term The ID of the term |
1527 | * @param string $taxonomy The context in which to relate the term to the object. |
1528 | * @param array|string $args Overwrite term field values |
1529 | * @return array|WP_Error Returns Term ID and Taxonomy Term ID |
1530 | */ |
1531 | function wp_update_term( $term, $taxonomy, $args = array() ) { |
1532 | global $wpdb; |
1533 | |
1534 | if ( ! is_taxonomy($taxonomy) ) |
1535 | return new WP_Error('invalid_taxonomy', __('Invalid taxonomy')); |
1536 | |
1537 | $term_id = (int) $term; |
1538 | |
1539 | // First, get all of the original args |
1540 | $term = get_term ($term_id, $taxonomy, ARRAY_A); |
1541 | |
1542 | // Escape data pulled from DB. |
1543 | $term = add_magic_quotes($term); |
1544 | |
1545 | // Merge old and new args with new args overwriting old ones. |
1546 | $args = array_merge($term, $args); |
1547 | |
1548 | $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); |
1549 | $args = wp_parse_args($args, $defaults); |
1550 | $args = sanitize_term($args, $taxonomy, 'db'); |
1551 | extract($args, EXTR_SKIP); |
1552 | |
1553 | // expected_slashed ($name) |
1554 | $name = stripslashes($name); |
1555 | $description = stripslashes($description); |
1556 | |
1557 | if ( '' == trim($name) ) |
1558 | return new WP_Error('empty_term_name', __('A name is required for this term')); |
1559 | |
1560 | $empty_slug = false; |
1561 | if ( empty($slug) ) { |
1562 | $empty_slug = true; |
1563 | $slug = sanitize_title($name); |
1564 | } |
1565 | |
1566 | if ( $alias_of ) { |
1567 | $alias = $wpdb->get_row( $wpdb->prepare( "SELECT term_id, term_group FROM $wpdb->terms WHERE slug = %s", $alias_of) ); |
1568 | if ( $alias->term_group ) { |
1569 | // The alias we want is already in a group, so let's use that one. |
1570 | $term_group = $alias->term_group; |
1571 | } else { |
1572 | // The alias isn't in a group, so let's create a new one and firstly add the alias term to it. |
1573 | $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1; |
1574 | $wpdb->update( $wpdb->terms, compact('term_group'), array( 'term_id' => $alias->term_id ) ); |
1575 | } |
1576 | } |
1577 | |
1578 | // Check for duplicate slug |
1579 | $id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms WHERE slug = %s", $slug ) ); |
1580 | if ( $id && ($id != $term_id) ) { |
1581 | // If an empty slug was passed or the parent changed, reset the slug to something unique. |
1582 | // Otherwise, bail. |
1583 | if ( $empty_slug || ( $parent != $term->parent) ) |
1584 | $slug = wp_unique_term_slug($slug, (object) $args); |
1585 | else |
1586 | return new WP_Error('duplicate_term_slug', sprintf(__('The slug "%s" is already in use by another term'), $slug)); |
1587 | } |
1588 | |
1589 | $wpdb->update($wpdb->terms, compact( 'name', 'slug', 'term_group' ), compact( 'term_id' ) ); |
1590 | |
1591 | if ( empty($slug) ) { |
1592 | $slug = sanitize_title($name, $term_id); |
1593 | $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); |
1594 | } |
1595 | |
1596 | $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id) ); |
1597 | |
1598 | $wpdb->update( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ), array( 'term_taxonomy_id' => $tt_id ) ); |
1599 | |
1600 | do_action("edit_term", $term_id, $tt_id); |
1601 | do_action("edit_$taxonomy", $term_id, $tt_id); |
1602 | |
1603 | $term_id = apply_filters('term_id_filter', $term_id, $tt_id); |
1604 | |
1605 | clean_term_cache($term_id, $taxonomy); |
1606 | |
1607 | do_action("edited_term", $term_id, $tt_id); |
1608 | do_action("edited_$taxonomy", $term_id, $tt_id); |
1609 | |
1610 | return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); |
1611 | } |
1612 | |
1613 | /** |
1614 | * Enable or disable term counting. |
1615 | * |
1616 | * @since 2.5.0 |
1617 | * |
1618 | * @param bool $defer Optional. Enable if true, disable if false. |
1619 | * @return bool Whether term counting is enabled or disabled. |
1620 | */ |
1621 | function wp_defer_term_counting($defer=null) { |
1622 | static $_defer = false; |
1623 | |
1624 | if ( is_bool($defer) ) { |
1625 | $_defer = $defer; |
1626 | // flush any deferred counts |
1627 | if ( !$defer ) |
1628 | wp_update_term_count( null, null, true ); |
1629 | } |
1630 | |
1631 | return $_defer; |
1632 | } |
1633 | |
1634 | /** |
1635 | * Updates the amount of terms in taxonomy. |
1636 | * |
1637 | * If there is a taxonomy callback applyed, then it will be called for updating |
1638 | * the count. |
1639 | * |
1640 | * The default action is to count what the amount of terms have the relationship |
1641 | * of term ID. Once that is done, then update the database. |
1642 | * |
1643 | * @package WordPress |
1644 | * @subpackage Taxonomy |
1645 | * @since 2.3.0 |
1646 | * @uses $wpdb |
1647 | * |
1648 | * @param int|array $terms The term_taxonomy_id of the terms |
1649 | * @param string $taxonomy The context of the term. |
1650 | * @return bool If no terms will return false, and if successful will return true. |
1651 | */ |
1652 | function wp_update_term_count( $terms, $taxonomy, $do_deferred=false ) { |
1653 | static $_deferred = array(); |
1654 | |
1655 | if ( $do_deferred ) { |
1656 | foreach ( (array) array_keys($_deferred) as $tax ) { |
1657 | wp_update_term_count_now( $_deferred[$tax], $tax ); |
1658 | unset( $_deferred[$tax] ); |
1659 | } |
1660 | } |
1661 | |
1662 | if ( empty($terms) ) |
1663 | return false; |
1664 | |
1665 | if ( !is_array($terms) ) |
1666 | $terms = array($terms); |
1667 | |
1668 | if ( wp_defer_term_counting() ) { |
1669 | if ( !isset($_deferred[$taxonomy]) ) |
1670 | $_deferred[$taxonomy] = array(); |
1671 | $_deferred[$taxonomy] = array_unique( array_merge($_deferred[$taxonomy], $terms) ); |
1672 | return true; |
1673 | } |
1674 | |
1675 | return wp_update_term_count_now( $terms, $taxonomy ); |
1676 | } |
1677 | |
1678 | /** |
1679 | * Perform term count update immediately. |
1680 | * |
1681 | * @since 2.5.0 |
1682 | * |
1683 | * @param array $terms The term_taxonomy_id of terms to update. |
1684 | * @param string $taxonomy The context of the term. |
1685 | * @return bool Always true when complete. |
1686 | */ |
1687 | function wp_update_term_count_now( $terms, $taxonomy ) { |
1688 | global $wpdb; |
1689 | |
1690 | $terms = array_map('intval', $terms); |
1691 | |
1692 | $taxonomy = get_taxonomy($taxonomy); |
1693 | if ( !empty($taxonomy->update_count_callback) ) { |
1694 | call_user_func($taxonomy->update_count_callback, $terms); |
1695 | } else { |
1696 | // Default count updater |
1697 | foreach ( (array) $terms as $term) { |
1698 | $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term) ); |
1699 | $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) ); |
1700 | } |
1701 | |
1702 | } |
1703 | |
1704 | clean_term_cache($terms); |
1705 | |
1706 | return true; |
1707 | } |
1708 | |
1709 | // |
1710 | // Cache |
1711 | // |
1712 | |
1713 | |
1714 | /** |
1715 | * Removes the taxonomy relationship to terms from the cache. |
1716 | * |
1717 | * Will remove the entire taxonomy relationship containing term $object_id. The |
1718 | * term IDs have to exist within the taxonomy $object_type for the deletion to |
1719 | * take place. |
1720 | * |
1721 | * @package WordPress |
1722 | * @subpackage Taxonomy |
1723 | * @since 2.3.0 |
1724 | * |
1725 | * @see get_object_taxonomies() for more on $object_type |
1726 | * @uses do_action() Will call action hook named, 'clean_object_term_cache' after completion. |
1727 | * Passes, function params in same order. |
1728 | * |
1729 | * @param int|array $object_ids Single or list of term object ID(s) |
1730 | * @param array|string $object_type The taxonomy object type |
1731 | */ |
1732 | function clean_object_term_cache($object_ids, $object_type) { |
1733 | if ( !is_array($object_ids) ) |
1734 | $object_ids = array($object_ids); |
1735 | |
1736 | foreach ( $object_ids as $id ) |
1737 | foreach ( get_object_taxonomies($object_type) as $taxonomy ) |
1738 | wp_cache_delete($id, "{$taxonomy}_relationships"); |
1739 | |
1740 | do_action('clean_object_term_cache', $object_ids, $object_type); |
1741 | } |
1742 | |
1743 | |
1744 | /** |
1745 | * Will remove all of the term ids from the cache. |
1746 | * |
1747 | * @package WordPress |
1748 | * @subpackage Taxonomy |
1749 | * @since 2.3.0 |
1750 | * @uses $wpdb |
1751 | * |
1752 | * @param int|array $ids Single or list of Term IDs |
1753 | * @param string $taxonomy Can be empty and will assume tt_ids, else will use for context. |
1754 | */ |
1755 | function clean_term_cache($ids, $taxonomy = '') { |
1756 | global $wpdb; |
1757 | static $cleaned = array(); |
1758 | |
1759 | if ( !is_array($ids) ) |
1760 | $ids = array($ids); |
1761 | |
1762 | $taxonomies = array(); |
1763 | // If no taxonomy, assume tt_ids. |
1764 | if ( empty($taxonomy) ) { |
1765 | $tt_ids = implode(', ', $ids); |
1766 | $terms = $wpdb->get_results("SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)"); |
1767 | foreach ( (array) $terms as $term ) { |
1768 | $taxonomies[] = $term->taxonomy; |
1769 | wp_cache_delete($term->term_id, $term->taxonomy); |
1770 | } |
1771 | $taxonomies = array_unique($taxonomies); |
1772 | } else { |
1773 | foreach ( $ids as $id ) { |
1774 | wp_cache_delete($id, $taxonomy); |
1775 | } |
1776 | $taxonomies = array($taxonomy); |
1777 | } |
1778 | |
1779 | foreach ( $taxonomies as $taxonomy ) { |
1780 | if ( isset($cleaned[$taxonomy]) ) |
1781 | continue; |
1782 | $cleaned[$taxonomy] = true; |
1783 | wp_cache_delete('all_ids', $taxonomy); |
1784 | wp_cache_delete('get', $taxonomy); |
1785 | delete_option("{$taxonomy}_children"); |
1786 | } |
1787 | |
1788 | wp_cache_set('last_changed', time(), 'terms'); |
1789 | |
1790 | do_action('clean_term_cache', $ids, $taxonomy); |
1791 | } |
1792 | |
1793 | |
1794 | /** |
1795 | * Retrieves the taxonomy relationship to the term object id. |
1796 | * |
1797 | * @package WordPress |
1798 | * @subpackage Taxonomy |
1799 | * @since 2.3.0 |
1800 | * |
1801 | * @uses wp_cache_get() Retrieves taxonomy relationship from cache |
1802 | * |
1803 | * @param int|array $id Term object ID |
1804 | * @param string $taxonomy Taxonomy Name |
1805 | * @return bool|array Empty array if $terms found, but not $taxonomy. False if nothing is in cache for $taxonomy and $id. |
1806 | */ |
1807 | function &get_object_term_cache($id, $taxonomy) { |
1808 | $cache = wp_cache_get($id, "{$taxonomy}_relationships"); |
1809 | return $cache; |
1810 | } |
1811 | |
1812 | |
1813 | /** |
1814 | * Updates the cache for Term ID(s). |
1815 | * |
1816 | * Will only update the cache for terms not already cached. |
1817 | * |
1818 | * The $object_ids expects that the ids be separated by commas, if it is a |
1819 | * string. |
1820 | * |
1821 | * It should be noted that update_object_term_cache() is very time extensive. It |
1822 | * is advised that the function is not called very often or at least not for a |
1823 | * lot of terms that exist in a lot of taxonomies. The amount of time increases |
1824 | * for each term and it also increases for each taxonomy the term belongs to. |
1825 | * |
1826 | * @package WordPress |
1827 | * @subpackage Taxonomy |
1828 | * @since 2.3.0 |
1829 | * @uses wp_get_object_terms() Used to get terms from the database to update |
1830 | * |
1831 | * @param string|array $object_ids Single or list of term object ID(s) |
1832 | * @param array|string $object_type The taxonomy object type |
1833 | * @return null|bool Null value is given with empty $object_ids. False if |
1834 | */ |
1835 | function update_object_term_cache($object_ids, $object_type) { |
1836 | if ( empty($object_ids) ) |
1837 | return; |
1838 | |
1839 | if ( !is_array($object_ids) ) |
1840 | $object_ids = explode(',', $object_ids); |
1841 | |
1842 | $object_ids = array_map('intval', $object_ids); |
1843 | |
1844 | $taxonomies = get_object_taxonomies($object_type); |
1845 | |
1846 | $ids = array(); |
1847 | foreach ( (array) $object_ids as $id ) { |
1848 | foreach ( $taxonomies as $taxonomy ) { |
1849 | if ( false === wp_cache_get($id, "{$taxonomy}_relationships") ) { |
1850 | $ids[] = $id; |
1851 | break; |
1852 | } |
1853 | } |
1854 | } |
1855 | |
1856 | if ( empty( $ids ) ) |
1857 | return false; |
1858 | |
1859 | $terms = wp_get_object_terms($ids, $taxonomies, 'fields=all_with_object_id'); |
1860 | |
1861 | $object_terms = array(); |
1862 | foreach ( (array) $terms as $term ) |
1863 | $object_terms[$term->object_id][$term->taxonomy][$term->term_id] = $term; |
1864 | |
1865 | foreach ( $ids as $id ) { |
1866 | foreach ( $taxonomies as $taxonomy ) { |
1867 | if ( ! isset($object_terms[$id][$taxonomy]) ) { |
1868 | if ( !isset($object_terms[$id]) ) |
1869 | $object_terms[$id] = array(); |
1870 | $object_terms[$id][$taxonomy] = array(); |
1871 | } |
1872 | } |
1873 | } |
1874 | |
1875 | foreach ( $object_terms as $id => $value ) { |
1876 | foreach ( $value as $taxonomy => $terms ) { |
1877 | wp_cache_set($id, $terms, "{$taxonomy}_relationships"); |
1878 | } |
1879 | } |
1880 | } |
1881 | |
1882 | |
1883 | /** |
1884 | * Updates Terms to Taxonomy in cache. |
1885 | * |
1886 | * @package WordPress |
1887 | * @subpackage Taxonomy |
1888 | * @since 2.3.0 |
1889 | * |
1890 | * @param array $terms List of Term objects to change |
1891 | * @param string $taxonomy Optional. Update Term to this taxonomy in cache |
1892 | */ |
1893 | function update_term_cache($terms, $taxonomy = '') { |
1894 | foreach ( (array) $terms as $term ) { |
1895 | $term_taxonomy = $taxonomy; |
1896 | if ( empty($term_taxonomy) ) |
1897 | $term_taxonomy = $term->taxonomy; |
1898 | |
1899 | wp_cache_add($term->term_id, $term, $term_taxonomy); |
1900 | } |
1901 | } |
1902 | |
1903 | // |
1904 | // Private |
1905 | // |
1906 | |
1907 | |
1908 | /** |
1909 | * Retrieves children of taxonomy. |
1910 | * |
1911 | * @package WordPress |
1912 | * @subpackage Taxonomy |
1913 | * @access private |
1914 | * @since 2.3.0 |
1915 | * |
1916 | * @uses update_option() Stores all of the children in "$taxonomy_children" |
1917 | * option. That is the name of the taxonomy, immediately followed by '_children'. |
1918 | * |
1919 | * @param string $taxonomy Taxonomy Name |
1920 | * @return array Empty if $taxonomy isn't hierarachical or returns children. |
1921 | */ |
1922 | function _get_term_hierarchy($taxonomy) { |
1923 | if ( !is_taxonomy_hierarchical($taxonomy) ) |
1924 | return array(); |
1925 | $children = get_option("{$taxonomy}_children"); |
1926 | if ( is_array($children) ) |
1927 | return $children; |
1928 | |
1929 | $children = array(); |
1930 | $terms = get_terms($taxonomy, 'get=all'); |
1931 | foreach ( $terms as $term ) { |
1932 | if ( $term->parent > 0 ) |
1933 | $children[$term->parent][] = $term->term_id; |
1934 | } |
1935 | update_option("{$taxonomy}_children", $children); |
1936 | |
1937 | return $children; |
1938 | } |
1939 | |
1940 | |
1941 | /** |
1942 | * Get the subset of $terms that are descendants of $term_id. |
1943 | * |
1944 | * If $terms is an array of objects, then _get_term_children returns an array of objects. |
1945 | * If $terms is an array of IDs, then _get_term_children returns an array of IDs. |
1946 | * |
1947 | * @package WordPress |
1948 | * @subpackage Taxonomy |
1949 | * @access private |
1950 | * @since 2.3.0 |
1951 | * |
1952 | * @param int $term_id The ancestor term: all returned terms should be descendants of $term_id. |
1953 | * @param array $terms The set of terms---either an array of term objects or term IDs---from which those that are descendants of $term_id will be chosen. |
1954 | * @param string $taxonomy The taxonomy which determines the hierarchy of the terms. |
1955 | * @return array The subset of $terms that are descendants of $term_id. |
1956 | */ |
1957 | function &_get_term_children($term_id, $terms, $taxonomy) { |
1958 | $empty_array = array(); |
1959 | if ( empty($terms) ) |
1960 | return $empty_array; |
1961 | |
1962 | $term_list = array(); |
1963 | $has_children = _get_term_hierarchy($taxonomy); |
1964 | |
1965 | if ( ( 0 != $term_id ) && ! isset($has_children[$term_id]) ) |
1966 | return $empty_array; |
1967 | |
1968 | foreach ( (array) $terms as $term ) { |
1969 | $use_id = false; |
1970 | if ( !is_object($term) ) { |
1971 | $term = get_term($term, $taxonomy); |
1972 | if ( is_wp_error( $term ) ) |
1973 | return $term; |
1974 | $use_id = true; |
1975 | } |
1976 | |
1977 | if ( $term->term_id == $term_id ) |
1978 | continue; |
1979 | |
1980 | if ( $term->parent == $term_id ) { |
1981 | if ( $use_id ) |
1982 | $term_list[] = $term->term_id; |
1983 | else |
1984 | $term_list[] = $term; |
1985 | |
1986 | if ( !isset($has_children[$term->term_id]) ) |
1987 | continue; |
1988 | |
1989 | if ( $children = _get_term_children($term->term_id, $terms, $taxonomy) ) |
1990 | $term_list = array_merge($term_list, $children); |
1991 | } |
1992 | } |
1993 | |
1994 | return $term_list; |
1995 | } |
1996 | |
1997 | |
1998 | /** |
1999 | * Add count of children to parent count. |
2000 | * |
2001 | * Recalculates term counts by including items from child terms. Assumes all |
2002 | * relevant children are already in the $terms argument. |
2003 | * |
2004 | * @package WordPress |
2005 | * @subpackage Taxonomy |
2006 | * @access private |
2007 | * @since 2.3.0 |
2008 | * @uses $wpdb |
2009 | * |
2010 | * @param array $terms List of Term IDs |
2011 | * @param string $taxonomy Term Context |
2012 | * @return null Will break from function if conditions are not met. |
2013 | */ |
2014 | function _pad_term_counts(&$terms, $taxonomy) { |
2015 | global $wpdb; |
2016 | |
2017 | // This function only works for post categories. |
2018 | if ( 'category' != $taxonomy ) |
2019 | return; |
2020 | |
2021 | $term_hier = _get_term_hierarchy($taxonomy); |
2022 | |
2023 | if ( empty($term_hier) ) |
2024 | return; |
2025 | |
2026 | $term_items = array(); |
2027 | |
2028 | foreach ( (array) $terms as $key => $term ) { |
2029 | $terms_by_id[$term->term_id] = & $terms[$key]; |
2030 | $term_ids[$term->term_taxonomy_id] = $term->term_id; |
2031 | } |
2032 | |
2033 | // Get the object and term ids and stick them in a lookup table |
2034 | $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (".join(',', array_keys($term_ids)).") AND post_type = 'post' AND post_status = 'publish'"); |
2035 | foreach ( $results as $row ) { |
2036 | $id = $term_ids[$row->term_taxonomy_id]; |
2037 | $term_items[$id][$row->object_id] = isset($term_items[$id][$row->object_id]) ? ++$term_items[$id][$row->object_id] : 1; |
2038 | } |
2039 | |
2040 | // Touch every ancestor's lookup row for each post in each term |
2041 | foreach ( $term_ids as $term_id ) { |
2042 | $child = $term_id; |
2043 | while ( $parent = $terms_by_id[$child]->parent ) { |
2044 | if ( !empty($term_items[$term_id]) ) |
2045 | foreach ( $term_items[$term_id] as $item_id => $touches ) { |
2046 | $term_items[$parent][$item_id] = isset($term_items[$parent][$item_id]) ? ++$term_items[$parent][$item_id]: 1; |
2047 | } |
2048 | $child = $parent; |
2049 | } |
2050 | } |
2051 | |
2052 | // Transfer the touched cells |
2053 | foreach ( (array) $term_items as $id => $items ) |
2054 | if ( isset($terms_by_id[$id]) ) |
2055 | $terms_by_id[$id]->count = count($items); |
2056 | } |
2057 | |
2058 | // |
2059 | // Default callbacks |
2060 | // |
2061 | |
2062 | /** |
2063 | * Will update term count based on posts. |
2064 | * |
2065 | * Private function for the default callback for post_tag and category |
2066 | * taxonomies. |
2067 | * |
2068 | * @package WordPress |
2069 | * @subpackage Taxonomy |
2070 | * @access private |
2071 | * @since 2.3.0 |
2072 | * @uses $wpdb |
2073 | * |
2074 | * @param array $terms List of Term taxonomy IDs |
2075 | */ |
2076 | function _update_post_term_count( $terms ) { |
2077 | global $wpdb; |
2078 | |
2079 | foreach ( (array) $terms as $term ) { |
2080 | $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type = 'post' AND term_taxonomy_id = %d", $term ) ); |
2081 | $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) ); |
2082 | } |
2083 | } |
2084 | |
2085 | |
2086 | /** |
2087 | * Generates a permalink for a taxonomy term archive. |
2088 | * |
2089 | * @since 2.5.0 |
2090 | * |
2091 | * @param object|int|string $term |
2092 | * @param string $taxonomy |
2093 | * @return string HTML link to taxonomy term archive |
2094 | */ |
2095 | function get_term_link( $term, $taxonomy ) { |
2096 | global $wp_rewrite; |
2097 | |
2098 | // use legacy functions for core taxonomies until they are fully plugged in |
2099 | if ( $taxonomy == 'category' ) |
2100 | return get_category_link($term); |
2101 | if ( $taxonomy == 'post_tag' ) |
2102 | return get_tag_link($term); |
2103 | |
2104 | $termlink = $wp_rewrite->get_extra_permastruct($taxonomy); |
2105 | |
2106 | if ( !is_object($term) ) { |
2107 | if ( is_int($term) ) { |
2108 | $term = &get_term($term, $taxonomy); |
2109 | } else { |
2110 | $term = &get_term_by('slug', $term, $taxonomy); |
2111 | } |
2112 | } |
2113 | if ( is_wp_error( $term ) ) |
2114 | return $term; |
2115 | |
2116 | $slug = $term->slug; |
2117 | |
2118 | if ( empty($termlink) ) { |
2119 | $file = get_option('home') . '/'; |
2120 | $t = get_taxonomy($taxonomy); |
2121 | if ( $t->query_var ) |
2122 | $termlink = "$file?$t->query_var=$slug"; |
2123 | else |
2124 | $termlink = "$file?taxonomy=$taxonomy&term=$slug"; |
2125 | } else { |
2126 | $termlink = str_replace("%$taxonomy%", $slug, $termlink); |
2127 | $termlink = get_option('home') . user_trailingslashit($termlink, 'category'); |
2128 | } |
2129 | return apply_filters('term_link', $termlink, $term, $taxonomy); |
2130 | } |
2131 | |
2132 | /** |
2133 | * Display the taxonomies of a post with available options. |
2134 | * |
2135 | * This function can be used within the loop to display the taxonomies for a |
2136 | * post without specifying the Post ID. You can also use it outside the Loop to |
2137 | * display the taxonomies for a specific post. |
2138 | * |
2139 | * The available defaults are: |
2140 | * 'post' : default is 0. The post ID to get taxonomies of. |
2141 | * 'before' : default is empty string. Display before taxonomies list. |
2142 | * 'sep' : default is empty string. Separate every taxonomy with value in this. |
2143 | * 'after' : default is empty string. Display this after the taxonomies list. |
2144 | * |
2145 | * @since 2.5.0 |
2146 | * @uses get_the_taxonomies() |
2147 | * |
2148 | * @param array $args Override the defaults. |
2149 | */ |
2150 | function the_taxonomies($args = array()) { |
2151 | $defaults = array( |
2152 | 'post' => 0, |
2153 | 'before' => '', |
2154 | 'sep' => ' ', |
2155 | 'after' => '', |
2156 | ); |
2157 | |
2158 | $r = wp_parse_args( $args, $defaults ); |
2159 | extract( $r, EXTR_SKIP ); |
2160 | |
2161 | echo $before . join($sep, get_the_taxonomies($post)) . $after; |
2162 | } |
2163 | |
2164 | /** |
2165 | * Retrieve all taxonomies associated with a post. |
2166 | * |
2167 | * This function can be used within the loop. It will also return an array of |
2168 | * the taxonomies with links to the taxonomy and name. |
2169 | * |
2170 | * @since 2.5.0 |
2171 | * |
2172 | * @param int $post Optional. Post ID or will use Global Post ID (in loop). |
2173 | * @return array |
2174 | */ |
2175 | function get_the_taxonomies($post = 0) { |
2176 | if ( is_int($post) ) |
2177 | $post =& get_post($post); |
2178 | elseif ( !is_object($post) ) |
2179 | $post =& $GLOBALS['post']; |
2180 | |
2181 | $taxonomies = array(); |
2182 | |
2183 | if ( !$post ) |
2184 | return $taxonomies; |
2185 | |
2186 | $template = apply_filters('taxonomy_template', '%s: %l.'); |
2187 | |
2188 | foreach ( get_object_taxonomies($post) as $taxonomy ) { |
2189 | $t = (array) get_taxonomy($taxonomy); |
2190 | if ( empty($t['label']) ) |
2191 | $t['label'] = $taxonomy; |
2192 | if ( empty($t['args']) ) |
2193 | $t['args'] = array(); |
2194 | if ( empty($t['template']) ) |
2195 | $t['template'] = $template; |
2196 | |
2197 | $terms = get_object_term_cache($post->ID, $taxonomy); |
2198 | if ( empty($terms) ) |
2199 | $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']); |
2200 | |
2201 | $links = array(); |
2202 | |
2203 | foreach ( $terms as $term ) |
2204 | $links[] = "<a href='" . attribute_escape(get_term_link($term, $taxonomy)) . "'>$term->name</a>"; |
2205 | |
2206 | if ( $links ) |
2207 | $taxonomies[$taxonomy] = wp_sprintf($t['template'], $t['label'], $links, $terms); |
2208 | } |
2209 | return $taxonomies; |
2210 | } |
2211 | |
2212 | /** |
2213 | * Retrieve all taxonomies of a post with just the names. |
2214 | * |
2215 | * @since 2.5.0 |
2216 | * @uses get_object_taxonomies() |
2217 | * |
2218 | * @param int $post Optional. Post ID |
2219 | * @return array |
2220 | */ |
2221 | function get_post_taxonomies($post = 0) { |
2222 | $post =& get_post($post); |
2223 | |
2224 | return get_object_taxonomies($post); |
2225 | } |
2226 | |
2227 | /** |
2228 | * Determine if the given object is associated with any of the given terms. |
2229 | * |
2230 | * The given terms are checked against the object's terms' term_ids, names and slugs. |
2231 | * Terms given as integers will only be checked against the object's terms' term_ids. |
2232 | * If no terms are given, determines if object is associated with any terms in the given taxonomy. |
2233 | * |
2234 | * @since 2.7.0 |
2235 | * @uses get_object_term_cache() |
2236 | * @uses wp_get_object_terms() |
2237 | * |
2238 | * @param int $object_id. ID of the object (post ID, link ID, ...) |
2239 | * @param string $taxonomy. Single taxonomy name |
2240 | * @param int|string|array $terms Optional. Term term_id, name, slug or array of said |
2241 | * @return bool|WP_Error. WP_Error on input error. |
2242 | */ |
2243 | function is_object_in_term( $object_id, $taxonomy, $terms = null ) { |
2244 | if ( !$object_id = (int) $object_id ) |
2245 | return new WP_Error( 'invalid_object', __( 'Invalid object ID' ) ); |
2246 | |
2247 | $object_terms = get_object_term_cache( $object_id, $taxonomy ); |
2248 | if ( empty( $object_terms ) ) |
2249 | $object_terms = wp_get_object_terms( $object_id, $taxonomy ); |
2250 | |
2251 | if ( is_wp_error( $object_terms ) ) |
2252 | return $object_terms; |
2253 | if ( empty( $object_terms ) ) |
2254 | return false; |
2255 | if ( empty( $terms ) ) |
2256 | return ( !empty( $object_terms ) ); |
2257 | |
2258 | $terms = (array) $terms; |
2259 | |
2260 | if ( $ints = array_filter( $terms, 'is_int' ) ) |
2261 | $strs = array_diff( $terms, $ints ); |
2262 | else |
2263 | $strs =& $terms; |
2264 | |
2265 | foreach ( $object_terms as $object_term ) { |
2266 | if ( $ints && in_array( $object_term->term_id, $ints ) ) return true; // If int, check against term_id |
2267 | if ( $strs ) { |
2268 | if ( in_array( $object_term->term_id, $strs ) ) return true; |
2269 | if ( in_array( $object_term->name, $strs ) ) return true; |
2270 | if ( in_array( $object_term->slug, $strs ) ) return true; |
2271 | } |
2272 | } |
2273 | |
2274 | return false; |
2275 | } |
2276 | |
2277 | ?> |