コード例 #1
0
/**
 * Retrieve the terms in a given taxonomy or list of taxonomies.
 *
 * You can fully inject any customizations to the query before it is sent, as
 * well as control the output with a filter.
 *
 * The {@see 'get_terms'} filter will be called when the cache has the term and will
 * pass the found term along with the array of $taxonomies and array of $args.
 * This filter is also called before the array of terms is passed and will pass
 * the array of terms, along with the $taxonomies and $args.
 *
 * The {@see 'list_terms_exclusions'} filter passes the compiled exclusions along with
 * the $args.
 *
 * The {@see 'get_terms_orderby'} filter passes the `ORDER BY` clause for the query
 * along with the $args array.
 *
 * @since 2.3.0
 * @since 4.2.0 Introduced 'name' and 'childless' parameters.
 * @since 4.4.0 Introduced the ability to pass 'term_id' as an alias of 'id' for the `orderby` parameter.
 *              Introduced the 'meta_query' and 'update_term_meta_cache' parameters. Converted to return
 *              a list of WP_Term objects.
 *
 * @global wpdb  $wpdb WordPress database abstraction object.
 * @global array $wp_filter
 *
 * @param string|array $taxonomies Taxonomy name or list of Taxonomy names.
 * @param array|string $args {
 *     Optional. Array or string of arguments to get terms.
 *
 *     @type string       $orderby                Field(s) to order terms by. Accepts term fields ('name', 'slug',
 *                                                'term_group', 'term_id', 'id', 'description'), 'count' for term
 *                                                taxonomy count, 'include' to match the 'order' of the $include param,
 *                                                or 'none' to skip ORDER BY. Defaults to 'name'.
 *     @type string       $order                  Whether to order terms in ascending or descending order.
 *                                                Accepts 'ASC' (ascending) or 'DESC' (descending).
 *                                                Default 'ASC'.
 *     @type bool|int     $hide_empty             Whether to hide terms not assigned to any posts. Accepts
 *                                                1|true or 0|false. Default 1|true.
 *     @type array|string $include                Array or comma/space-separated string of term ids to include.
 *                                                Default empty array.
 *     @type array|string $exclude                Array or comma/space-separated string of term ids to exclude.
 *                                                If $include is non-empty, $exclude is ignored.
 *                                                Default empty array.
 *     @type array|string $exclude_tree           Array or comma/space-separated string of term ids to exclude
 *                                                along with all of their descendant terms. If $include is
 *                                                non-empty, $exclude_tree is ignored. Default empty array.
 *     @type int|string   $number                 Maximum number of terms to return. Accepts ''|0 (all) or any
 *                                                positive number. Default ''|0 (all).
 *     @type int          $offset                 The number by which to offset the terms query. Default empty.
 *     @type string       $fields                 Term fields to query for. Accepts 'all' (returns an array of complete
 *                                                term objects), 'ids' (returns an array of ids), 'id=>parent' (returns
 *                                                an associative array with ids as keys, parent term IDs as values),
 *                                                'names' (returns an array of term names), 'count' (returns the number
 *                                                of matching terms), 'id=>name' (returns an associative array with ids
 *                                                as keys, term names as values), or 'id=>slug' (returns an associative
 *                                                array with ids as keys, term slugs as values). Default 'all'.
 *     @type string|array $name                   Optional. Name or array of names to return term(s) for. Default empty.
 *     @type string|array $slug                   Optional. Slug or array of slugs to return term(s) for. Default empty.
 *     @type bool         $hierarchical           Whether to include terms that have non-empty descendants (even
 *                                                if $hide_empty is set to true). Default true.
 *     @type string       $search                 Search criteria to match terms. Will be SQL-formatted with
 *                                                wildcards before and after. Default empty.
 *     @type string       $name__like             Retrieve terms with criteria by which a term is LIKE $name__like.
 *                                                Default empty.
 *     @type string       $description__like      Retrieve terms where the description is LIKE $description__like.
 *                                                Default empty.
 *     @type bool         $pad_counts             Whether to pad the quantity of a term's children in the quantity
 *                                                of each term's "count" object variable. Default false.
 *     @type string       $get                    Whether to return terms regardless of ancestry or whether the terms
 *                                                are empty. Accepts 'all' or empty (disabled). Default empty.
 *     @type int          $child_of               Term ID to retrieve child terms of. If multiple taxonomies
 *                                                are passed, $child_of is ignored. Default 0.
 *     @type int|string   $parent                 Parent term ID to retrieve direct-child terms of. Default empty.
 *     @type bool         $childless              True to limit results to terms that have no children. This parameter
 *                                                has no effect on non-hierarchical taxonomies. Default false.
 *     @type string       $cache_domain           Unique cache key to be produced when this query is stored in an
 *                                                object cache. Default is 'core'.
 *     @type bool         $update_term_meta_cache Whether to prime meta caches for matched terms. Default true.
 *     @type array        $meta_query             Meta query clauses to limit retrieved terms by.
 *                                                See `WP_Meta_Query`. Default empty.
 * }
 * @return array|int|WP_Error List of WP_Term instances and their children. Will return WP_Error, if any of $taxonomies
 *                            do not exist.
 */
