PHP Cross Reference of WordPress Subversion HEAD |
| [ Index ] [ Classes ] [ Functions ] [ Variables ] [ Constants ] |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @package WordPress 4 * @subpackage Taxonomy 5 * @since 2.3 6 */ 7 8 // 9 // Taxonomy Registration 10 // 11 12 /** 13 * Default Taxonomy Objects 14 * @since 2.3 15 * @global array $wp_taxonomies 16 */ 17 $wp_taxonomies = array(); 18 $wp_taxonomies['category'] = (object) array('name' => 'category', 'object_type' => 'post', 'hierarchical' => true, 'update_count_callback' => '_update_post_term_count'); 19 $wp_taxonomies['post_tag'] = (object) array('name' => 'post_tag', 'object_type' => 'post', 'hierarchical' => false, 'update_count_callback' => '_update_post_term_count'); 20 $wp_taxonomies['link_category'] = (object) array('name' => 'link_category', 'object_type' => 'link', 'hierarchical' => false); 21 22 /** 23 * get_object_taxonomies() - Return all of the taxonomy names that are of $object_type 24 * 25 * It appears that this function can be used to find all of the names inside of 26 * $wp_taxonomies global variable. 27 * 28 * <code><?php $taxonomies = get_object_taxonomies('post'); ?></code> 29 * Should result in <code>Array('category', 'post_tag')</code> 30 * 31 * @package WordPress 32 * @subpackage Taxonomy 33 * @since 2.3 34 * 35 * @uses $wp_taxonomies 36 * 37 * @param string $object_type Name of the type of taxonomy object 38 * @return array The names of all taxonomy of $object_type. 39 */ 40 function get_object_taxonomies($object_type) { 41 global $wp_taxonomies; 42 43 $taxonomies = array(); 44 foreach ( $wp_taxonomies as $taxonomy ) { 45 if ( $object_type === $taxonomy->object_type ) 46 $taxonomies[] = $taxonomy->name; 47 } 48 49 return $taxonomies; 50 } 51 52 /** 53 * get_taxonomy() - Returns the taxonomy object of $taxonomy. 54 * 55 * The get_taxonomy function will first check that the parameter string given 56 * is a taxonomy object and if it is, it will return it. 57 * 58 * @package WordPress 59 * @subpackage Taxonomy 60 * @since 2.3 61 * 62 * @uses $wp_taxonomies 63 * @uses is_taxonomy() Checks whether taxonomy exists 64 * 65 * @param string $taxonomy Name of taxonomy object to return 66 * @return object|bool The Taxonomy Object or false if $taxonomy doesn't exist 67 */ 68 function get_taxonomy( $taxonomy ) { 69 global $wp_taxonomies; 70 71 if ( ! is_taxonomy($taxonomy) ) 72 return false; 73 74 return $wp_taxonomies[$taxonomy]; 75 } 76 77 /** 78 * is_taxonomy() - Checks that the taxonomy name exists 79 * 80 * @package WordPress 81 * @subpackage Taxonomy 82 * @since 2.3 83 * 84 * @uses $wp_taxonomies 85 * 86 * @param string $taxonomy Name of taxonomy object 87 * @return bool Whether the taxonomy exists or not. 88 */ 89 function is_taxonomy( $taxonomy ) { 90 global $wp_taxonomies; 91 92 return isset($wp_taxonomies[$taxonomy]); 93 } 94 95 /** 96 * is_taxonomy_hierarchical() - Whether the taxonomy object is hierarchical 97 * 98 * Checks to make sure that the taxonomy is an object first. Then Gets the object, and finally 99 * returns the hierarchical value in the object. 100 * 101 * A false return value might also mean that the taxonomy does not exist. 102 * 103 * @package WordPress 104 * @subpackage Taxonomy 105 * @since 2.3 106 * 107 * @uses is_taxonomy() Checks whether taxonomy exists 108 * @uses get_taxonomy() Used to get the taxonomy object 109 * 110 * @param string $taxonomy Name of taxonomy object 111 * @return bool Whether the taxonomy is hierarchical 112 */ 113 function is_taxonomy_hierarchical($taxonomy) { 114 if ( ! is_taxonomy($taxonomy) ) 115 return false; 116 117 $taxonomy = get_taxonomy($taxonomy); 118 return $taxonomy->hierarchical; 119 } 120 121 /** 122 * register_taxonomy() - Create or modify a taxonomy object. 123 * 124 * A simple function for creating or modifying a taxonomy object based on the parameters given. 125 * The function will accept an array (third optional parameter), along with strings for the 126 * taxonomy name and another string for the object type. 127 * 128 * The function keeps a default set, allowing for the $args to be optional but allow the other 129 * functions to still work. It is possible to overwrite the default set, which contains two 130 * keys: hierarchical and update_count_callback. 131 * 132 * Nothing is returned, so expect error maybe or use is_taxonomy() to check whether taxonomy exists. 133 * 134 * Optional $args contents: 135 * hierarachical - has some defined purpose at other parts of the API and is a boolean value. 136 * update_count_callback - works much like a hook, in that it will be called when the count is updated. 137 * 138 * @package WordPress 139 * @subpackage Taxonomy 140 * @since 2.3 141 * @uses $wp_taxonomies Inserts new taxonomy object into the list 142 * 143 * @param string $taxonomy Name of taxonomy object 144 * @param string $object_type Name of the object type for the taxonomy object. 145 * @param array|string $args See above description for the two keys values. 146 */ 147 function register_taxonomy( $taxonomy, $object_type, $args = array() ) { 148 global $wp_taxonomies; 149 150 $defaults = array('hierarchical' => false, 'update_count_callback' => ''); 151 $args = wp_parse_args($args, $defaults); 152 153 $args['name'] = $taxonomy; 154 $args['object_type'] = $object_type; 155 $wp_taxonomies[$taxonomy] = (object) $args; 156 } 157 158 // 159 // Term API 160 // 161 162 /** 163 * get_objects_in_term() - Return object_ids of valid taxonomy and term 164 * 165 * The strings of $taxonomies must exist before this function will continue. On failure of finding 166 * a valid taxonomy, it will return an WP_Error class, kind of like Exceptions in PHP 5, except you 167 * can't catch them. Even so, you can still test for the WP_Error class and get the error message. 168 * 169 * The $terms aren't checked the same as $taxonomies, but still need to exist for $object_ids to 170 * be returned. 171 * 172 * It is possible to change the order that object_ids is returned by either using PHP sort family 173 * functions or using the database by using $args with either ASC or DESC array. The value should 174 * be in the key named 'order'. 175 * 176 * @package WordPress 177 * @subpackage Taxonomy 178 * @since 2.3 179 * 180 * @uses $wpdb 181 * @uses wp_parse_args() Creates an array from string $args. 182 * 183 * @param string|array $terms String of term or array of string values of terms that will be used 184 * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names 185 * @param array|string $args Change the order of the object_ids, either ASC or DESC 186 * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success 187 * the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found. 188 */ 189 function get_objects_in_term( $terms, $taxonomies, $args = array() ) { 190 global $wpdb; 191 192 if ( !is_array( $terms) ) 193 $terms = array($terms); 194 195 if ( !is_array($taxonomies) ) 196 $taxonomies = array($taxonomies); 197 198 foreach ( $taxonomies as $taxonomy ) { 199 if ( ! is_taxonomy($taxonomy) ) 200 return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); 201 } 202 203 $defaults = array('order' => 'ASC'); 204 $args = wp_parse_args( $args, $defaults ); 205 extract($args, EXTR_SKIP); 206 207 $order = ( 'desc' == strtolower($order) ) ? 'DESC' : 'ASC'; 208 209 $terms = array_map('intval', $terms); 210 211 $taxonomies = "'" . implode("', '", $taxonomies) . "'"; 212 $terms = "'" . implode("', '", $terms) . "'"; 213 214 $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"); 215 216 if ( ! $object_ids ) 217 return array(); 218 219 return $object_ids; 220 } 221 222 /** 223 * get_term() - Get all Term data from database by Term ID. 224 * 225 * The usage of the get_term function is to apply filters to a term object. 226 * It is possible to get a term object from the database before applying the 227 * filters. 228 * 229 * $term ID must be part of $taxonomy, to get from the database. Failure, might be 230 * able to be captured by the hooks. Failure would be the same value as $wpdb returns for the 231 * get_row method. 232 * 233 * There are two hooks, one is specifically for each term, named 'get_term', and the second is 234 * for the taxonomy name, 'term_$taxonomy'. Both hooks gets the term object, and the taxonomy 235 * name as parameters. Both hooks are expected to return a Term object. 236 * 237 * 'get_term' hook - Takes two parameters the term Object and the taxonomy name. Must return 238 * term object. Used in @see get_term() as a catch-all filter for every $term. 239 * 240 * 'get_$taxonomy' hook - Takes two parameters the term Object and the taxonomy name. Must return 241 * term object. $taxonomy will be the taxonomy name, so for example, if 'category', it would be 242 * 'get_category' as the filter name. Useful for custom taxonomies or plugging into default taxonomies. 243 * 244 * @package WordPress 245 * @subpackage Taxonomy 246 * @since 2.3 247 * 248 * @uses $wpdb 249 * 250 * @param int|object $term If integer, will get from database. If object will apply filters and return $term. 251 * @param string $taxonomy Taxonomy name that $term is part of. 252 * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N 253 * @param string $filter {@internal Missing Description}} 254 * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not 255 * exist then WP_Error will be returned. 256 */ 257 function &get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { 258 global $wpdb; 259 260 if ( empty($term) ) 261 return null; 262 263 if ( ! is_taxonomy($taxonomy) ) 264 return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); 265 266 if ( is_object($term) ) { 267 wp_cache_add($term->term_id, $term, $taxonomy); 268 $_term = $term; 269 } else { 270 $term = (int) $term; 271 if ( ! $_term = wp_cache_get($term, $taxonomy) ) { 272 $_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) ); 273 wp_cache_add($term, $_term, $taxonomy); 274 } 275 } 276 277 $_term = apply_filters('get_term', $_term, $taxonomy); 278 $_term = apply_filters("get_$taxonomy", $_term, $taxonomy); 279 $_term = sanitize_term($_term, $taxonomy, $filter); 280 281 if ( $output == OBJECT ) { 282 return $_term; 283 } elseif ( $output == ARRAY_A ) { 284 return get_object_vars($_term); 285 } elseif ( $output == ARRAY_N ) { 286 return array_values(get_object_vars($_term)); 287 } else { 288 return $_term; 289 } 290 } 291 292 /** 293 * get_term_by() - Get all Term data from database by Term field and data. 294 * 295 * Warning: $value is not escaped for 'name' $field. You must do it yourself, if required. 296 * 297 * The default $field is 'id', therefore it is possible to also use null for field, but not 298 * recommended that you do so. 299 * 300 * If $value does not exist, the return value will be false. If $taxonomy exists and $field 301 * and $value combinations exist, the Term will be returned. 302 * 303 * @package WordPress 304 * @subpackage Taxonomy 305 * @since 2.3 306 * 307 * @uses $wpdb 308 * 309 * @param string $field Either 'slug', 'name', or 'id' 310 * @param string|int $value Search for this term value 311 * @param string $taxonomy Taxonomy Name 312 * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N 313 * @param string $filter {@internal Missing Description}} 314 * @return mixed Term Row from database. Will return false if $taxonomy does not exist or $term was not found. 315 */ 316 function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw') { 317 global $wpdb; 318 319 if ( ! is_taxonomy($taxonomy) ) 320 return false; 321 322 if ( 'slug' == $field ) { 323 $field = 't.slug'; 324 $value = sanitize_title($value); 325 if ( empty($value) ) 326 return false; 327 } else if ( 'name' == $field ) { 328 // Assume already escaped 329 $field = 't.name'; 330 } else { 331 $field = 't.term_id'; 332 $value = (int) $value; 333 } 334 335 $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) ); 336 if ( !$term ) 337 return false; 338 339 wp_cache_add($term->term_id, $term, $taxonomy); 340 341 $term = sanitize_term($term, $taxonomy, $filter); 342 343 if ( $output == OBJECT ) { 344 return $term; 345 } elseif ( $output == ARRAY_A ) { 346 return get_object_vars($term); 347 } elseif ( $output == ARRAY_N ) { 348 return array_values(get_object_vars($term)); 349 } else { 350 return $term; 351 } 352 } 353 354 /** 355 * get_term_children() - Merge all term children into a single array. 356 * 357 * This recursive function will merge all of the children of $term into 358 * the same array. Only useful for taxonomies which are hierarchical. 359 * 360 * Will return an empty array if $term does not exist in $taxonomy. 361 * 362 * @package WordPress 363 * @subpackage Taxonomy 364 * @since 2.3 365 * 366 * @uses $wpdb 367 * @uses _get_term_hierarchy() 368 * @uses get_term_children() Used to get the children of both $taxonomy and the parent $term 369 * 370 * @param string $term Name of Term to get children 371 * @param string $taxonomy Taxonomy Name 372 * @return array|WP_Error List of Term Objects. WP_Error returned if $taxonomy does not exist 373 */ 374 function get_term_children( $term, $taxonomy ) { 375 if ( ! is_taxonomy($taxonomy) ) 376 return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); 377 378 $terms = _get_term_hierarchy($taxonomy); 379 380 if ( ! isset($terms[$term]) ) 381 return array(); 382 383 $children = $terms[$term]; 384 385 foreach ( $terms[$term] as $child ) { 386 if ( isset($terms[$child]) ) 387 $children = array_merge($children, get_term_children($child, $taxonomy)); 388 } 389 390 return $children; 391 } 392 393 /** 394 * get_term_field() - Get sanitized Term field 395 * 396 * Does checks for $term, based on the $taxonomy. The function is for 397 * contextual reasons and for simplicity of usage. @see sanitize_term_field() for 398 * more information. 399 * 400 * @package WordPress 401 * @subpackage Taxonomy 402 * @since 2.3 403 * 404 * @uses sanitize_term_field() Passes the return value in sanitize_term_field on success. 405 * 406 * @param string $field Term field to fetch 407 * @param int $term Term ID 408 * @param string $taxonomy Taxonomy Name 409 * @param string $context {@internal Missing Description}} 410 * @return mixed Will return an empty string if $term is not an object or if $field is not set in $term. 411 */ 412 function get_term_field( $field, $term, $taxonomy, $context = 'display' ) { 413 $term = (int) $term; 414 $term = get_term( $term, $taxonomy ); 415 if ( is_wp_error($term) ) 416 return $term; 417 418 if ( !is_object($term) ) 419 return ''; 420 421 if ( !isset($term->$field) ) 422 return ''; 423 424 return sanitize_term_field($field, $term->$field, $term->term_id, $taxonomy, $context); 425 } 426 427 /** 428 * get_term_to_edit() - Sanitizes Term for editing 429 * 430 * Return value is @see sanitize_term() and usage is for sanitizing the term 431 * for editing. Function is for contextual and simplicity. 432 * 433 * @package WordPress 434 * @subpackage Taxonomy 435 * @since 2.3 436 * 437 * @uses sanitize_term() Passes the return value on success 438 * 439 * @param int|object $id Term ID or Object 440 * @param string $taxonomy Taxonomy Name 441 * @return mixed|null|WP_Error Will return empty string if $term is not an object. 442 */ 443 function get_term_to_edit( $id, $taxonomy ) { 444 $term = get_term( $id, $taxonomy ); 445 446 if ( is_wp_error($term) ) 447 return $term; 448 449 if ( !is_object($term) ) 450 return ''; 451 452 return sanitize_term($term, $taxonomy, 'edit'); 453 } 454 455 /** 456 * get_terms() - Retrieve the terms in taxonomy or list of taxonomies. 457 * 458 * You can fully inject any customizations to the query before it is sent, as well as control 459 * the output with a filter. 460 * 461 * The 'get_terms' filter will be called when the cache has the term and will pass the found 462 * term along with the array of $taxonomies and array of $args. This filter is also called 463 * before the array of terms is passed and will pass the array of terms, along with the $taxonomies 464 * and $args. 465 * 466 * The 'list_terms_exclusions' filter passes the compiled exclusions along with the $args. 467 * 468 * The list that $args can contain, which will overwrite the defaults. 469 * orderby - Default is 'name'. Can be name, count, or nothing (will use term_id). 470 * order - Default is ASC. Can use DESC. 471 * hide_empty - Default is true. Will not return empty $terms. 472 * fields - Default is all. 473 * slug - Any terms that has this value. Default is empty string. 474 * hierarchical - Whether to return hierarchical taxonomy. Default is true. 475 * name__like - Default is empty string. 476 * 477 * The argument 'pad_counts' will count all of the children along with the $terms. 478 * 479 * The 'get' argument allows for overwriting 'hide_empty' and 'child_of', which can be done by 480 * setting the value to 'all', instead of its default empty string value. 481 * 482 * The 'child_of' argument will be used if you use multiple taxonomy or the first $taxonomy 483 * isn't hierarchical or 'parent' isn't used. The default is 0, which will be translated to 484 * a false value. If 'child_of' is set, then 'child_of' value will be tested against 485 * $taxonomy to see if 'child_of' is contained within. Will return an empty array if test 486 * fails. 487 * 488 * If 'parent' is set, then it will be used to test against the first taxonomy. Much like 489 * 'child_of'. Will return an empty array if the test fails. 490 * 491 * @package WordPress 492 * @subpackage Taxonomy 493 * @since 2.3 494 * 495 * @uses $wpdb 496 * @uses wp_parse_args() Merges the defaults with those defined by $args and allows for strings. 497 * 498 * @param string|array Taxonomy name or list of Taxonomy names 499 * @param string|array $args The values of what to search for when returning terms 500 * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist. 501 */ 502 function &get_terms($taxonomies, $args = '') { 503 global $wpdb; 504 505 $single_taxonomy = false; 506 if ( !is_array($taxonomies) ) { 507 $single_taxonomy = true; 508 $taxonomies = array($taxonomies); 509 } 510 511 foreach ( $taxonomies as $taxonomy ) { 512 if ( ! is_taxonomy($taxonomy) ) 513 return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy')); 514 } 515 516 $in_taxonomies = "'" . implode("', '", $taxonomies) . "'"; 517 518 $defaults = array('orderby' => 'name', 'order' => 'ASC', 519 'hide_empty' => true, 'exclude' => '', 'include' => '', 520 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', 521 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 522 'pad_counts' => false); 523 $args = wp_parse_args( $args, $defaults ); 524 $args['number'] = absint( $args['number'] ); 525 if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || 526 '' != $args['parent'] ) { 527 $args['child_of'] = 0; 528 $args['hierarchical'] = false; 529 $args['pad_counts'] = false; 530 } 531 532 if ( 'all' == $args['get'] ) { 533 $args['child_of'] = 0; 534 $args['hide_empty'] = 0; 535 $args['hierarchical'] = false; 536 $args['pad_counts'] = false; 537 } 538 extract($args, EXTR_SKIP); 539 540 if ( $child_of ) { 541 $hierarchy = _get_term_hierarchy($taxonomies[0]); 542 if ( !isset($hierarchy[$child_of]) ) 543 return array(); 544 } 545 546 if ( $parent ) { 547 $hierarchy = _get_term_hierarchy($taxonomies[0]); 548 if ( !isset($hierarchy[$parent]) ) 549 return array(); 550 } 551 552 $key = md5( serialize( $args ) . serialize( $taxonomies ) ); 553 if ( $cache = wp_cache_get( 'get_terms', 'terms' ) ) { 554 if ( isset( $cache[ $key ] ) ) 555 return apply_filters('get_terms', $cache[$key], $taxonomies, $args); 556 } 557 558 if ( 'count' == $orderby ) 559 $orderby = 'tt.count'; 560 else if ( 'name' == $orderby ) 561 $orderby = 't.name'; 562 else if ( 'slug' == $orderby ) 563 $orderby = 't.slug'; 564 else if ( 'term_group' == $orderby ) 565 $orderby = 't.term_group'; 566 else 567 $orderby = 't.term_id'; 568 569 $where = ''; 570 $inclusions = ''; 571 if ( !empty($include) ) { 572 $exclude = ''; 573 $interms = preg_split('/[\s,]+/',$include); 574 if ( count($interms) ) { 575 foreach ( $interms as $interm ) { 576 if (empty($inclusions)) 577 $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' '; 578 else 579 $inclusions .= ' OR t.term_id = ' . intval($interm) . ' '; 580 } 581 } 582 } 583 584 if ( !empty($inclusions) ) 585 $inclusions .= ')'; 586 $where .= $inclusions; 587 588 $exclusions = ''; 589 if ( !empty($exclude) ) { 590 $exterms = preg_split('/[\s,]+/',$exclude); 591 if ( count($exterms) ) { 592 foreach ( $exterms as $exterm ) { 593 if (empty($exclusions)) 594 $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; 595 else 596 $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' '; 597 } 598 } 599 } 600 601 if ( !empty($exclusions) ) 602 $exclusions .= ')'; 603 $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args ); 604 $where .= $exclusions; 605 606 if ( !empty($slug) ) { 607 $slug = sanitize_title($slug); 608 $where .= " AND t.slug = '$slug'"; 609 } 610 611 if ( !empty($name__like) ) 612 $where .= " AND t.name LIKE '{$name__like}%'"; 613 614 if ( '' != $parent ) { 615 $parent = (int) $parent; 616 $where .= " AND tt.parent = '$parent'"; 617 } 618 619 if ( $hide_empty && !$hierarchical ) 620 $where .= ' AND tt.count > 0'; 621 622 if ( !empty($number) ) 623 $number = 'LIMIT ' . $number; 624 else 625 $number = ''; 626 627 if ( 'all' == $fields )