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