function get_terms($taxonomies, $args = '')
{
    global $wpdb;
    $empty_array = array();
    $single_taxonomy = !is_array($taxonomies) || 1 === count($taxonomies);
    if (!is_array($taxonomies)) {
        $taxonomies = array($taxonomies);
    }
    foreach ($taxonomies as $taxonomy) {
        if (!taxonomy_exists($taxonomy)) {
            return new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
        }
    }
    $defaults = array('orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(), 'number' => '', 'fields' => 'all', 'name' => '', 'slug' => '', 'parent' => '', 'childless' => false, 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'description__like' => '', 'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core', 'update_term_meta_cache' => true, 'meta_query' => '');
    $args = wp_parse_args($args, $defaults);
    $args['number'] = absint($args['number']);
    $args['offset'] = absint($args['offset']);
    // Save queries by not crawling the tree in the case of multiple taxes or a flat tax.
    $has_hierarchical_tax = false;
    foreach ($taxonomies as $_tax) {
        if (is_taxonomy_hierarchical($_tax)) {
            $has_hierarchical_tax = true;
        }
    }
    if (!$has_hierarchical_tax) {
        $args['hierarchical'] = false;
        $args['pad_counts'] = false;
    }
    // 'parent' overrides 'child_of'.
    if (0 < intval($args['parent'])) {
        $args['child_of'] = false;
    }
    if ('all' == $args['get']) {
        $args['childless'] = false;
        $args['child_of'] = 0;
        $args['hide_empty'] = 0;
        $args['hierarchical'] = false;
        $args['pad_counts'] = false;
    }
    /**
     * Filter the terms query arguments.
     *
     * @since 3.1.0
     *
     * @param array $args       An array of get_term() arguments.
     * @param array $taxonomies An array of taxonomies.
     */
    $args = apply_filters('get_terms_args', $args, $taxonomies);
    // Avoid the query if the queried parent/child_of term has no descendants.
    $child_of = $args['child_of'];
    $parent = $args['parent'];
    if ($child_of) {
        $_parent = $child_of;
    } elseif ($parent) {
        $_parent = $parent;
    } else {
        $_parent = false;
    }
    if ($_parent) {
        $in_hierarchy = false;
        foreach ($taxonomies as $_tax) {
            $hierarchy = _get_term_hierarchy($_tax);
            if (isset($hierarchy[$_parent])) {
                $in_hierarchy = true;
            }
        }
        if (!$in_hierarchy) {
            return $empty_array;
        }
    }
    $_orderby = strtolower($args['orderby']);
    if ('count' == $_orderby) {
        $orderby = 'tt.count';
    } elseif ('name' == $_orderby) {
        $orderby = 't.name';
    } elseif ('slug' == $_orderby) {
        $orderby = 't.slug';
    } elseif ('include' == $_orderby && !empty($args['include'])) {
        $include = implode(',', array_map('absint', $args['include']));
        $orderby = "FIELD( t.term_id, {$include} )";
    } elseif ('term_group' == $_orderby) {
        $orderby = 't.term_group';
    } elseif ('description' == $_orderby) {
        $orderby = 'tt.description';
    } elseif ('none' == $_orderby) {
        $orderby = '';
    } elseif (empty($_orderby) || 'id' == $_orderby || 'term_id' === $_orderby) {
        $orderby = 't.term_id';
    } else {
        $orderby = 't.name';
    }
    /**
     * Filter the ORDERBY clause of the terms query.
     *
     * @since 2.8.0
     *
     * @param string $orderby    `ORDERBY` clause of the terms query.
     * @param array  $args       An array of terms query arguments.
     * @param array  $taxonomies An array of taxonomies.
     */
    $orderby = apply_filters('get_terms_orderby', $orderby, $args, $taxonomies);
    $order = strtoupper($args['order']);
    if (!empty($orderby)) {
        $orderby = "ORDER BY {$orderby}";
    } else {
        $order = '';
    }
    if ('' !== $order && !in_array($order, array('ASC', 'DESC'))) {
        $order = 'ASC';
    }
    $where = "tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')";
    $exclude = $args['exclude'];
    $exclude_tree = $args['exclude_tree'];
    $include = $args['include'];
    $inclusions = '';
    if (!empty($include)) {
        $exclude = '';
        $exclude_tree = '';
        $inclusions = implode(',', wp_parse_id_list($include));
    }
    if (!empty($inclusions)) {
        $inclusions = ' AND t.term_id IN ( ' . $inclusions . ' )';
        $where .= $inclusions;
    }
    $exclusions = array();
    if (!empty($exclude_tree)) {
        $exclude_tree = wp_parse_id_list($exclude_tree);
        $excluded_children = $exclude_tree;
        foreach ($exclude_tree as $extrunk) {
            $excluded_children = array_merge($excluded_children, (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids', 'hide_empty' => 0)));
        }
        $exclusions = array_merge($excluded_children, $exclusions);
    }
    if (!empty($exclude)) {
        $exclusions = array_merge(wp_parse_id_list($exclude), $exclusions);
    }
    // 'childless' terms are those without an entry in the flattened term hierarchy.
    $childless = (bool) $args['childless'];
    if ($childless) {
        foreach ($taxonomies as $_tax) {
            $term_hierarchy = _get_term_hierarchy($_tax);
            $exclusions = array_merge(array_keys($term_hierarchy), $exclusions);
        }
    }
    if (!empty($exclusions)) {
        $exclusions = ' AND t.term_id NOT IN (' . implode(',', array_map('intval', $exclusions)) . ')';
    } else {
        $exclusions = '';
    }
    /**
     * Filter the terms to exclude from the terms query.
     *
     * @since 2.3.0
     *
     * @param string $exclusions `NOT IN` clause of the terms query.
     * @param array  $args       An array of terms query arguments.
     * @param array  $taxonomies An array of taxonomies.
     */
    $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args, $taxonomies);
    if (!empty($exclusions)) {
        $where .= $exclusions;
    }
    if (!empty($args['name'])) {
        $names = (array) $args['name'];
        foreach ($names as &$_name) {
            $_name = sanitize_term_field('name', $_name, 0, reset($taxonomies), 'db');
        }
        $where .= " AND t.name IN ('" . implode("', '", array_map('esc_sql', $names)) . "')";
    }
    if (!empty($args['slug'])) {
        if (is_array($args['slug'])) {
            $slug = array_map('sanitize_title', $args['slug']);
            $where .= " AND t.slug IN ('" . implode("', '", $slug) . "')";
        } else {
            $slug = sanitize_title($args['slug']);
            $where .= " AND t.slug = '{$slug}'";
        }
    }
    if (!empty($args['name__like'])) {
        $where .= $wpdb->prepare(" AND t.name LIKE %s", '%' . $wpdb->esc_like($args['name__like']) . '%');
    }
    if (!empty($args['description__like'])) {
        $where .= $wpdb->prepare(" AND tt.description LIKE %s", '%' . $wpdb->esc_like($args['description__like']) . '%');
    }
    if ('' !== $parent) {
        $parent = (int) $parent;
        $where .= " AND tt.parent = '{$parent}'";
    }
    $hierarchical = $args['hierarchical'];
    if ('count' == $args['fields']) {
        $hierarchical = false;
    }
    if ($args['hide_empty'] && !$hierarchical) {
        $where .= ' AND tt.count > 0';
    }
    $number = $args['number'];
    $offset = $args['offset'];
    // Don't limit the query results when we have to descend the family tree.
    if ($number && !$hierarchical && !$child_of && '' === $parent) {
        if ($offset) {
            $limits = 'LIMIT ' . $offset . ',' . $number;
        } else {
            $limits = 'LIMIT ' . $number;
        }
    } else {
        $limits = '';
    }
    if (!empty($args['search'])) {
        $like = '%' . $wpdb->esc_like($args['search']) . '%';
        $where .= $wpdb->prepare(' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like);
    }
    // Meta query support.
    $join = '';
    if (!empty($args['meta_query'])) {
        $mquery = new WP_Meta_Query($args['meta_query']);
        $mq_sql = $mquery->get_sql('term', 't', 'term_id');
        $join .= $mq_sql['join'];
        $where .= $mq_sql['where'];
    }
    $selects = array();
    switch ($args['fields']) {
        case 'all':
            $selects = array('t.*', 'tt.*');
            break;
        case 'ids':
        case 'id=>parent':
            $selects = array('t.term_id', 'tt.parent', 'tt.count', 'tt.taxonomy');
            break;
        case 'names':
            $selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name', 'tt.taxonomy');
            break;
        case 'count':
            $orderby = '';
            $order = '';
            $selects = array('COUNT(*)');
            break;
        case 'id=>name':
            $selects = array('t.term_id', 't.name', 'tt.count', 'tt.taxonomy');
            break;
        case 'id=>slug':
            $selects = array('t.term_id', 't.slug', 'tt.count', 'tt.taxonomy');
            break;
    }
    $_fields = $args['fields'];
    /**
     * Filter the fields to select in the terms query.
     *
     * Field lists modified using this filter will only modify the term fields returned
     * by the function when the `$fields` parameter set to 'count' or 'all'. In all other
     * cases, the term fields in the results array will be determined by the `$fields`
     * parameter alone.
     *
     * Use of this filter can result in unpredictable behavior, and is not recommended.
     *
     * @since 2.8.0
     *
     * @param array $selects    An array of fields to select for the terms query.
     * @param array $args       An array of term query arguments.
     * @param array $taxonomies An array of taxonomies.
     */
    $fields = implode(', ', apply_filters('get_terms_fields', $selects, $args, $taxonomies));
    $join .= " INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id";
    $pieces = array('fields', 'join', 'where', 'orderby', 'order', 'limits');
    /**
     * Filter the terms query SQL clauses.
     *
     * @since 3.1.0
     *
     * @param array $pieces     Terms query SQL clauses.
     * @param array $taxonomies An array of taxonomies.
     * @param array $args       An array of terms query arguments.
     */
    $clauses = apply_filters('terms_clauses', compact($pieces), $taxonomies, $args);
    $fields = isset($clauses['fields']) ? $clauses['fields'] : '';
    $join = isset($clauses['join']) ? $clauses['join'] : '';
    $where = isset($clauses['where']) ? $clauses['where'] : '';
    $orderby = isset($clauses['orderby']) ? $clauses['orderby'] : '';
    $order = isset($clauses['order']) ? $clauses['order'] : '';
    $limits = isset($clauses['limits']) ? $clauses['limits'] : '';
    $query = "SELECT {$fields} FROM {$wpdb->terms} AS t {$join} WHERE {$where} {$orderby} {$order} {$limits}";
    // $args can be anything. Only use the args defined in defaults to compute the key.
    $key = md5(serialize(wp_array_slice_assoc($args, array_keys($defaults))) . serialize($taxonomies) . $query);
    $last_changed = wp_cache_get('last_changed', 'terms');
    if (!$last_changed) {
        $last_changed = microtime();
        wp_cache_set('last_changed', $last_changed, 'terms');
    }
    $cache_key = "get_terms:{$key}:{$last_changed}";
    $cache = wp_cache_get($cache_key, 'terms');
    if (false !== $cache) {
        if ('all' === $_fields) {
            $cache = array_map('get_term', $cache);
        }
        /**
         * Filter the given taxonomy's terms cache.
         *
         * @since 2.3.0
         *
         * @param array $cache      Cached array of terms for the given taxonomy.
         * @param array $taxonomies An array of taxonomies.
         * @param array $args       An array of get_terms() arguments.
         */
        return apply_filters('get_terms', $cache, $taxonomies, $args);
    }
    if ('count' == $_fields) {
        return $wpdb->get_var($query);
    }
    $terms = $wpdb->get_results($query);
    if ('all' == $_fields) {
        update_term_cache($terms);
    }
    // Prime termmeta cache.
    if ($args['update_term_meta_cache']) {
        $term_ids = wp_list_pluck($terms, 'term_id');
        update_termmeta_cache($term_ids);
    }
    if (empty($terms)) {
        wp_cache_add($cache_key, array(), 'terms', DAY_IN_SECONDS);
        /** This filter is documented in wp-includes/taxonomy-functions.php */
        return apply_filters('get_terms', array(), $taxonomies, $args);
    }
    if ($child_of) {
        foreach ($taxonomies as $_tax) {
            $children = _get_term_hierarchy($_tax);
            if (!empty($children)) {
                $terms = _get_term_children($child_of, $terms, $_tax);
            }
        }
    }
    // Update term counts to include children.
    if ($args['pad_counts'] && 'all' == $_fields) {
        foreach ($taxonomies as $_tax) {
            _pad_term_counts($terms, $_tax);
        }
    }
    // Make sure we show empty categories that have children.
    if ($hierarchical && $args['hide_empty'] && is_array($terms)) {
        foreach ($terms as $k => $term) {
            if (!$term->count) {
                $children = get_term_children($term->term_id, $term->taxonomy);
                if (is_array($children)) {
                    foreach ($children as $child_id) {
                        $child = get_term($child_id, $term->taxonomy);
                        if ($child->count) {
                            continue 2;
                        }
                    }
                }
                // It really is empty.
                unset($terms[$k]);
            }
        }
    }
    $_terms = array();
    if ('id=>parent' == $_fields) {
        foreach ($terms as $term) {
            $_terms[$term->term_id] = $term->parent;
        }
    } elseif ('ids' == $_fields) {
        foreach ($terms as $term) {
            $_terms[] = $term->term_id;
        }
    } elseif ('names' == $_fields) {
        foreach ($terms as $term) {
            $_terms[] = $term->name;
        }
    } elseif ('id=>name' == $_fields) {
        foreach ($terms as $term) {
            $_terms[$term->term_id] = $term->name;
        }
    } elseif ('id=>slug' == $_fields) {
        foreach ($terms as $term) {
            $_terms[$term->term_id] = $term->slug;
        }
    }
    if (!empty($_terms)) {
        $terms = $_terms;
    }
    if ($number && is_array($terms) && count($terms) > $number) {
        $terms = array_slice($terms, $offset, $number);
    }
    wp_cache_add($cache_key, $terms, 'terms', DAY_IN_SECONDS);
    if ('all' === $_fields) {
        $terms = array_map('get_term', $terms);
    }
    /** This filter is documented in wp-includes/taxonomy */
    return apply_filters('get_terms', $terms, $taxonomies, $args);
}
コード例 #2
0
 /**
  * Extended get_terms public static function support
  * - Limit category
  * - Limit days
  * - Selection restrict
  * - Min usage
  *
  * @param string|array $taxonomies
  * @param string $args
  * @return array
  */
 public static function getTerms($taxonomies, $args = '')
 {
     global $wpdb;
     $empty_array = array();
     $join_relation = false;
     $single_taxonomy = false;
     if (!is_array($taxonomies)) {
         $single_taxonomy = true;
         $taxonomies = array($taxonomies);
     }
     foreach ((array) $taxonomies as $taxonomy) {
         if (!taxonomy_exists($taxonomy)) {
             $error = new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
             return $error;
         }
     }
     $in_taxonomies = "'" . implode("', '", $taxonomies) . "'";
     $defaults = array('orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(), 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'pad_counts' => false, 'offset' => '', 'search' => '', 'limit_days' => 0, 'category' => 0, 'min_usage' => 0, 'st_name__like' => '');
     $args = wp_parse_args($args, $defaults);
     // Translate selection order
     $args['orderby'] = self::compatOldOrder($args['selectionby'], 'orderby');
     $args['order'] = self::compatOldOrder($args['selection'], 'order');
     $args['number'] = absint($args['number']);
     $args['offset'] = absint($args['offset']);
     $args['limit_days'] = absint($args['limit_days']);
     $args['min_usage'] = absint($args['min_usage']);
     if (!$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' !== $args['parent']) {
         $args['child_of'] = 0;
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     if ('all' == $args['get']) {
         $args['child_of'] = 0;
         $args['hide_empty'] = 0;
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     extract($args, EXTR_SKIP);
     if ($child_of) {
         $hierarchy = _get_term_hierarchy($taxonomies[0]);
         if (!isset($hierarchy[$child_of])) {
             return $empty_array;
         }
     }
     if ($parent) {
         $hierarchy = _get_term_hierarchy($taxonomies[0]);
         if (!isset($hierarchy[$parent])) {
             return $empty_array;
         }
     }
     // $args can be whatever, only use the args defined in defaults to compute the key
     $filter_key = has_filter('list_terms_exclusions') ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
     $key = md5(serialize(compact(array_keys($defaults))) . serialize($taxonomies) . $filter_key);
     $last_changed = wp_cache_get('last_changed', 's-terms');
     if (!$last_changed) {
         $last_changed = time();
         wp_cache_set('last_changed', $last_changed, 's-terms');
     }
     $cache_key = "get_terms:{$key}:{$last_changed}";
     $cache = wp_cache_get($cache_key, 's-terms');
     if (false !== $cache) {
         $cache = apply_filters('get_terms', $cache, $taxonomies, $args);
         return $cache;
     }
     $_orderby = strtolower($orderby);
     if ('count' == $_orderby) {
         $orderby = 'tt.count';
     }
     if ('random' == $_orderby) {
         $orderby = 'RAND()';
     } else {
         if ('name' == $_orderby) {
             $orderby = 't.name';
         } else {
             if ('slug' == $_orderby) {
                 $orderby = 't.slug';
             } else {
                 if ('term_group' == $_orderby) {
                     $orderby = 't.term_group';
                 } elseif (empty($_orderby) || 'id' == $_orderby) {
                     $orderby = 't.term_id';
                 }
             }
         }
     }
     $orderby = apply_filters('get_terms_orderby', $orderby, $args);
     if (!empty($orderby)) {
         $orderby = "ORDER BY {$orderby}";
     } else {
         $order = '';
     }
     $where = '';
     $inclusions = '';
     if (!empty($include)) {
         $exclude = '';
         $exclude_tree = '';
         $interms = wp_parse_id_list($include);
         foreach ($interms as $interm) {
             if (empty($inclusions)) {
                 $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
             } else {
                 $inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
             }
         }
     }
     if (!empty($inclusions)) {
         $inclusions .= ')';
     }
     $where .= $inclusions;
     $exclusions = '';
     if (!empty($exclude_tree)) {
         $excluded_trunks = wp_parse_id_list($exclude_tree);
         foreach ($excluded_trunks as $extrunk) {
             $excluded_children = (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids'));
             $excluded_children[] = $extrunk;
             foreach ($excluded_children as $exterm) {
                 if (empty($exclusions)) {
                     $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
                 } else {
                     $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
                 }
             }
         }
     }
     if (!empty($exclude)) {
         $exterms = wp_parse_id_list($exclude);
         foreach ($exterms as $exterm) {
             if (empty($exclusions)) {
                 $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
             } else {
                 $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
             }
         }
     }
     if (!empty($exclusions)) {
         $exclusions .= ')';
     }
     $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args);
     $where .= $exclusions;
     // ST Features : Restrict category
     if ($category != 0) {
         if (!is_array($taxonomies)) {
             $taxonomies = array($taxonomies);
         }
         $incategories = wp_parse_id_list($category);
         $taxonomies = "'" . implode("', '", $taxonomies) . "'";
         $incategories = "'" . implode("', '", $incategories) . "'";
         $where .= " AND tr.object_id IN ( ";
         $where .= "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 INNER JOIN {$wpdb->posts} as p ON tr.object_id=p.ID WHERE tt.term_id IN ({$incategories}) AND p.post_status='publish'";
         $where .= " ) ";
         $join_relation = true;
         unset($incategories, $category);
     }
     // ST Features : Limit posts date
     if ($limit_days != 0) {
         $where .= " AND tr.object_id IN ( ";
         $where .= "SELECT DISTINCT ID FROM {$wpdb->posts} AS p WHERE p.post_status='publish' AND " . (is_page_have_tags() ? "p.post_type IN('page', 'post')" : "post_type = 'post'") . " AND p.post_date_gmt > '" . date('Y-m-d H:i:s', time() - $limit_days * 86400) . "'";
         $where .= " ) ";
         $join_relation = true;
         unset($limit_days);
     }
     if (!empty($slug)) {
         $slug = sanitize_title($slug);
         $where .= " AND t.slug = '{$slug}'";
     }
     if (!empty($name__like)) {
         $where .= " AND t.name LIKE '{$name__like}%'";
     }
     if ('' !== $parent) {
         $parent = (int) $parent;
         $where .= " AND tt.parent = '{$parent}'";
     }
     // ST Features : Another way to search
     if (strpos($st_name__like, ' ') !== false) {
         $st_terms_formatted = array();
         $st_terms = preg_split('/[\\s,]+/', $st_name_like);
         foreach ((array) $st_terms as $st_term) {
             if (empty($st_term)) {
                 continue;
             }
             $st_terms_formatted[] = "t.name LIKE '%" . like_escape($st_term) . "%'";
         }
         $where .= " AND ( " . explode(' OR ', $st_terms_formatted) . " ) ";
         unset($st_term, $st_terms_formatted, $st_terms);
     } elseif (!empty($st_name__like)) {
         $where .= " AND t.name LIKE '%{$st_name__like}%'";
     }
     // ST Features : Add min usage
     if ($hide_empty && !$hierarchical) {
         if ($min_usage == 0) {
             $where .= ' AND tt.count > 0';
         } else {
             $where .= $wpdb->prepare(' AND tt.count >= %d', $min_usage);
         }
     }
     // don't limit the query results when we have to descend the family tree
     if (!empty($number) && !$hierarchical && empty($child_of) && '' === $parent) {
         if ($offset) {
             $limit = 'LIMIT ' . $offset . ',' . $number;
         } else {
             $limit = 'LIMIT ' . $number;
         }
     } else {
         $limit = '';
     }
     if (!empty($search)) {
         $search = like_escape($search);
         $where .= " AND (t.name LIKE '%{$search}%')";
     }
     $selects = array();
     switch ($fields) {
         case 'all':
             $selects = array('t.*', 'tt.*');
             break;
         case 'ids':
         case 'id=>parent':
             $selects = array('t.term_id', 'tt.parent', 'tt.count');
             break;
         case 'names':
             $selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name');
             break;
         case 'count':
             $orderby = '';
             $order = '';
             $selects = array('COUNT(*)');
     }
     $select_this = implode(', ', apply_filters('get_terms_fields', $selects, $args));
     // Add inner to relation table ?
     $join_relation = $join_relation == false ? '' : "INNER JOIN {$wpdb->term_relationships} AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id";
     $query = "SELECT {$select_this}\r\n\t\t\tFROM {$wpdb->terms} AS t\r\n\t\t\tINNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id\r\n\t\t\t{$join_relation}\r\n\t\t\tWHERE tt.taxonomy IN ({$in_taxonomies})\r\n\t\t\t{$where}\r\n\t\t\t{$orderby} {$order}\r\n\t\t\t{$limit}";
     // GROUP BY t.term_id
     if ('count' == $fields) {
         $term_count = $wpdb->get_var($query);
         return $term_count;
     }
     $terms = $wpdb->get_results($query);
     if ('all' == $fields) {
         update_term_cache($terms);
     }
     if (empty($terms)) {
         wp_cache_add($cache_key, array(), 's-terms');
         $terms = apply_filters('get_terms', array(), $taxonomies, $args);
         return $terms;
     }
     if ($child_of) {
         $children = _get_term_hierarchy($taxonomies[0]);
         if (!empty($children)) {
             $terms =& _get_term_children($child_of, $terms, $taxonomies[0]);
         }
     }
     // Update term counts to include children.
     if ($pad_counts && 'all' == $fields) {
         _pad_term_counts($terms, $taxonomies[0]);
     }
     // Make sure we show empty categories that have children.
     if ($hierarchical && $hide_empty && is_array($terms)) {
         foreach ($terms as $k => $term) {
             if (!$term->count) {
                 $children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
                 if (is_array($children)) {
                     foreach ($children as $child) {
                         if ($child->count) {
                             continue 2;
                         }
                     }
                 }
                 // It really is empty
                 unset($terms[$k]);
             }
         }
     }
     reset($terms);
     $_terms = array();
     if ('id=>parent' == $fields) {
         while ($term = array_shift($terms)) {
             $_terms[$term->term_id] = $term->parent;
         }
         $terms = $_terms;
     } elseif ('ids' == $fields) {
         while ($term = array_shift($terms)) {
             $_terms[] = $term->term_id;
         }
         $terms = $_terms;
     } elseif ('names' == $fields) {
         while ($term = array_shift($terms)) {
             $_terms[] = $term->name;
         }
         $terms = $_terms;
     }
     if (0 < $number && intval(@count($terms)) > $number) {
         $terms = array_slice($terms, $offset, $number);
     }
     wp_cache_add($cache_key, $terms, 's-terms');
     $terms = apply_filters('get_terms', $terms, $taxonomies, $args);
     return $terms;
 }
コード例 #3
0
/**
 * get_terms() - Retrieve the terms in taxonomy or list of taxonomies.
 *
 * You can fully inject any customizations to the query before it is sent, as well as control
 * the output with a filter.
 *
 * The 'get_terms' filter will be called when the cache has the term and will pass the found
 * term along with the array of $taxonomies and array of $args. This filter is also called
 * before the array of terms is passed and will pass the array of terms, along with the $taxonomies
 * and $args.
 *
 * The 'list_terms_exclusions' filter passes the compiled exclusions along with the $args.
 *
 * The list that $args can contain, which will overwrite the defaults.
 * orderby - Default is 'name'. Can be name, count, or nothing (will use term_id).
 * order - Default is ASC. Can use DESC.
 * hide_empty - Default is true. Will not return empty $terms.
 * fields - Default is all.
 * slug - Any terms that has this value. Default is empty string.
 * hierarchical - Whether to return hierarchical taxonomy. Default is true.
 * name__like - Default is empty string.
 *
 * The argument 'pad_counts' will count all of the children along with the $terms.
 *
 * The 'get' argument allows for overwriting 'hide_empty' and 'child_of', which can be done by
 * setting the value to 'all', instead of its default empty string value.
 *
 * The 'child_of' argument will be used if you use multiple taxonomy or the first $taxonomy
 * isn't hierarchical or 'parent' isn't used. The default is 0, which will be translated to
 * a false value. If 'child_of' is set, then 'child_of' value will be tested against
 * $taxonomy to see if 'child_of' is contained within. Will return an empty array if test
 * fails.
 *
 * If 'parent' is set, then it will be used to test against the first taxonomy. Much like
 * 'child_of'. Will return an empty array if the test fails.
 *
 * @package WordPress
 * @subpackage Taxonomy
 * @since 2.3
 *
 * @uses $wpdb
 * @uses wp_parse_args() Merges the defaults with those defined by $args and allows for strings.
 *
 *
 * @param string|array Taxonomy name or list of Taxonomy names
 * @param string|array $args The values of what to search for when returning terms
 * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist.
 */
function &get_terms($taxonomies, $args = '') {
	global $wpdb;
	$empty_array = array();

	$single_taxonomy = false;
	if ( !is_array($taxonomies) ) {
		$single_taxonomy = true;
		$taxonomies = array($taxonomies);
	}

	foreach ( $taxonomies as $taxonomy ) {
		if ( ! is_taxonomy($taxonomy) )
			return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
	}

	$in_taxonomies = "'" . implode("', '", $taxonomies) . "'";

	$defaults = array('orderby' => 'name', 'order' => 'ASC',
		'hide_empty' => true, 'exclude' => '', 'include' => '',
		'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '',
		'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '',
		'pad_counts' => false, 'offset' => '', 'search' => '');
	$args = wp_parse_args( $args, $defaults );
	$args['number'] = absint( $args['number'] );
	$args['offset'] = absint( $args['offset'] );
	if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) ||
		'' != $args['parent'] ) {
		$args['child_of'] = 0;
		$args['hierarchical'] = false;
		$args['pad_counts'] = false;
	}

	if ( 'all' == $args['get'] ) {
		$args['child_of'] = 0;
		$args['hide_empty'] = 0;
		$args['hierarchical'] = false;
		$args['pad_counts'] = false;
	}
	extract($args, EXTR_SKIP);

	if ( $child_of ) {
		$hierarchy = _get_term_hierarchy($taxonomies[0]);
		if ( !isset($hierarchy[$child_of]) )
			return $empty_array;
	}

	if ( $parent ) {
		$hierarchy = _get_term_hierarchy($taxonomies[0]);
		if ( !isset($hierarchy[$parent]) )
			return $empty_array;
	}

	$key = md5( serialize( $args ) . serialize( $taxonomies ) );
	if ( $cache = wp_cache_get( 'get_terms', 'terms' ) ) {
		if ( isset( $cache[ $key ] ) )
			return apply_filters('get_terms', $cache[$key], $taxonomies, $args);
	}

	if ( 'count' == $orderby )
		$orderby = 'tt.count';
	else if ( 'name' == $orderby )
		$orderby = 't.name';
	else if ( 'slug' == $orderby )
		$orderby = 't.slug';
	else if ( 'term_group' == $orderby )
		$orderby = 't.term_group';
	else
		$orderby = 't.term_id';

	$where = '';
	$inclusions = '';
	if ( !empty($include) ) {
		$exclude = '';
		$interms = preg_split('/[\s,]+/',$include);
		if ( count($interms) ) {
			foreach ( $interms as $interm ) {
				if (empty($inclusions))
					$inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
				else
					$inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
			}
		}
	}

	if ( !empty($inclusions) )
		$inclusions .= ')';
	$where .= $inclusions;

	$exclusions = '';
	if ( !empty($exclude) ) {
		$exterms = preg_split('/[\s,]+/',$exclude);
		if ( count($exterms) ) {
			foreach ( $exterms as $exterm ) {
				if (empty($exclusions))
					$exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
				else
					$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
			}
		}
	}

	if ( !empty($exclusions) )
		$exclusions .= ')';
	$exclusions = apply_filters('list_terms_exclusions', $exclusions, $args );
	$where .= $exclusions;

	if ( !empty($slug) ) {
		$slug = sanitize_title($slug);
		$where .= " AND t.slug = '$slug'";
	}

	if ( !empty($name__like) )
		$where .= " AND t.name LIKE '{$name__like}%'";

	if ( '' != $parent ) {
		$parent = (int) $parent;
		$where .= " AND tt.parent = '$parent'";
	}

	if ( $hide_empty && !$hierarchical )
		$where .= ' AND tt.count > 0';

	if ( !empty($number) ) {
		if( $offset )
			$number = 'LIMIT ' . $offset . ',' . $number;
		else
			$number = 'LIMIT ' . $number;

	} else
		$number = '';

	if ( !empty($search) ) {
		$search = like_escape($search);
		$where .= " AND (t.name LIKE '%$search%')";
	}

	$select_this = '';
	if ( 'all' == $fields )
		$select_this = 't.*, tt.*';
	else if ( 'ids' == $fields )
		$select_this = 't.term_id';
	else if ( 'names' == $fields )
		$select_this = 't.name';

	$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";

	if ( 'all' == $fields ) {
		$terms = $wpdb->get_results($query);
		update_term_cache($terms);
	} else if ( ('ids' == $fields) || ('names' == $fields) ) {
		$terms = $wpdb->get_col($query);
	}

	if ( empty($terms) ) {
		$cache[ $key ] = array();
		wp_cache_set( 'get_terms', $cache, 'terms' );
		return apply_filters('get_terms', array(), $taxonomies, $args);
	}

	if ( $child_of || $hierarchical ) {
		$children = _get_term_hierarchy($taxonomies[0]);
		if ( ! empty($children) )
			$terms = & _get_term_children($child_of, $terms, $taxonomies[0]);
	}

	// Update term counts to include children.
	if ( $pad_counts )
		_pad_term_counts($terms, $taxonomies[0]);

	// Make sure we show empty categories that have children.
	if ( $hierarchical && $hide_empty ) {
		foreach ( $terms as $k => $term ) {
			if ( ! $term->count ) {
				$children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
				foreach ( $children as $child )
					if ( $child->count )
						continue 2;

				// It really is empty
				unset($terms[$k]);
			}
		}
	}
	reset ( $terms );

	$cache[ $key ] = $terms;
	wp_cache_set( 'get_terms', $cache, 'terms' );

	$terms = apply_filters('get_terms', $terms, $taxonomies, $args);
	return $terms;
}
コード例 #4
0
ファイル: taxonomy.php プロジェクト: klr2003/sourceread
/**
 * Retrieve the terms in a given taxonomy or list of taxonomies.
 *
 * You can fully inject any customizations to the query before it is sent, as
 * well as control the output with a filter.
 *
 * The 'get_terms' filter will be called when the cache has the term and will
 * pass the found term along with the array of $taxonomies and array of $args.
 * This filter is also called before the array of terms is passed and will pass
 * the array of terms, along with the $taxonomies and $args.
 *
 * The 'list_terms_exclusions' filter passes the compiled exclusions along with
 * the $args.
 *
 * The 'get_terms_orderby' filter passes the ORDER BY clause for the query
 * along with the $args array.
 * The 'get_terms_fields' filter passes the fields for the SELECT query
 * along with the $args array.
 *
 * The list of arguments that $args can contain, which will overwrite the defaults:
 *
 * orderby - Default is 'name'. Can be name, count, term_group, slug or nothing
 * (will use term_id), Passing a custom value other than these will cause it to
 * order based on the custom value.
 *
 * order - Default is ASC. Can use DESC.
 *
 * hide_empty - Default is true. Will not return empty terms, which means
 * terms whose count is 0 according to the given taxonomy.
 *
 * exclude - Default is an empty string.  A comma- or space-delimited string
 * of term ids to exclude from the return array.  If 'include' is non-empty,
 * 'exclude' is ignored.
 *
 * exclude_tree - A comma- or space-delimited string of term ids to exclude
 * from the return array, along with all of their descendant terms according to
 * the primary taxonomy.  If 'include' is non-empty, 'exclude_tree' is ignored.
 *
 * include - Default is an empty string.  A comma- or space-delimited string
 * of term ids to include in the return array.
 *
 * number - The maximum number of terms to return.  Default is empty.
 *
 * offset - The number by which to offset the terms query.
 *
 * fields - Default is 'all', which returns an array of term objects.
 * If 'fields' is 'ids' or 'names', returns an array of
 * integers or strings, respectively.
 *
 * slug - Returns terms whose "slug" matches this value. Default is empty string.
 *
 * hierarchical - Whether to include terms that have non-empty descendants
 * (even if 'hide_empty' is set to true).
 *
 * search - Returned terms' names will contain the value of 'search',
 * case-insensitive.  Default is an empty string.
 *
 * name__like - Returned terms' names will begin with the value of 'name__like',
 * case-insensitive. Default is empty string.
 *
 * The argument 'pad_counts', if set to true will include the quantity of a term's
 * children in the quantity of each term's "count" object variable.
 *
 * The 'get' argument, if set to 'all' instead of its default empty string,
 * returns terms regardless of ancestry or whether the terms are empty.
 *
 * The 'child_of' argument, when used, should be set to the integer of a term ID.  Its default
 * is 0.  If set to a non-zero value, all returned terms will be descendants
 * of that term according to the given taxonomy.  Hence 'child_of' is set to 0
 * if more than one taxonomy is passed in $taxonomies, because multiple taxonomies
 * make term ancestry ambiguous.
 *
 * The 'parent' argument, when used, should be set to the integer of a term ID.  Its default is
 * the empty string '', which has a different meaning from the integer 0.
 * If set to an integer value, all returned terms will have as an immediate
 * ancestor the term whose ID is specified by that integer according to the given taxonomy.
 * The 'parent' argument is different from 'child_of' in that a term X is considered a 'parent'
 * of term Y only if term X is the father of term Y, not its grandfather or great-grandfather, etc.
 *
 * @package WordPress
 * @subpackage Taxonomy
 * @since 2.3.0
 *
 * @uses $wpdb
 * @uses wp_parse_args() Merges the defaults with those defined by $args and allows for strings.
 *
 * @param string|array Taxonomy name or list of Taxonomy names
 * @param string|array $args The values of what to search for when returning terms
 * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist.
 */
function &get_terms($taxonomies, $args = '')
{
    global $wpdb;
    $empty_array = array();
    $single_taxonomy = false;
    if (!is_array($taxonomies)) {
        $single_taxonomy = true;
        $taxonomies = array($taxonomies);
    }
    foreach ((array) $taxonomies as $taxonomy) {
        if (!is_taxonomy($taxonomy)) {
            $error =& new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
            return $error;
        }
    }
    $in_taxonomies = "'" . implode("', '", $taxonomies) . "'";
    $defaults = array('orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'exclude' => '', 'exclude_tree' => '', 'include' => '', 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'pad_counts' => false, 'offset' => '', 'search' => '');
    $args = wp_parse_args($args, $defaults);
    $args['number'] = absint($args['number']);
    $args['offset'] = absint($args['offset']);
    if (!$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' !== $args['parent']) {
        $args['child_of'] = 0;
        $args['hierarchical'] = false;
        $args['pad_counts'] = false;
    }
    if ('all' == $args['get']) {
        $args['child_of'] = 0;
        $args['hide_empty'] = 0;
        $args['hierarchical'] = false;
        $args['pad_counts'] = false;
    }
    extract($args, EXTR_SKIP);
    if ($child_of) {
        $hierarchy = _get_term_hierarchy($taxonomies[0]);
        if (!isset($hierarchy[$child_of])) {
            return $empty_array;
        }
    }
    if ($parent) {
        $hierarchy = _get_term_hierarchy($taxonomies[0]);
        if (!isset($hierarchy[$parent])) {
            return $empty_array;
        }
    }
    // $args can be whatever, only use the args defined in defaults to compute the key
    $filter_key = has_filter('list_terms_exclusions') ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
    $key = md5(serialize(compact(array_keys($defaults))) . serialize($taxonomies) . $filter_key);
    $last_changed = wp_cache_get('last_changed', 'terms');
    if (!$last_changed) {
        $last_changed = time();
        wp_cache_set('last_changed', $last_changed, 'terms');
    }
    $cache_key = "get_terms:{$key}:{$last_changed}";
    $cache = wp_cache_get($cache_key, 'terms');
    if (false !== $cache) {
        $cache = apply_filters('get_terms', $cache, $taxonomies, $args);
        return $cache;
    }
    $_orderby = strtolower($orderby);
    if ('count' == $_orderby) {
        $orderby = 'tt.count';
    } else {
        if ('name' == $_orderby) {
            $orderby = 't.name';
        } else {
            if ('slug' == $_orderby) {
                $orderby = 't.slug';
            } else {
                if ('term_group' == $_orderby) {
                    $orderby = 't.term_group';
                } elseif (empty($_orderby) || 'id' == $_orderby) {
                    $orderby = 't.term_id';
                }
            }
        }
    }
    $orderby = apply_filters('get_terms_orderby', $orderby, $args);
    $where = '';
    $inclusions = '';
    if (!empty($include)) {
        $exclude = '';
        $exclude_tree = '';
        $interms = preg_split('/[\\s,]+/', $include);
        if (count($interms)) {
            foreach ((array) $interms as $interm) {
                if (empty($inclusions)) {
                    $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
                } else {
                    $inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
                }
            }
        }
    }
    if (!empty($inclusions)) {
        $inclusions .= ')';
    }
    $where .= $inclusions;
    $exclusions = '';
    if (!empty($exclude_tree)) {
        $excluded_trunks = preg_split('/[\\s,]+/', $exclude_tree);
        foreach ((array) $excluded_trunks as $extrunk) {
            $excluded_children = (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids'));
            $excluded_children[] = $extrunk;
            foreach ((array) $excluded_children as $exterm) {
                if (empty($exclusions)) {
                    $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
                } else {
                    $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
                }
            }
        }
    }
    if (!empty($exclude)) {
        $exterms = preg_split('/[\\s,]+/', $exclude);
        if (count($exterms)) {
            foreach ((array) $exterms as $exterm) {
                if (empty($exclusions)) {
                    $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
                } else {
                    $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
                }
            }
        }
    }
    if (!empty($exclusions)) {
        $exclusions .= ')';
    }
    $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args);
    $where .= $exclusions;
    if (!empty($slug)) {
        $slug = sanitize_title($slug);
        $where .= " AND t.slug = '{$slug}'";
    }
    if (!empty($name__like)) {
        $where .= " AND t.name LIKE '{$name__like}%'";
    }
    if ('' !== $parent) {
        $parent = (int) $parent;
        $where .= " AND tt.parent = '{$parent}'";
    }
    if ($hide_empty && !$hierarchical) {
        $where .= ' AND tt.count > 0';
    }
    // don't limit the query results when we have to descend the family tree
    if (!empty($number) && !$hierarchical && empty($child_of) && '' === $parent) {
        if ($offset) {
            $limit = 'LIMIT ' . $offset . ',' . $number;
        } else {
            $limit = 'LIMIT ' . $number;
        }
    } else {
        $limit = '';
    }
    if (!empty($search)) {
        $search = like_escape($search);
        $where .= " AND (t.name LIKE '%{$search}%')";
    }
    $selects = array();
    if ('all' == $fields) {
        $selects = array('t.*', 'tt.*');
    } else {
        if ('ids' == $fields) {
            $selects = array('t.term_id', 'tt.parent', 'tt.count');
        } else {
            if ('names' == $fields) {
                $selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name');
            }
        }
    }
    $select_this = implode(', ', apply_filters('get_terms_fields', $selects, $args));
    $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} {$limit}";
    $terms = $wpdb->get_results($query);
    if ('all' == $fields) {
        update_term_cache($terms);
    }
    if (empty($terms)) {
        wp_cache_add($cache_key, array(), 'terms');
        $terms = apply_filters('get_terms', array(), $taxonomies, $args);
        return $terms;
    }
    if ($child_of) {
        $children = _get_term_hierarchy($taxonomies[0]);
        if (!empty($children)) {
            $terms =& _get_term_children($child_of, $terms, $taxonomies[0]);
        }
    }
    // Update term counts to include children.
    if ($pad_counts && 'all' == $fields) {
        _pad_term_counts($terms, $taxonomies[0]);
    }
    // Make sure we show empty categories that have children.
    if ($hierarchical && $hide_empty && is_array($terms)) {
        foreach ($terms as $k => $term) {
            if (!$term->count) {
                $children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
                if (is_array($children)) {
                    foreach ($children as $child) {
                        if ($child->count) {
                            continue 2;
                        }
                    }
                }
                // It really is empty
                unset($terms[$k]);
            }
        }
    }
    reset($terms);
    $_terms = array();
    if ('ids' == $fields) {
        while ($term = array_shift($terms)) {
            $_terms[] = $term->term_id;
        }
        $terms = $_terms;
    } elseif ('names' == $fields) {
        while ($term = array_shift($terms)) {
            $_terms[] = $term->name;
        }
        $terms = $_terms;
    }
    if (0 < $number && intval(@count($terms)) > $number) {
        $terms = array_slice($terms, $offset, $number);
    }
    wp_cache_add($cache_key, $terms, 'terms');
    $terms = apply_filters('get_terms', $terms, $taxonomies, $args);
    return $terms;
}
コード例 #5
0
	/**
	 * Extended get_terms function support
	 * - Limit category
	 * - Limit days
	 * - Selection restrict
	 * - Min usage
	 *
	 * @param string|array $taxonomies
	 * @param string $args
	 * @return array
	 */
	function getTerms( $taxonomies, $args = '', $skip_cache = false, $internal_st = false ) {
		global $wpdb;
		$empty_array = array();

		$single_taxonomy = false;
		if ( !is_array($taxonomies) ) {
			$single_taxonomy = true;
			$taxonomies = array($taxonomies);
		}

		foreach ( $taxonomies as $taxonomy ) {
			if ( ! is_taxonomy($taxonomy) ) {
				return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
			}
		}

		$in_taxonomies = "'" . implode("', '", $taxonomies) . "'";

		$defaults = array(
			'orderby' => 'name',
			'order' => 'ASC',
			'cloud_selection' => 'count-desc',
			'hide_empty' => true,
			'exclude' => '',
			'include' => '',
			'number' => '',
			'fields' => 'all',
			'slug' => '',
			'parent' => '',
			'hierarchical' => true,
			'child_of' => 0,
			'get' => '',
			'name__like' => '',
			'st_name_like' => '',
			'pad_counts' => false,
			'offset' => '',
			'search' => '',
			'limit_days' => 0,
			'category' => 0,
			'min_usage' => 0
		);

		$args = wp_parse_args( $args, $defaults );
		if ( $internal_st != true ) { // Allow limit :)
			$args['number'] = absint( $args['number'] );
		}
		$args['offset'] = absint( $args['offset'] );
		if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' != $args['parent'] ) {
			$args['child_of'] = 0;
			$args['hierarchical'] = false;
			$args['pad_counts'] = false;
		}

		if ( 'all' == $args['get'] ) {
			$args['child_of'] = 0;
			$args['hide_empty'] = 0;
			$args['hierarchical'] = false;
			$args['pad_counts'] = false;
		}
		extract($args, EXTR_SKIP);

		if ( $child_of ) {
			$hierarchy = _get_term_hierarchy($taxonomies[0]);
			if ( !isset($hierarchy[$child_of]) )
				return $empty_array;
		}

		if ( $parent ) {
			$hierarchy = _get_term_hierarchy($taxonomies[0]);
			if ( !isset($hierarchy[$parent]) )
				return $empty_array;
		}
		
		if ( $skip_cache != true ) {
			// $args can be whatever, only use the args defined in defaults to compute the key
			$filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
			$key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key );
			$last_changed = wp_cache_get('last_changed', 'terms');
			if ( !$last_changed ) {
			    $last_changed = time();
			    wp_cache_set('last_changed', $last_changed, 'terms');
			}
			$cache_key = "get_terms:$key:$last_changed";
			
			if ( $cache = wp_cache_get( $cache_key, 'terms' ) ) {
			    $terms = apply_filters('get_terms', $cache, $taxonomies, $args);
			    return $terms;
			}
		}

		// Restrict category
		$category_sql = '';
		if ( !empty($category) && $category != '0' ) {
			$incategories = preg_split('/[\s,]+/', $category);

			$objects_id = get_objects_in_term( $incategories, 'category' );
			$objects_id = array_unique ($objects_id); // to be sure haven't duplicates

			if ( empty($objects_id) ) { // No posts for this category = no tags for this category
				return array();
			}

			foreach ( (array) $objects_id as $object_id ) {
				$category_sql .= "'". $object_id . "', ";
			}

			$category_sql = substr($category_sql, 0, strlen($category_sql) - 2); // Remove latest ", "
			$category_sql = 'AND p.ID IN ('.$category_sql.')';
		}

		// count-asc/count-desc/name-asc/name-desc/random
		$cloud_selection = strtolower($cloud_selection);
		switch ( $cloud_selection ) {
			case 'count-asc':
				$order_by = 'tt.count ASC';
				break;
			case 'random':
				$order_by = 'RAND()';
				break;
			case 'name-asc':
				$order_by = 't.name ASC';
				break;
			case 'name-desc':
				$order_by = 't.name DESC';
				break;
			default: // count-desc
			$order_by = 'tt.count DESC';
			break;
		}

		// Min usage
		$restict_usage = '';
		$min_usage = (int) $min_usage;
		if ( $min_usage != 0 ) {
			$restict_usage = ' AND tt.count >= '. $min_usage;
		}

		$where = '';
		$inclusions = '';
		if ( !empty($include) ) {
			$exclude = '';
			$interms = preg_split('/[\s,]+/',$include);
			foreach ( (array) $interms as $interm ) {
				if (empty($inclusions)) {
					$inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
				} else {
					$inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
				}
			}
		}

		if ( !empty($inclusions) ) {
			$inclusions .= ')';
		}
		$where .= $inclusions;

		$exclusions = '';
		if ( !empty($exclude) ) {
			$exterms = preg_split('/[\s,]+/',$exclude);
			foreach ( (array) $exterms as $exterm ) {
				if (empty($exclusions)) {
					$exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
				} else {
					$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
				}
			}
		}

		if ( !empty($exclusions) ) {
			$exclusions .= ')';
		}
		$exclusions = apply_filters('list_terms_exclusions', $exclusions, $args );
		$where .= $exclusions;

		if ( !empty($slug) ) {
			$slug = sanitize_title($slug);
			$where .= " AND t.slug = '$slug'";
		}

		if ( !empty($name__like) ) {
			$where .= " AND t.name LIKE '{$name__like}%'";
		}

		if ( strpos($st_name_like, ' ') != false || strpos($st_name_like, ' ') != null ) {
			$tmp = '';
			$sts = explode(' ', $st_name_like);
			foreach ( (array) $sts as $st ) {
				if ( empty($st) )
				continue;

				$st = addslashes_gpc($st);
				$tmp .= " t.name LIKE '%{$st}%' OR ";
			}
			// Remove latest OR
			$tmp = substr( $tmp, 0, strlen($tmp) - 4);

			$where .= " AND ( $tmp ) ";
			unset($tmp)	;
		} elseif ( !empty($st_name_like) ) {
			$where .= " AND t.name LIKE '%{$st_name_like}%'";
		}

		if ( '' != $parent ) {
			$parent = (int) $parent;
			$where .= " AND tt.parent = '$parent'";
		}

		if ( $hide_empty && !$hierarchical ) {
			$where .= ' AND tt.count > 0';
		}

		$number_sql = '';
		if ( strpos($number, ',') != false || strpos($number, ',') != null ) {
			$number_sql = $number;
		} else {
			$number = (int) $number;
			if ( $number != 0 ) {
				$number_sql = 'LIMIT ' . $number;
			}
		}

		if ( !empty($search) ) {
			$search = like_escape($search);
			$where .= " AND (t.name LIKE '%$search%')";
		}

		$select_this = '';

		if ( 'all' == $fields ) {
			$select_this = 't.*, tt.*';
		} else if ( 'ids' == $fields ) {
 	        $select_this = 't.term_id, tt.parent, tt.count';
		} else if ( 'names' == $fields ) {
			$select_this = 't.term_id, tt.parent, tt.count, t.name';
		}

		// Limit posts date
		$limitdays_sql = '';
		$limit_days = (int) $limit_days;
		if ( $limit_days != 0 ) {
			$limitdays_sql = 'AND p.post_date_gmt > "' .date( 'Y-m-d H:i:s', time() - $limit_days * 86400 ). '"';
		}

		$query = "SELECT {$select_this}
			FROM {$wpdb->terms} AS t
			INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
			INNER JOIN {$wpdb->term_relationships} AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
			INNER JOIN {$wpdb->posts} AS p ON tr.object_id = p.ID
			WHERE tt.taxonomy IN ( {$in_taxonomies} )
			AND p.post_date_gmt < '".current_time('mysql')."'
			{$limitdays_sql}
			{$category_sql}
			{$where}
			{$restict_usage}
			GROUP BY t.term_id
			ORDER BY {$order_by}
			{$number_sql}";
		
		if ( 'all' == $fields ) {
			$terms = $wpdb->get_results($query);
			if ( $skip_cache != true ) {
				update_term_cache($terms);
			}
		} else if ( ('ids' == $fields) || ('names' == $fields) ) {
			$terms = $wpdb->get_results($query);
		}

		if ( empty($terms) ) {
			$cache[ $key ] = array();
			wp_cache_set( 'get_terms', $cache, 'terms' );
			$terms = apply_filters('get_terms', array(), $taxonomies, $args);
			return $terms;
		}

		if ( $child_of ) {
		    $children = _get_term_hierarchy($taxonomies[0]);
		    if ( ! empty($children) )
		        $terms = & _get_term_children($child_of, $terms, $taxonomies[0]);
		}

		// Update term counts to include children.
 	    if ( $pad_counts && 'all' == $fields )
	        _pad_term_counts($terms, $taxonomies[0]);

		// Make sure we show empty categories that have children.
		if ( $hierarchical && $hide_empty && is_array($terms) ) {
		    foreach ( $terms as $k => $term ) {
		        if ( ! $term->count ) {
		            $children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
		            if( is_array($children) )
		                foreach ( $children as $child )
		                    if ( $child->count )
		                        continue 2;
		
		            // It really is empty
		            unset($terms[$k]);
		        }
		    }
		}
		reset ( $terms );
		
		$_terms = array();
		if ( 'ids' == $fields ) {
		    while ( $term = array_shift($terms) )
		        $_terms[] = $term->term_id;
		    $terms = $_terms;
		} elseif ( 'names' == $fields ) {
		    while ( $term = array_shift($terms) )
		        $_terms[] = $term->name;
		    $terms = $_terms;
		}
		
		if ( $skip_cache != true ) {
			wp_cache_add( $cache_key, $terms, 'terms' );
		}

		$terms = apply_filters('get_terms', $terms, $taxonomies, $args);
		return $terms;
	}
コード例 #6
0
ファイル: TAXONOMY.PHP プロジェクト: pauEscarcia/AIMM
/**
 * Retrieve the terms in a given taxonomy or list of taxonomies.
 *
 * You can fully inject any customizations to the query before it is sent, as
 * well as control the output with a filter.
 *
 * The 'get_terms' filter will be called when the cache has the term and will
 * pass the found term along with the array of $taxonomies and array of $args.
 * This filter is also called before the array of terms is passed and will pass
 * the array of terms, along with the $taxonomies and $args.
 *
 * The 'list_terms_exclusions' filter passes the compiled exclusions along with
 * the $args.
 *
 * The 'get_terms_orderby' filter passes the ORDER BY clause for the query
 * along with the $args array.
 *
 * The 'get_terms_fields' filter passes the fields for the SELECT query
 * along with the $args array.
 *
 * The list of arguments that $args can contain, which will overwrite the defaults:
 *
 * orderby - Default is 'name'. Can be name, count, term_group, slug or nothing
 * (will use term_id), Passing a custom value other than these will cause it to
 * order based on the custom value.
 *
 * order - Default is ASC. Can use DESC.
 *
 * hide_empty - Default is true. Will not return empty terms, which means
 * terms whose count is 0 according to the given taxonomy.
 *
 * exclude - Default is an empty array. An array, comma- or space-delimited string
 * of term ids to exclude from the return array. If 'include' is non-empty,
 * 'exclude' is ignored.
 *
 * exclude_tree - Default is an empty array. An array, comma- or space-delimited
 * string of term ids to exclude from the return array, along with all of their
 * descendant terms according to the primary taxonomy. If 'include' is non-empty,
 * 'exclude_tree' is ignored.
 *
 * include - Default is an empty array. An array, comma- or space-delimited string
 * of term ids to include in the return array.
 *
 * number - The maximum number of terms to return. Default is to return them all.
 *
 * offset - The number by which to offset the terms query.
 *
 * fields - Default is 'all', which returns an array of term objects.
 * If 'fields' is 'ids' or 'names', returns an array of
 * integers or strings, respectively.
 *
 * slug - Returns terms whose "slug" matches this value. Default is empty string.
 *
 * hierarchical - Whether to include terms that have non-empty descendants
 * (even if 'hide_empty' is set to true).
 *
 * search - Returned terms' names will contain the value of 'search',
 * case-insensitive. Default is an empty string.
 *
 * name__like - Returned terms' names will begin with the value of 'name__like',
 * case-insensitive. Default is empty string.
 *
 * The argument 'pad_counts', if set to true will include the quantity of a term's
 * children in the quantity of each term's "count" object variable.
 *
 * The 'get' argument, if set to 'all' instead of its default empty string,
 * returns terms regardless of ancestry or whether the terms are empty.
 *
 * The 'child_of' argument, when used, should be set to the integer of a term ID. Its default
 * is 0. If set to a non-zero value, all returned terms will be descendants
 * of that term according to the given taxonomy. Hence 'child_of' is set to 0
 * if more than one taxonomy is passed in $taxonomies, because multiple taxonomies
 * make term ancestry ambiguous.
 *
 * The 'parent' argument, when used, should be set to the integer of a term ID. Its default is
 * the empty string '', which has a different meaning from the integer 0.
 * If set to an integer value, all returned terms will have as an immediate
 * ancestor the term whose ID is specified by that integer according to the given taxonomy.
 * The 'parent' argument is different from 'child_of' in that a term X is considered a 'parent'
 * of term Y only if term X is the father of term Y, not its grandfather or great-grandfather, etc.
 *
 * The 'cache_domain' argument enables a unique cache key to be produced when this query is stored
 * in object cache. For instance, if you are using one of this function's filters to modify the
 * query (such as 'terms_clauses'), setting 'cache_domain' to a unique value will not overwrite
 * the cache for similar queries. Default value is 'core'.
 *
 * @package WordPress
 * @subpackage Taxonomy
 * @since 2.3.0
 *
 * @uses $wpdb
 * @uses wp_parse_args() Merges the defaults with those defined by $args and allows for strings.
 *
 * @param string|array $taxonomies Taxonomy name or list of Taxonomy names
 * @param string|array $args The values of what to search for when returning terms
 * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist.
 */
function get_terms($taxonomies, $args = '') {
	global $wpdb;
	$empty_array = array();

	$single_taxonomy = ! is_array( $taxonomies ) || 1 === count( $taxonomies );
	if ( ! is_array( $taxonomies ) )
		$taxonomies = array( $taxonomies );

	foreach ( $taxonomies as $taxonomy ) {
		if ( ! taxonomy_exists($taxonomy) ) {
			$error = new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
			return $error;
		}
	}

	$defaults = array('orderby' => 'name', 'order' => 'ASC',
		'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(),
		'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '',
		'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '',
		'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core' );
	$args = wp_parse_args( $args, $defaults );
	$args['number'] = absint( $args['number'] );
	$args['offset'] = absint( $args['offset'] );
	if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) ||
		'' !== $args['parent'] ) {
		$args['child_of'] = 0;
		$args['hierarchical'] = false;
		$args['pad_counts'] = false;
	}

	if ( 'all' == $args['get'] ) {
		$args['child_of'] = 0;
		$args['hide_empty'] = 0;
		$args['hierarchical'] = false;
		$args['pad_counts'] = false;
	}

	$args = apply_filters( 'get_terms_args', $args, $taxonomies );

	extract($args, EXTR_SKIP);

	if ( $child_of ) {
		$hierarchy = _get_term_hierarchy($taxonomies[0]);
		if ( !isset($hierarchy[$child_of]) )
			return $empty_array;
	}

	if ( $parent ) {
		$hierarchy = _get_term_hierarchy($taxonomies[0]);
		if ( !isset($hierarchy[$parent]) )
			return $empty_array;
	}

	// $args can be whatever, only use the args defined in defaults to compute the key
	$filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
	$key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key );
	$last_changed = wp_cache_get('last_changed', 'terms');
	if ( !$last_changed ) {
		$last_changed = time();
		wp_cache_set('last_changed', $last_changed, 'terms');
	}
	$cache_key = "get_terms:$key:$last_changed";
	$cache = wp_cache_get( $cache_key, 'terms' );
	if ( false !== $cache ) {
		$cache = apply_filters('get_terms', $cache, $taxonomies, $args);
		return $cache;
	}

	$_orderby = strtolower($orderby);
	if ( 'count' == $_orderby )
		$orderby = 'tt.count';
	else if ( 'name' == $_orderby )
		$orderby = 't.name';
	else if ( 'slug' == $_orderby )
		$orderby = 't.slug';
	else if ( 'term_group' == $_orderby )
		$orderby = 't.term_group';
	else if ( 'none' == $_orderby )
		$orderby = '';
	elseif ( empty($_orderby) || 'id' == $_orderby )
		$orderby = 't.term_id';
	else
		$orderby = 't.name';

	$orderby = apply_filters( 'get_terms_orderby', $orderby, $args );

	if ( !empty($orderby) )
		$orderby = "ORDER BY $orderby";
	else
		$order = '';

	$order = strtoupper( $order );
	if ( '' !== $order && !in_array( $order, array( 'ASC', 'DESC' ) ) )
		$order = 'ASC';

	$where = "tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')";
	$inclusions = '';
	if ( !empty($include) ) {
		$exclude = '';
		$exclude_tree = '';
		$interms = wp_parse_id_list($include);
		foreach ( $interms as $interm ) {
			if ( empty($inclusions) )
				$inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
			else
				$inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
		}
	}

	if ( !empty($inclusions) )
		$inclusions .= ')';
	$where .= $inclusions;

	$exclusions = '';
	if ( !empty( $exclude_tree ) ) {
		$excluded_trunks = wp_parse_id_list($exclude_tree);
		foreach ( $excluded_trunks as $extrunk ) {
			$excluded_children = (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids', 'hide_empty' => 0));
			$excluded_children[] = $extrunk;
			foreach( $excluded_children as $exterm ) {
				if ( empty($exclusions) )
					$exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
				else
					$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
			}
		}
	}

	if ( !empty($exclude) ) {
		$exterms = wp_parse_id_list($exclude);
		foreach ( $exterms as $exterm ) {
			if ( empty($exclusions) )
				$exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
			else
				$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
		}
	}

	if ( !empty($exclusions) )
		$exclusions .= ')';
	$exclusions = apply_filters('list_terms_exclusions', $exclusions, $args );
	$where .= $exclusions;

	if ( !empty($slug) ) {
		$slug = sanitize_title($slug);
		$where .= " AND t.slug = '$slug'";
	}

	if ( !empty($name__like) ) {
		$name__like = like_escape( $name__like );
		$where .= $wpdb->prepare( " AND t.name LIKE %s", $name__like . '%' );
	}

	if ( '' !== $parent ) {
		$parent = (int) $parent;
		$where .= " AND tt.parent = '$parent'";
	}

	if ( $hide_empty && !$hierarchical )
		$where .= ' AND tt.count > 0';

	// don't limit the query results when we have to descend the family tree
	if ( ! empty($number) && ! $hierarchical && empty( $child_of ) && '' === $parent ) {
		if ( $offset )
			$limits = 'LIMIT ' . $offset . ',' . $number;
		else
			$limits = 'LIMIT ' . $number;
	} else {
		$limits = '';
	}

	if ( !empty($search) ) {
		$search = like_escape($search);
		$where .= $wpdb->prepare( " AND (t.name LIKE %s)", '%' . $search . '%');
	}

	$selects = array();
	switch ( $fields ) {
		case 'all':
			$selects = array('t.*', 'tt.*');
			break;
		case 'ids':
		case 'id=>parent':
			$selects = array('t.term_id', 'tt.parent', 'tt.count');
			break;
		case 'names':
			$selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name');
			break;
		case 'count':
			$orderby = '';
			$order = '';
			$selects = array('COUNT(*)');
	}

	$_fields = $fields;

	$fields = implode(', ', apply_filters( 'get_terms_fields', $selects, $args ));

	$join = "INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";

	$pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits' );
	$clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args );
	foreach ( $pieces as $piece )
		$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';

	$query = "SELECT $fields FROM $wpdb->terms AS t $join WHERE $where $orderby $order $limits";

	$fields = $_fields;

	if ( 'count' == $fields ) {
		$term_count = $wpdb->get_var($query);
		return $term_count;
	}

	$terms = $wpdb->get_results($query);
	if ( 'all' == $fields ) {
		update_term_cache($terms);
	}

	if ( empty($terms) ) {
		wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS );
		$terms = apply_filters('get_terms', array(), $taxonomies, $args);
		return $terms;
	}

	if ( $child_of ) {
		$children = _get_term_hierarchy($taxonomies[0]);
		if ( ! empty($children) )
			$terms = _get_term_children($child_of, $terms, $taxonomies[0]);
	}

	// Update term counts to include children.
	if ( $pad_counts && 'all' == $fields )
		_pad_term_counts($terms, $taxonomies[0]);

	// Make sure we show empty categories that have children.
	if ( $hierarchical && $hide_empty && is_array($terms) ) {
		foreach ( $terms as $k => $term ) {
			if ( ! $term->count ) {
				$children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
				if ( is_array($children) )
					foreach ( $children as $child )
						if ( $child->count )
							continue 2;

				// It really is empty
				unset($terms[$k]);
			}
		}
	}
	reset ( $terms );

	$_terms = array();
	if ( 'id=>parent' == $fields ) {
		while ( $term = array_shift($terms) )
			$_terms[$term->term_id] = $term->parent;
		$terms = $_terms;
	} elseif ( 'ids' == $fields ) {
		while ( $term = array_shift($terms) )
			$_terms[] = $term->term_id;
		$terms = $_terms;
	} elseif ( 'names' == $fields ) {
		while ( $term = array_shift($terms) )
			$_terms[] = $term->name;
		$terms = $_terms;
	}

	if ( 0 < $number && intval(@count($terms)) > $number ) {
		$terms = array_slice($terms, $offset, $number);
	}

	wp_cache_add( $cache_key, $terms, 'terms', DAY_IN_SECONDS );

	$terms = apply_filters('get_terms', $terms, $taxonomies, $args);
	return $terms;
}
コード例 #7
0
 /**
  * Get terms, based on query_vars.
  *
  * @param 4.6.0
  * @access public
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
  * @return array
  */
 public function get_terms()
 {
     global $wpdb;
     $this->parse_query($this->query_vars);
     $args = $this->query_vars;
     // Set up meta_query so it's available to 'pre_get_terms'.
     $this->meta_query = new WP_Meta_Query();
     $this->meta_query->parse_query_vars($args);
     /**
      * Fires before terms are retrieved.
      *
      * @since 4.6.0
      *
      * @param WP_Term_Query $this Current instance of WP_Term_Query.
      */
     do_action('pre_get_terms', $this);
     $taxonomies = $args['taxonomy'];
     // Save queries by not crawling the tree in the case of multiple taxes or a flat tax.
     $has_hierarchical_tax = false;
     if ($taxonomies) {
         foreach ($taxonomies as $_tax) {
             if (is_taxonomy_hierarchical($_tax)) {
                 $has_hierarchical_tax = true;
             }
         }
     }
     if (!$has_hierarchical_tax) {
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     // 'parent' overrides 'child_of'.
     if (0 < intval($args['parent'])) {
         $args['child_of'] = false;
     }
     if ('all' == $args['get']) {
         $args['childless'] = false;
         $args['child_of'] = 0;
         $args['hide_empty'] = 0;
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     /**
      * Filters the terms query arguments.
      *
      * @since 3.1.0
      *
      * @param array $args       An array of get_terms() arguments.
      * @param array $taxonomies An array of taxonomies.
      */
     $args = apply_filters('get_terms_args', $args, $taxonomies);
     // Avoid the query if the queried parent/child_of term has no descendants.
     $child_of = $args['child_of'];
     $parent = $args['parent'];
     if ($child_of) {
         $_parent = $child_of;
     } elseif ($parent) {
         $_parent = $parent;
     } else {
         $_parent = false;
     }
     if ($_parent) {
         $in_hierarchy = false;
         foreach ($taxonomies as $_tax) {
             $hierarchy = _get_term_hierarchy($_tax);
             if (isset($hierarchy[$_parent])) {
                 $in_hierarchy = true;
             }
         }
         if (!$in_hierarchy) {
             return array();
         }
     }
     $orderby = $this->parse_orderby($this->query_vars['orderby']);
     $order = $this->parse_order($this->query_vars['order']);
     if ($taxonomies) {
         $this->sql_clauses['where']['taxonomy'] = "tt.taxonomy IN ('" . implode("', '", array_map('esc_sql', $taxonomies)) . "')";
     }
     $exclude = $args['exclude'];
     $exclude_tree = $args['exclude_tree'];
     $include = $args['include'];
     $inclusions = '';
     if (!empty($include)) {
         $exclude = '';
         $exclude_tree = '';
         $inclusions = implode(',', wp_parse_id_list($include));
     }
     if (!empty($inclusions)) {
         $this->sql_clauses['where']['inclusions'] = 't.term_id IN ( ' . $inclusions . ' )';
     }
     $exclusions = array();
     if (!empty($exclude_tree)) {
         $exclude_tree = wp_parse_id_list($exclude_tree);
         $excluded_children = $exclude_tree;
         foreach ($exclude_tree as $extrunk) {
             $excluded_children = array_merge($excluded_children, (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids', 'hide_empty' => 0)));
         }
         $exclusions = array_merge($excluded_children, $exclusions);
     }
     if (!empty($exclude)) {
         $exclusions = array_merge(wp_parse_id_list($exclude), $exclusions);
     }
     // 'childless' terms are those without an entry in the flattened term hierarchy.
     $childless = (bool) $args['childless'];
     if ($childless) {
         foreach ($taxonomies as $_tax) {
             $term_hierarchy = _get_term_hierarchy($_tax);
             $exclusions = array_merge(array_keys($term_hierarchy), $exclusions);
         }
     }
     if (!empty($exclusions)) {
         $exclusions = 't.term_id NOT IN (' . implode(',', array_map('intval', $exclusions)) . ')';
     } else {
         $exclusions = '';
     }
     /**
      * Filters the terms to exclude from the terms query.
      *
      * @since 2.3.0
      *
      * @param string $exclusions `NOT IN` clause of the terms query.
      * @param array  $args       An array of terms query arguments.
      * @param array  $taxonomies An array of taxonomies.
      */
     $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args, $taxonomies);
     if (!empty($exclusions)) {
         // Must do string manipulation here for backward compatibility with filter.
         $this->sql_clauses['where']['exclusions'] = preg_replace('/^\\s*AND\\s*/', '', $exclusions);
     }
     if (!empty($args['name'])) {
         $names = (array) $args['name'];
         foreach ($names as &$_name) {
             // `sanitize_term_field()` returns slashed data.
             $_name = stripslashes(sanitize_term_field('name', $_name, 0, reset($taxonomies), 'db'));
         }
         $this->sql_clauses['where']['name'] = "t.name IN ('" . implode("', '", array_map('esc_sql', $names)) . "')";
     }
     if (!empty($args['slug'])) {
         if (is_array($args['slug'])) {
             $slug = array_map('sanitize_title', $args['slug']);
             $this->sql_clauses['where']['slug'] = "t.slug IN ('" . implode("', '", $slug) . "')";
         } else {
             $slug = sanitize_title($args['slug']);
             $this->sql_clauses['where']['slug'] = "t.slug = '{$slug}'";
         }
     }
     if (!empty($args['term_taxonomy_id'])) {
         if (is_array($args['term_taxonomy_id'])) {
             $tt_ids = implode(',', array_map('intval', $args['term_taxonomy_id']));
             $this->sql_clauses['where']['term_taxonomy_id'] = "tt.term_taxonomy_id IN ({$tt_ids})";
         } else {
             $this->sql_clauses['where']['term_taxonomy_id'] = $wpdb->prepare("tt.term_taxonomy_id = %d", $args['term_taxonomy_id']);
         }
     }
     if (!empty($args['name__like'])) {
         $this->sql_clauses['where']['name__like'] = $wpdb->prepare("t.name LIKE %s", '%' . $wpdb->esc_like($args['name__like']) . '%');
     }
     if (!empty($args['description__like'])) {
         $this->sql_clauses['where']['description__like'] = $wpdb->prepare("tt.description LIKE %s", '%' . $wpdb->esc_like($args['description__like']) . '%');
     }
     if ('' !== $parent) {
         $parent = (int) $parent;
         $this->sql_clauses['where']['parent'] = "tt.parent = '{$parent}'";
     }
     $hierarchical = $args['hierarchical'];
     if ('count' == $args['fields']) {
         $hierarchical = false;
     }
     if ($args['hide_empty'] && !$hierarchical) {
         $this->sql_clauses['where']['count'] = 'tt.count > 0';
     }
     $number = $args['number'];
     $offset = $args['offset'];
     // Don't limit the query results when we have to descend the family tree.
     if ($number && !$hierarchical && !$child_of && '' === $parent) {
         if ($offset) {
             $limits = 'LIMIT ' . $offset . ',' . $number;
         } else {
             $limits = 'LIMIT ' . $number;
         }
     } else {
         $limits = '';
     }
     if (!empty($args['search'])) {
         $this->sql_clauses['where']['search'] = $this->get_search_sql($args['search']);
     }
     // Meta query support.
     $join = '';
     $distinct = '';
     // Reparse meta_query query_vars, in case they were modified in a 'pre_get_terms' callback.
     $this->meta_query->parse_query_vars($this->query_vars);
     $mq_sql = $this->meta_query->get_sql('term', 't', 'term_id');
     $meta_clauses = $this->meta_query->get_clauses();
     if (!empty($meta_clauses)) {
         $join .= $mq_sql['join'];
         $this->sql_clauses['where']['meta_query'] = preg_replace('/^\\s*AND\\s*/', '', $mq_sql['where']);
         $distinct .= "DISTINCT";
     }
     $selects = array();
     switch ($args['fields']) {
         case 'all':
             $selects = array('t.*', 'tt.*');
             break;
         case 'ids':
         case 'id=>parent':
             $selects = array('t.term_id', 'tt.parent', 'tt.count', 'tt.taxonomy');
             break;
         case 'names':
             $selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name', 'tt.taxonomy');
             break;
         case 'count':
             $orderby = '';
             $order = '';
             $selects = array('COUNT(*)');
             break;
         case 'id=>name':
             $selects = array('t.term_id', 't.name', 'tt.count', 'tt.taxonomy');
             break;
         case 'id=>slug':
             $selects = array('t.term_id', 't.slug', 'tt.count', 'tt.taxonomy');
             break;
     }
     $_fields = $args['fields'];
     /**
      * Filters the fields to select in the terms query.
      *
      * Field lists modified using this filter will only modify the term fields returned
      * by the function when the `$fields` parameter set to 'count' or 'all'. In all other
      * cases, the term fields in the results array will be determined by the `$fields`
      * parameter alone.
      *
      * Use of this filter can result in unpredictable behavior, and is not recommended.
      *
      * @since 2.8.0
      *
      * @param array $selects    An array of fields to select for the terms query.
      * @param array $args       An array of term query arguments.
      * @param array $taxonomies An array of taxonomies.
      */
     $fields = implode(', ', apply_filters('get_terms_fields', $selects, $args, $taxonomies));
     $join .= " INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id";
     $where = implode(' AND ', $this->sql_clauses['where']);
     $pieces = array('fields', 'join', 'where', 'distinct', 'orderby', 'order', 'limits');
     /**
      * Filters the terms query SQL clauses.
      *
      * @since 3.1.0
      *
      * @param array $pieces     Terms query SQL clauses.
      * @param array $taxonomies An array of taxonomies.
      * @param array $args       An array of terms query arguments.
      */
     $clauses = apply_filters('terms_clauses', compact($pieces), $taxonomies, $args);
     $fields = isset($clauses['fields']) ? $clauses['fields'] : '';
     $join = isset($clauses['join']) ? $clauses['join'] : '';
     $where = isset($clauses['where']) ? $clauses['where'] : '';
     $distinct = isset($clauses['distinct']) ? $clauses['distinct'] : '';
     $orderby = isset($clauses['orderby']) ? $clauses['orderby'] : '';
     $order = isset($clauses['order']) ? $clauses['order'] : '';
     $limits = isset($clauses['limits']) ? $clauses['limits'] : '';
     if ($where) {
         $where = "WHERE {$where}";
     }
     $this->sql_clauses['select'] = "SELECT {$distinct} {$fields}";
     $this->sql_clauses['from'] = "FROM {$wpdb->terms} AS t {$join}";
     $this->sql_clauses['orderby'] = $orderby ? "ORDER BY {$orderby} {$order}" : '';
     $this->sql_clauses['limits'] = $limits;
     $this->request = "{$this->sql_clauses['select']} {$this->sql_clauses['from']} {$where} {$this->sql_clauses['orderby']} {$this->sql_clauses['limits']}";
     // $args can be anything. Only use the args defined in defaults to compute the key.
     $key = md5(serialize(wp_array_slice_assoc($args, array_keys($this->query_var_defaults))) . serialize($taxonomies) . $this->request);
     $last_changed = wp_cache_get('last_changed', 'terms');
     if (!$last_changed) {
         $last_changed = microtime();
         wp_cache_set('last_changed', $last_changed, 'terms');
     }
     $cache_key = "get_terms:{$key}:{$last_changed}";
     $cache = wp_cache_get($cache_key, 'terms');
     if (false !== $cache) {
         if ('all' === $_fields) {
             $cache = array_map('get_term', $cache);
         }
         return $cache;
     }
     if ('count' == $_fields) {
         return $wpdb->get_var($this->request);
     }
     $terms = $wpdb->get_results($this->request);
     if ('all' == $_fields) {
         update_term_cache($terms);
     }
     // Prime termmeta cache.
     if ($args['update_term_meta_cache']) {
         $term_ids = wp_list_pluck($terms, 'term_id');
         update_termmeta_cache($term_ids);
     }
     if (empty($terms)) {
         wp_cache_add($cache_key, array(), 'terms', DAY_IN_SECONDS);
         return array();
     }
     if ($child_of) {
         foreach ($taxonomies as $_tax) {
             $children = _get_term_hierarchy($_tax);
             if (!empty($children)) {
                 $terms = _get_term_children($child_of, $terms, $_tax);
             }
         }
     }
     // Update term counts to include children.
     if ($args['pad_counts'] && 'all' == $_fields) {
         foreach ($taxonomies as $_tax) {
             _pad_term_counts($terms, $_tax);
         }
     }
     // Make sure we show empty categories that have children.
     if ($hierarchical && $args['hide_empty'] && is_array($terms)) {
         foreach ($terms as $k => $term) {
             if (!$term->count) {
                 $children = get_term_children($term->term_id, $term->taxonomy);
                 if (is_array($children)) {
                     foreach ($children as $child_id) {
                         $child = get_term($child_id, $term->taxonomy);
                         if ($child->count) {
                             continue 2;
                         }
                     }
                 }
                 // It really is empty.
                 unset($terms[$k]);
             }
         }
     }
     $_terms = array();
     if ('id=>parent' == $_fields) {
         foreach ($terms as $term) {
             $_terms[$term->term_id] = $term->parent;
         }
     } elseif ('ids' == $_fields) {
         foreach ($terms as $term) {
             $_terms[] = $term->term_id;
         }
     } elseif ('names' == $_fields) {
         foreach ($terms as $term) {
             $_terms[] = $term->name;
         }
     } elseif ('id=>name' == $_fields) {
         foreach ($terms as $term) {
             $_terms[$term->term_id] = $term->name;
         }
     } elseif ('id=>slug' == $_fields) {
         foreach ($terms as $term) {
             $_terms[$term->term_id] = $term->slug;
         }
     }
     if (!empty($_terms)) {
         $terms = $_terms;
     }
     // Hierarchical queries are not limited, so 'offset' and 'number' must be handled now.
     if ($hierarchical && $number && is_array($terms)) {
         if ($offset >= count($terms)) {
             $terms = array();
         } else {
             $terms = array_slice($terms, $offset, $number, true);
         }
     }
     wp_cache_add($cache_key, $terms, 'terms', DAY_IN_SECONDS);
     if ('all' === $_fields) {
         $terms = array_map('get_term', $terms);
     }
     $this->terms = $terms;
     return $this->terms;
 }
コード例 #8
0
/**
 * Retrieve the terms in a given taxonomy or list of taxonomies.
 *
 * You can fully inject any customizations to the query before it is sent, as
 * well as control the output with a filter.
 *
 * The 'get_terms' filter will be called when the cache has the term and will
 * pass the found term along with the array of $taxonomies and array of $args.
 * This filter is also called before the array of terms is passed and will pass
 * the array of terms, along with the $taxonomies and $args.
 *
 * The 'list_terms_exclusions' filter passes the compiled exclusions along with
 * the $args.
 *
 * The 'get_terms_orderby' filter passes the ORDER BY clause for the query
 * along with the $args array.
 *
 * The 'get_terms_fields' filter passes the fields for the SELECT query
 * along with the $args array.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string|array $taxonomies Taxonomy name or list of Taxonomy names.
 * @param array|string $args {
 *     Optional. Array or string of arguments to get terms.
 *
 *     @type string   $orderby               Field(s) to order terms by. Accepts term fields ('name', 'slug',
 *                                           'term_group', 'term_id', 'id'), 'count' for term taxonomy count,
 *                                           'include' to match the 'order' of the $include param, or 'none'
 *                                           to skip ORDER BY. Defaults to 'name'.
 *     @type string   $order                 Whether to order terms in ascending or descending order.
 *                                           Accepts 'ASC' (ascending) or 'DESC' (descending).
 *                                           Default 'ASC'.
 *     @type bool|int     $hide_empty        Whether to hide terms not assigned to any posts. Accepts
 *                                           1|true or 0|false. Default 1|true.
 *     @type array|string $include           Array or comma/space-separated string of term ids to include.
 *                                           Default empty array.
 *     @type array|string $exclude           Array or comma/space-separated string of term ids to exclude.
 *                                           If $include is non-empty, $exclude is ignored.
 *                                           Default empty array.
 *     @type array|string $exclude_tree      Array or comma/space-separated string of term ids to exclude
 *                                           along with all of their descendant terms. If $include is
 *                                           non-empty, $exclude_tree is ignored. Default empty array.
 *     @type int          $number            Maximum number of terms to return. Accepts 1+ or -1 (all).
 *                                           Default -1.
 *     @type int          $offset            The number by which to offset the terms query. Default empty.
 *     @type string       $fields            Term fields to query for. Accepts 'all' (returns an array of
 *                                           term objects), 'ids' or 'names' (returns an array of integers
 *                                           or strings, respectively. Default 'all'.
 *     @type string|array $slug              Optional. Slug or array of slugs to return term(s) for. Default empty.
 *     @type bool         $hierarchical      Whether to include terms that have non-empty descendants (even
 *                                           if $hide_empty is set to true). Default true.
 *     @type string       $search            Search criteria to match terms. Will be SQL-formatted with
 *                                           wildcards before and after. Default empty.
 *     @type string       $name__like        Retrieve terms with criteria by which a term is LIKE $name__like.
 *                                           Default empty.
 *     @type string       $description__like Retrieve terms where the description is LIKE $description__like.
 *                                           Default empty.
 *     @type bool         $pad_counts        Whether to pad the quantity of a term's children in the quantity
 *                                           of each term's "count" object variable. Default false.
 *     @type string       $get               Whether to return terms regardless of ancestry or whether the terms
 *                                           are empty. Accepts 'all' or empty (disabled). Default empty.
 *     @type int          $child_of          Term ID to retrieve child terms of. If multiple taxonomies
 *                                           are passed, $child_of is ignored. Default 0.
 *     @type int|string   $parent            Parent term ID to retrieve direct-child terms of. Default empty.
 *     @type string       $cache_domain      Unique cache key to be produced when this query is stored in an
 *                                           object cache. Default is 'core'.
 * }
 * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies
 *                        do not exist.
 */
function get_terms( $taxonomies, $args = '' ) {
	global $wpdb;
	$empty_array = array();

	$single_taxonomy = ! is_array( $taxonomies ) || 1 === count( $taxonomies );
	if ( ! is_array( $taxonomies ) ) {
		$taxonomies = array( $taxonomies );
	}

	foreach ( $taxonomies as $taxonomy ) {
		if ( ! taxonomy_exists($taxonomy) ) {
			$error = new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
			return $error;
		}
	}

	$defaults = array('orderby' => 'name', 'order' => 'ASC',
		'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(),
		'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '',
		'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'description__like' => '',
		'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core' );
	$args = wp_parse_args( $args, $defaults );
	$args['number'] = absint( $args['number'] );
	$args['offset'] = absint( $args['offset'] );

	// Save queries by not crawling the tree in the case of multiple taxes or a flat tax.
	if ( ! $single_taxonomy || ! is_taxonomy_hierarchical( reset( $taxonomies ) ) ) {
		$args['hierarchical'] = false;
		$args['pad_counts'] = false;
	}

	// 'parent' overrides 'child_of'.
	if ( 0 < intval( $args['parent'] ) ) {
		$args['child_of'] = false;
	}

	if ( 'all' == $args['get'] ) {
		$args['child_of'] = 0;
		$args['hide_empty'] = 0;
		$args['hierarchical'] = false;
		$args['pad_counts'] = false;
	}

	/**
	 * Filter the terms query arguments.
	 *
	 * @since 3.1.0
	 *
	 * @param array        $args       An array of arguments.
	 * @param string|array $taxonomies A taxonomy or array of taxonomies.
	 */
	$args = apply_filters( 'get_terms_args', $args, $taxonomies );

	$child_of = $args['child_of'];
	if ( $child_of ) {
		$hierarchy = _get_term_hierarchy( reset( $taxonomies ) );
		if ( ! isset( $hierarchy[ $child_of ] ) ) {
			return $empty_array;
		}
	}

	$parent = $args['parent'];
	if ( $parent ) {
		$hierarchy = _get_term_hierarchy( reset( $taxonomies ) );
		if ( ! isset( $hierarchy[ $parent ] ) ) {
			return $empty_array;
		}
	}

	// $args can be whatever, only use the args defined in defaults to compute the key
	$filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
	$key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $defaults ) ) ) . serialize( $taxonomies ) . $filter_key );
	$last_changed = wp_cache_get( 'last_changed', 'terms' );
	if ( ! $last_changed ) {
		$last_changed = microtime();
		wp_cache_set( 'last_changed', $last_changed, 'terms' );
	}
	$cache_key = "get_terms:$key:$last_changed";
	$cache = wp_cache_get( $cache_key, 'terms' );
	if ( false !== $cache ) {

		/**
		 * Filter the given taxonomy's terms cache.
		 *
		 * @since 2.3.0
		 *
		 * @param array        $cache      Cached array of terms for the given taxonomy.
		 * @param string|array $taxonomies A taxonomy or array of taxonomies.
		 * @param array        $args       An array of arguments to get terms.
		 */
		$cache = apply_filters( 'get_terms', $cache, $taxonomies, $args );
		return $cache;
	}

	$_orderby = strtolower( $args['orderby'] );
	if ( 'count' == $_orderby ) {
		$orderby = 'tt.count';
	} else if ( 'name' == $_orderby ) {
		$orderby = 't.name';
	} else if ( 'slug' == $_orderby ) {
		$orderby = 't.slug';
	} else if ( 'include' == $_orderby && ! empty( $args['include'] ) ) {
		$include = implode( ',', array_map( 'absint', $args['include'] ) );
		$orderby = "FIELD( t.term_id, $include )";
	} else if ( 'term_group' == $_orderby ) {
		$orderby = 't.term_group';
	} else if ( 'none' == $_orderby ) {
		$orderby = '';
	} elseif ( empty($_orderby) || 'id' == $_orderby ) {
		$orderby = 't.term_id';
	} else {
		$orderby = 't.name';
	}
	/**
	 * Filter the ORDERBY clause of the terms query.
	 *
	 * @since 2.8.0
	 *
	 * @param string       $orderby    ORDERBY clause of the terms query.
	 * @param array        $args       An array of terms query arguments.
	 * @param string|array $taxonomies A taxonomy or array of taxonomies.
	 */
	$orderby = apply_filters( 'get_terms_orderby', $orderby, $args, $taxonomies );

	$order = strtoupper( $args['order'] );
	if ( ! empty( $orderby ) ) {
		$orderby = "ORDER BY $orderby";
	} else {
		$order = '';
	}

	if ( '' !== $order && ! in_array( $order, array( 'ASC', 'DESC' ) ) ) {
		$order = 'ASC';
	}

	$where = "tt.taxonomy IN ('" . implode("', '", array_map( 'esc_sql', $taxonomies ) ) . "')";

	$exclude = $args['exclude'];
	$exclude_tree = $args['exclude_tree'];
	$include = $args['include'];

	$inclusions = '';
	if ( ! empty( $include ) ) {
		$exclude = '';
		$exclude_tree = '';
		$inclusions = implode( ',', wp_parse_id_list( $include ) );
	}

	if ( ! empty( $inclusions ) ) {
		$inclusions = ' AND t.term_id IN ( ' . $inclusions . ' )';
		$where .= $inclusions;
	}

	if ( ! empty( $exclude_tree ) ) {
		$exclude_tree = wp_parse_id_list( $exclude_tree );
		$excluded_children = $exclude_tree;
		foreach ( $exclude_tree as $extrunk ) {
			$excluded_children = array_merge(
				$excluded_children,
				(array) get_terms( $taxonomies[0], array( 'child_of' => intval( $extrunk ), 'fields' => 'ids', 'hide_empty' => 0 ) )
			);
		}
		$exclusions = implode( ',', array_map( 'intval', $excluded_children ) );
	} else {
		$exclusions = '';
	}

	if ( ! empty( $exclude ) ) {
		$exterms = wp_parse_id_list( $exclude );
		if ( empty( $exclusions ) ) {
			$exclusions = implode( ',', $exterms );
		} else {
			$exclusions .= ', ' . implode( ',', $exterms );
		}
	}

	if ( ! empty( $exclusions ) ) {
		$exclusions = ' AND t.term_id NOT IN (' . $exclusions . ')';
	}

	/**
	 * Filter the terms to exclude from the terms query.
	 *
	 * @since 2.3.0
	 *
	 * @param string       $exclusions NOT IN clause of the terms query.
	 * @param array        $args       An array of terms query arguments.
	 * @param string|array $taxonomies A taxonomy or array of taxonomies.
	 */
	$exclusions = apply_filters( 'list_terms_exclusions', $exclusions, $args, $taxonomies );

	if ( ! empty( $exclusions ) ) {
		$where .= $exclusions;
	}

	if ( ! empty( $args['slug'] ) ) {
		if ( is_array( $args['slug'] ) ) {
			$slug = array_map( 'sanitize_title', $args['slug'] );
			$where .= " AND t.slug IN ('" . implode( "', '", $slug ) . "')";
		} else {
			$slug = sanitize_title( $args['slug'] );
			$where .= " AND t.slug = '$slug'";
		}
	}

	if ( ! empty( $args['name__like'] ) ) {
		$where .= $wpdb->prepare( " AND t.name LIKE %s", '%' . $wpdb->esc_like( $args['name__like'] ) . '%' );
	}

	if ( ! empty( $args['description__like'] ) ) {
		$where .= $wpdb->prepare( " AND tt.description LIKE %s", '%' . $wpdb->esc_like( $args['description__like'] ) . '%' );
	}

	if ( '' !== $parent ) {
		$parent = (int) $parent;
		$where .= " AND tt.parent = '$parent'";
	}

	$hierarchical = $args['hierarchical'];
	if ( 'count' == $args['fields'] ) {
		$hierarchical = false;
	}
	if ( $args['hide_empty'] && !$hierarchical ) {
		$where .= ' AND tt.count > 0';
	}

	$number = $args['number'];
	$offset = $args['offset'];

	// don't limit the query results when we have to descend the family tree
	if ( $number && ! $hierarchical && ! $child_of && '' === $parent ) {
		if ( $offset ) {
			$limits = 'LIMIT ' . $offset . ',' . $number;
		} else {
			$limits = 'LIMIT ' . $number;
		}
	} else {
		$limits = '';
	}

	if ( ! empty( $args['search'] ) ) {
		$like = '%' . $wpdb->esc_like( $args['search'] ) . '%';
		$where .= $wpdb->prepare( ' AND ((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like );
	}

	$selects = array();
	switch ( $args['fields'] ) {
		case 'all':
			$selects = array( 't.*', 'tt.*' );
			break;
		case 'ids':
		case 'id=>parent':
			$selects = array( 't.term_id', 'tt.parent', 'tt.count' );
			break;
		case 'names':
			$selects = array( 't.term_id', 'tt.parent', 'tt.count', 't.name' );
			break;
		case 'count':
			$orderby = '';
			$order = '';
			$selects = array( 'COUNT(*)' );
			break;
		case 'id=>name':
			$selects = array( 't.term_id', 't.name', 'tt.count' );
			break;
		case 'id=>slug':
			$selects = array( 't.term_id', 't.slug', 'tt.count' );
			break;
	}

	$_fields = $args['fields'];

	/**
	 * Filter the fields to select in the terms query.
	 *
	 * @since 2.8.0
	 *
	 * @param array        $selects    An array of fields to select for the terms query.
	 * @param array        $args       An array of term query arguments.
	 * @param string|array $taxonomies A taxonomy or array of taxonomies.
	 */
	$fields = implode( ', ', apply_filters( 'get_terms_fields', $selects, $args, $taxonomies ) );

	$join = "INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";

	$pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits' );

	/**
	 * Filter the terms query SQL clauses.
	 *
	 * @since 3.1.0
	 *
	 * @param array        $pieces     Terms query SQL clauses.
	 * @param string|array $taxonomies A taxonomy or array of taxonomies.
	 * @param array        $args       An array of terms query arguments.
	 */
	$clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args );
	$fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
	$join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
	$where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
	$orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
	$order = isset( $clauses[ 'order' ] ) ? $clauses[ 'order' ] : '';
	$limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';

	$query = "SELECT $fields FROM $wpdb->terms AS t $join WHERE $where $orderby $order $limits";

	if ( 'count' == $_fields ) {
		$term_count = $wpdb->get_var($query);
		return $term_count;
	}

	$terms = $wpdb->get_results($query);
	if ( 'all' == $_fields ) {
		update_term_cache( $terms );
	}

	if ( empty($terms) ) {
		wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS );

		/** This filter is documented in wp-includes/taxonomy.php */
		$terms = apply_filters( 'get_terms', array(), $taxonomies, $args );
		return $terms;
	}

	if ( $child_of ) {
		$children = _get_term_hierarchy( reset( $taxonomies ) );
		if ( ! empty( $children ) ) {
			$terms = _get_term_children( $child_of, $terms, reset( $taxonomies ) );
		}
	}

	// Update term counts to include children.
	if ( $args['pad_counts'] && 'all' == $_fields ) {
		_pad_term_counts( $terms, reset( $taxonomies ) );
	}
	// Make sure we show empty categories that have children.
	if ( $hierarchical && $args['hide_empty'] && is_array( $terms ) ) {
		foreach ( $terms as $k => $term ) {
			if ( ! $term->count ) {
				$children = get_term_children( $term->term_id, reset( $taxonomies ) );
				if ( is_array( $children ) ) {
					foreach ( $children as $child_id ) {
						$child = get_term( $child_id, reset( $taxonomies ) );
						if ( $child->count ) {
							continue 2;
						}
					}
				}

				// It really is empty
				unset($terms[$k]);
			}
		}
	}
	reset( $terms );

	$_terms = array();
	if ( 'id=>parent' == $_fields ) {
		while ( $term = array_shift( $terms ) ) {
			$_terms[$term->term_id] = $term->parent;
		}
	} elseif ( 'ids' == $_fields ) {
		while ( $term = array_shift( $terms ) ) {
			$_terms[] = $term->term_id;
		}
	} elseif ( 'names' == $_fields ) {
		while ( $term = array_shift( $terms ) ) {
			$_terms[] = $term->name;
		}
	} elseif ( 'id=>name' == $_fields ) {
		while ( $term = array_shift( $terms ) ) {
			$_terms[$term->term_id] = $term->name;
		}
	} elseif ( 'id=>slug' == $_fields ) {
		while ( $term = array_shift( $terms ) ) {
			$_terms[$term->term_id] = $term->slug;
		}
	}

	if ( ! empty( $_terms ) ) {
		$terms = $_terms;
	}

	if ( $number && is_array( $terms ) && count( $terms ) > $number ) {
		$terms = array_slice( $terms, $offset, $number );
	}

	wp_cache_add( $cache_key, $terms, 'terms', DAY_IN_SECONDS );

	/** This filter is documented in wp-includes/taxonomy */
	$terms = apply_filters( 'get_terms', $terms, $taxonomies, $args );
	return $terms;
}
コード例 #9
0
ファイル: client.php プロジェクト: BackupTheBerlios/oos-svn
	/**
	 * Extended get_terms function support
	 * - Limit category
	 * - Limit days
	 * - Selection restrict
	 * - Min usage
	 *
	 * @param string|array $taxonomies
	 * @param string $args
	 * @return array
	 */
	function getTerms( $taxonomies, $args = '', $internal_st = false ) {
		global $wpdb;
		$empty_array = array();

		$single_taxonomy = false;
		if ( !is_array($taxonomies) ) {
			$single_taxonomy = true;
			$taxonomies = array($taxonomies);
		}

		foreach ( (array) $taxonomies as $taxonomy ) {
			if ( ! is_taxonomy($taxonomy) ) {
				$error = & new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
				return $error;
			}
		}
		$in_taxonomies = "'" . implode("', '", $taxonomies) . "'";
		
		$defaults = array('orderby' => 'name', 'order' => 'ASC',
			'hide_empty' => true, 'exclude' => '', 'exclude_tree' => '', 'include' => '',
			'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '',
			'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '',
			'pad_counts' => false, 'offset' => '', 'search' => '', 
			// Simple tags added
			'limit_days' => 0, 'category' => 0, 'min_usage' => 0, 'st_name__like' => '' );

		$args = wp_parse_args( $args, $defaults );

		// Translate selection order
		$args['orderby'] = $args['selectionby'];
		$args['order']   = $args['selection'];

		$args['number'] 	= absint( $args['number'] );
		$args['offset'] 	= absint( $args['offset'] );
		$args['limit_days'] = absint( $args['limit_days'] );
		$args['min_usage'] 	= absint( $args['min_usage'] );

		if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) ||
			'' !== $args['parent'] ) {
			$args['child_of'] 		= 0;
			$args['hierarchical'] 	= false;
			$args['pad_counts'] 	= false;
		}

		if ( 'all' == $args['get'] ) {
			$args['child_of'] 		= 0;
			$args['hide_empty'] 	= 0;
			$args['hierarchical'] 	= false;
			$args['pad_counts'] 	= false;
		}
		extract($args, EXTR_SKIP);

		if ( $child_of ) {
			$hierarchy = _get_term_hierarchy($taxonomies[0]);
			if ( !isset($hierarchy[$child_of]) )
				return $empty_array;
		}

		if ( $parent ) {
			$hierarchy = _get_term_hierarchy($taxonomies[0]);
			if ( !isset($hierarchy[$parent]) )
				return $empty_array;
		}

		$_orderby = strtolower($orderby);
		if ( 'count' == $_orderby )
			$orderby = 'tt.count';
		if ( 'random' == $_orderby )
			$orderby = 'RAND()';
		else if ( 'name' == $_orderby )
			$orderby = 't.name';
		else if ( 'slug' == $_orderby )
			$orderby = 't.slug';
		else if ( 'term_group' == $_orderby )
			$orderby = 't.term_group';
		elseif ( empty($_orderby) || 'id' == $_orderby )
			$orderby = 't.term_id';
		$orderby = apply_filters( 'get_terms_orderby', $orderby, $args );

		$where = '';
		$inclusions = '';
		if ( !empty($include) ) {
			$exclude = '';
			$exclude_tree = '';
			$interms = preg_split('/[\s,]+/',$include);
			if ( count($interms) ) {
				foreach ( (array) $interms as $interm ) {
					if (empty($inclusions))
						$inclusions  = ' AND ( t.term_id = ' . intval($interm) . ' ';
					else
						$inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
				}
			}
		}
		if ( !empty($inclusions) )
			$inclusions .= ')';
		$where .= $inclusions;

		$exclusions = '';
		if ( ! empty( $exclude_tree ) ) {
			$excluded_trunks = preg_split('/[\s,]+/',$exclude_tree);
			foreach( (array) $excluded_trunks as $extrunk ) {
				$excluded_children = (array) get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids'));
				$excluded_children[] = $extrunk;
				foreach( (array) $excluded_children as $exterm ) {
					if ( empty($exclusions) )
						$exclusions  = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
					else
						$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';

				}
			}
		}
		if ( !empty($exclude) ) {
			$exterms = preg_split('/[\s,]+/',$exclude);
			if ( count($exterms) ) {
				foreach ( (array) $exterms as $exterm ) {
					if ( empty($exclusions) )
						$exclusions  = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
					else
						$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
				}
			}
		}

		if ( !empty($exclusions) )
			$exclusions .= ')';
		$exclusions = apply_filters('list_terms_exclusions', $exclusions, $args );
		$where .= $exclusions;

		// $args can be whatever, only use the args defined in defaults to compute the key
		$filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
		$key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key );
		$last_changed = wp_cache_get('last_changed', 'terms');
		if ( !$last_changed ) {
			$last_changed = time();
			wp_cache_set('last_changed', $last_changed, 'terms');
		}
		$cache_key = "st_get_terms:$key:$last_changed";
		$cache = wp_cache_get( $cache_key, 'terms' );
		if ( false !== $cache ) {
			$cache = apply_filters('get_terms', $cache, $taxonomies, $args);
			return $cache;
		}

		// ST Features : Restrict category
		if ( $category != 0 ) {
			if ( !is_array($taxonomies) ) 
				$taxonomies = array($taxonomies);

			$incategories = preg_split('/[\s,]+/', $category);
			$incategories = array_map('intval', $incategories);

			$taxonomies 	= "'" . implode("', '", $taxonomies) . "'";
			$incategories 	= "'" . implode("', '", $incategories) . "'";

			$where .= " AND tr.object_id IN ( ";
				$where .= "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 ($incategories)";
			$where .= " ) ";

			unset($incategories, $category);
		}

		// ST Features : Limit posts date
		if ( $limit_days != 0 ) {
			$where .= " AND tr.object_id IN ( ";
				$where .= "SELECT ID WHERE $wpdb->posts WHERE post_date_gmt > '" .date( 'Y-m-d H:i:s', time() - $limit_days * 86400 ). "'";
			$where .= " ) ";	

			unset($limit_days);
		}

		if ( !empty($slug) ) {
			$slug = sanitize_title($slug);
			$where .= " AND t.slug = '$slug'";
		}

		if ( !empty($name__like) )
			$where .= " AND t.name LIKE '{$name__like}%'";

		if ( '' !== $parent ) {
			$parent = (int) $parent;
			$where .= " AND tt.parent = '$parent'";
		}

		// ST Features : Another way to search 
		if ( strpos($st_name__like, ' ') !== false ) {

			$st_terms_formatted = array();
			$st_terms = preg_split('/[\s,]+/', $st_name_like);
			foreach ( (array) $st_terms as $st_term ) {
				if ( empty($st_term) )
					continue;
				$st_terms_formatted[] = "t.name LIKE '%".like_escape($st_term)."%'";
			}

			$where .= " AND ( " . explode( ' OR ', $st_terms_formatted ) . " ) ";
			unset( $st_term, $st_terms_formatted, $st_terms );

		} elseif ( !empty($st_name__like) ) {

			$where .= " AND t.name LIKE '%{$st_name__like}%'";

		}

		// ST Features : Add min usage
		if ( $hide_empty && !$hierarchical ) {
			if ( $min_usage == 0 ) 
				$where .= ' AND tt.count > 0';
			else 
				$where .= $wpdb->prepare( ' AND tt.count >= %d', $min_usage );
		}

		if ( !empty($search) ) {
			$search = like_escape($search);
			$where .= " AND (t.name LIKE '%$search%')";
		}

		// don't limit the query results when we have to descend the family tree
		if ( ! empty($number) && ! $hierarchical && empty( $child_of ) && '' === $parent ) {
			if( $offset )
				$limit = 'LIMIT ' . $offset . ',' . $number;
			else
				$limit = 'LIMIT ' . $number;

		} else
			$limit = '';

		$selects = array();
		if ( 'all' == $fields )
			$selects = array('t.*', 'tt.*');
		else if ( 'ids' == $fields )
			$selects = array('t.term_id', 'tt.parent', 'tt.count');
		else if ( 'names' == $fields )
			$selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name');

		$select_this = implode(', ', apply_filters( 'get_terms_fields', $selects, $args ));

		$query = "SELECT $select_this 
			FROM $wpdb->terms AS t 
			INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id 
			INNER JOIN $wpdb->term_relationships AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
			WHERE tt.taxonomy IN ($in_taxonomies) 
			$where 
			GROUP BY t.term_id
			ORDER BY $orderby $order
			$limit";

		$terms = $wpdb->get_results($query);
		if ( 'all' == $fields ) {
			update_term_cache($terms);
		}

		if ( empty($terms) ) {
			wp_cache_add( $cache_key, array(), 'terms' );
			$terms = apply_filters('get_terms', array(), $taxonomies, $args);
			return $terms;
		}

		if ( $child_of ) {
			$children = _get_term_hierarchy($taxonomies[0]);
			if ( ! empty($children) )
				$terms = & _get_term_children($child_of, $terms, $taxonomies[0]);
		}

		// Update term counts to include children.
		if ( $pad_counts && 'all' == $fields )
			_pad_term_counts($terms, $taxonomies[0]);

		// Make sure we show empty categories that have children.
		if ( $hierarchical && $hide_empty && is_array($terms) ) {
			foreach ( $terms as $k => $term ) {
				if ( ! $term->count ) {
					$children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
					if( is_array($children) )
						foreach ( $children as $child )
							if ( $child->count )
								continue 2;

					// It really is empty
					unset($terms[$k]);
				}
			}
		}
		reset ( $terms );

		$_terms = array();
		if ( 'ids' == $fields ) {
			while ( $term = array_shift($terms) )
				$_terms[] = $term->term_id;
			$terms = $_terms;
		} elseif ( 'names' == $fields ) {
			while ( $term = array_shift($terms) )
				$_terms[] = $term->name;
			$terms = $_terms;
		}

		if ( 0 < $number && intval(@count($terms)) > $number ) {
			$terms = array_slice($terms, $offset, $number);
		}

		wp_cache_add( $cache_key, $terms, 'terms' );

		$terms = apply_filters('get_terms', $terms, $taxonomies, $args);
		return $terms;
	}
コード例 #10
0
ファイル: simple-tags.php プロジェクト: nurpax/saastafi
 /**
  * Extended get_terms function support
  *  - Limit category
  *  - Limit days
  *  - Selection restrict
  *  - Min usage
  *
  * @param string|array $taxonomies
  * @param string $args
  * @return array
  */
 function getTerms($taxonomies, $args = '', $skip_cache = false)
 {
     global $wpdb;
     $single_taxonomy = false;
     if (!is_array($taxonomies)) {
         $single_taxonomy = true;
         $taxonomies = array($taxonomies);
     }
     foreach ((array) $taxonomies as $taxonomy) {
         if (!is_taxonomy($taxonomy)) {
             return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
         }
     }
     $in_taxonomies = "'" . implode("', '", $taxonomies) . "'";
     $defaults = array('cloud_selection' => 'count-desc', 'hide_empty' => true, 'exclude' => '', 'include' => '', 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'st_name_like' => '', 'pad_counts' => false, 'limit_days' => 0, 'category' => 0, 'min_usage' => 0);
     $args = wp_parse_args($args, $defaults);
     if (!$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' != $args['parent']) {
         $args['child_of'] = 0;
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     if ('all' == $args['get']) {
         $args['child_of'] = 0;
         $args['hide_empty'] = 0;
         $args['hierarchical'] = false;
         $args['pad_counts'] = false;
     }
     extract($args, EXTR_SKIP);
     if ($child_of) {
         $hierarchy = _get_term_hierarchy($taxonomies[0]);
         if (!isset($hierarchy[$child_of])) {
             return array();
         }
     }
     if ($parent) {
         $hierarchy = _get_term_hierarchy($taxonomies[0]);
         if (!isset($hierarchy[$parent])) {
             return array();
         }
     }
     if ($skip_cache != true) {
         // Get cache if exist
         $key = md5(serialize($args) . serialize($taxonomies));
         if ($cache = wp_cache_get('get_terms', 'terms')) {
             if (isset($cache[$key])) {
                 return apply_filters('get_terms', $cache[$key], $taxonomies, $args);
             }
         }
     }
     // Restrict category
     $category_sql = '';
     if (!empty($category) && $category != '0') {
         $incategories = preg_split('/[\\s,]+/', $category);
         $objects_id = get_objects_in_term($incategories, 'category');
         $objects_id = array_unique($objects_id);
         // to be sure haven't duplicates
         if (empty($objects_id)) {
             // No posts for this category = no tags for this category
             return array();
         }
         foreach ((array) $objects_id as $object_id) {
             $category_sql .= "'" . $object_id . "', ";
         }
         $category_sql = substr($category_sql, 0, strlen($category_sql) - 2);
         // Remove latest ", "
         $category_sql = 'AND p.ID IN (' . $category_sql . ')';
     }
     // count-asc/count-desc/name-asc/name-desc/random
     $cloud_selection = strtolower($cloud_selection);
     switch ($cloud_selection) {
         case 'count-asc':
             $order_by = 'tt.count ASC';
             break;
         case 'random':
             $order_by = 'RAND()';
             break;
         case 'name-asc':
             $order_by = 't.name ASC';
             break;
         case 'name-desc':
             $order_by = 't.name DESC';
             break;
         default:
             // count-desc
             $order_by = 'tt.count DESC';
             break;
     }
     // Min usage
     $restict_usage = '';
     $min_usage = (int) $min_usage;
     if ($min_usage != 0) {
         $restict_usage = ' AND tt.count >= ' . $min_usage;
     }
     $where = '';
     $inclusions = '';
     if (!empty($include)) {
         $exclude = '';
         $interms = preg_split('/[\\s,]+/', $include);
         foreach ((array) $interms as $interm) {
             if (empty($inclusions)) {
                 $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
             } else {
                 $inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
             }
         }
     }
     if (!empty($inclusions)) {
         $inclusions .= ')';
     }
     $where .= $inclusions;
     $exclusions = '';
     if (!empty($exclude)) {
         $exterms = preg_split('/[\\s,]+/', $exclude);
         foreach ((array) $exterms as $exterm) {
             if (empty($exclusions)) {
                 $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
             } else {
                 $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
             }
         }
     }
     if (!empty($exclusions)) {
         $exclusions .= ')';
     }
     $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args);
     $where .= $exclusions;
     if (!empty($slug)) {
         $slug = sanitize_title($slug);
         $where .= " AND t.slug = '{$slug}'";
     }
     if (!empty($name__like)) {
         $where .= " AND t.name LIKE '{$name__like}%'";
     }
     if (strpos($st_name_like, ' ') != false || strpos($st_name_like, ' ') != null) {
         $tmp = '';
         $sts = explode(' ', $st_name_like);
         foreach ((array) $sts as $st) {
             if (empty($st)) {
                 continue;
             }
             $st = addslashes_gpc($st);
             $tmp .= " t.name LIKE '%{$st}%' OR ";
         }
         // Remove latest OR
         $tmp = substr($tmp, 0, strlen($tmp) - 4);
         $where .= " AND ( {$tmp} ) ";
         unset($tmp);
     } elseif (!empty($st_name_like)) {
         $where .= " AND t.name LIKE '%{$st_name_like}%'";
     }
     if ('' != $parent) {
         $parent = (int) $parent;
         $where .= " AND tt.parent = '{$parent}'";
     }
     if ($hide_empty && !$hierarchical) {
         $where .= ' AND tt.count > 0';
     }
     $number_sql = '';
     if (strpos($number, ',') != false || strpos($number, ',') != null) {
         $number_sql = $number;
     } else {
         $number = (int) $number;
         if ($number != 0) {
             $number_sql = 'LIMIT ' . $number;
         }
     }
     if ('all' == $fields) {
         $select_this = 't.*, tt.*';
     } else {
         if ('ids' == $fields) {
             $select_this = 't.term_id';
         } else {
             if ('names' == $fields) {
                 $select_this == 't.name';
             }
         }
     }
     // Limit posts date
     $limitdays_sql = '';
     $limit_days = (int) $limit_days;
     if ($limit_days != 0) {
         $limitdays_sql = 'AND p.post_date > "' . date('Y-m-d H:i:s', time() - $limit_days * 86400) . '"';
     }
     // Join posts ?
     $inner_posts = '';
     if (!empty($limitdays_sql) | !empty($category_sql)) {
         $inner_posts = "\r\n\t\t\t\tINNER JOIN {$wpdb->term_relationships} AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id\r\n\t\t\t\tINNER JOIN {$wpdb->posts} AS p ON tr.object_id = p.ID";
     }
     $query = "SELECT DISTINCT {$select_this}\r\n\t\t\tFROM {$wpdb->terms} AS t\r\n\t\t\tINNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id\r\n\t\t\t{$inner_posts}\r\n\t\t\tWHERE tt.taxonomy IN ( {$in_taxonomies} )\r\n\t\t\t{$limitdays_sql}\r\n\t\t\t{$category_sql}\r\n\t\t\t{$where}\r\n\t\t\t{$restict_usage}\r\n\t\t\tORDER BY {$order_by}\r\n\t\t\t{$number_sql}";
     if ('all' == $fields) {
         $terms = $wpdb->get_results($query);
         if ($skip_cache != true) {
             update_term_cache($terms);
         }
     } elseif ('ids' == $fields) {
         $terms = $wpdb->get_col($query);
     }
     if (empty($terms)) {
         return array();
     }
     if ($child_of || $hierarchical) {
         $children = _get_term_hierarchy($taxonomies[0]);
         if (!empty($children)) {
             $terms =& _get_term_children($child_of, $terms, $taxonomies[0]);
         }
     }
     // Update term counts to include children.
     if ($pad_counts) {
         _pad_term_counts($terms, $taxonomies[0]);
     }
     // Make sure we show empty categories that have children.
     if ($hierarchical && $hide_empty) {
         foreach ((array) $terms as $k => $term) {
             if (!$term->count) {
                 $children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
                 foreach ((array) $children as $child) {
                     if ($child->count) {
                         continue 2;
                     }
                 }
                 // It really is empty
                 unset($terms[$k]);
             }
         }
     }
     reset($terms);
     if ($skip_cache != true) {
         $cache[$key] = $terms;
         wp_cache_set('get_terms', $cache, 'terms');
     }
     $terms = apply_filters('get_terms', $terms, $taxonomies, $args);
     return $terms;
 }