function ajax_query() { // options $options = acf_parse_args($_GET, array('post_id' => 0, 's' => '', 'field_key' => '', 'nonce' => '')); // validate if (!wp_verify_nonce($options['nonce'], 'acf_nonce')) { die; } // vars $r = array(); $args = array('hide_empty' => false); // load field $field = acf_get_field($options['field_key']); if (!$field) { die; } // search if ($options['s']) { $args['search'] = $options['s']; } // filters $args = apply_filters('acf/fields/taxonomy/query', $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/name=' . $field['name'], $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/key=' . $field['key'], $args, $field, $options['post_id']); // get terms $terms = get_terms($field['taxonomy'], $args); // sort into hierachial order! if (is_taxonomy_hierarchical($field['taxonomy'])) { // this will fail if a search has taken place because parents wont exist if (empty($args['search'])) { $terms = _get_term_children(0, $terms, $field['taxonomy']); } } /// append to r foreach ($terms as $term) { // add to json $r[] = array('id' => $term->term_id, 'text' => $this->get_term_title($term, $field, $options['post_id'])); } // return JSON echo json_encode($r); die; }
function get_choices($options = array()) { // defaults $options = acf_parse_args($options, array('post_id' => 0, 's' => '', 'field_key' => '')); // vars $r = array(); $args = array('hide_empty' => false); // load field $field = acf_get_field($options['field_key']); if (!$field) { return false; } // search if ($options['s']) { $args['search'] = $options['s']; } // filters $args = apply_filters('acf/fields/taxonomy/query', $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/name=' . $field['name'], $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/key=' . $field['key'], $args, $field, $options['post_id']); // get terms $terms = get_terms($field['taxonomy'], $args); // sort into hierachial order! if (is_taxonomy_hierarchical($field['taxonomy'])) { // get parent $parent = acf_maybe_get($args, 'parent', 0); $parent = acf_maybe_get($args, 'child_of', $parent); // this will fail if a search has taken place because parents wont exist if (empty($args['search'])) { $terms = _get_term_children($parent, $terms, $field['taxonomy']); } } /// append to r foreach ($terms as $term) { // add to json $r[] = array('id' => $term->term_id, 'text' => $this->get_term_title($term, $field, $options['post_id'])); } // return return $r; }
/** * Get the subset of $terms that are descendants of $term_id. * * If `$terms` is an array of objects, then _get_term_children() returns an array of objects. * If `$terms` is an array of IDs, then _get_term_children() returns an array of IDs. * * @access private * @since 2.3.0 * * @param int $term_id The ancestor term: all returned terms should be descendants of `$term_id`. * @param array $terms The set of terms - either an array of term objects or term IDs - from which those that * are descendants of $term_id will be chosen. * @param string $taxonomy The taxonomy which determines the hierarchy of the terms. * @param array $ancestors Optional. Term ancestors that have already been identified. Passed by reference, to keep * track of found terms when recursing the hierarchy. The array of located ancestors is used * to prevent infinite recursion loops. For performance, `term_ids` are used as array keys, * with 1 as value. Default empty array. * @return array|WP_Error The subset of $terms that are descendants of $term_id. */ function _get_term_children($term_id, $terms, $taxonomy, &$ancestors = array()) { $empty_array = array(); if (empty($terms)) { return $empty_array; } $term_list = array(); $has_children = _get_term_hierarchy($taxonomy); if (0 != $term_id && !isset($has_children[$term_id])) { return $empty_array; } // Include the term itself in the ancestors array, so we can properly detect when a loop has occurred. if (empty($ancestors)) { $ancestors[$term_id] = 1; } foreach ((array) $terms as $term) { $use_id = false; if (!is_object($term)) { $term = get_term($term, $taxonomy); if (is_wp_error($term)) { return $term; } $use_id = true; } // Don't recurse if we've already identified the term as a child - this indicates a loop. if (isset($ancestors[$term->term_id])) { continue; } if ($term->parent == $term_id) { if ($use_id) { $term_list[] = $term->term_id; } else { $term_list[] = $term; } if (!isset($has_children[$term->term_id])) { continue; } $ancestors[$term->term_id] = 1; if ($children = _get_term_children($term->term_id, $terms, $taxonomy, $ancestors)) { $term_list = array_merge($term_list, $children); } } } return $term_list; }
function acf_get_taxonomy_terms($taxonomies = array()) { // force array $taxonomies = acf_get_array($taxonomies); // get pretty taxonomy names $taxonomies = acf_get_pretty_taxonomies($taxonomies); // vars $r = array(); // populate $r foreach (array_keys($taxonomies) as $taxonomy) { // vars $label = $taxonomies[$taxonomy]; $terms = get_terms($taxonomy, array('hide_empty' => false)); $is_hierarchical = is_taxonomy_hierarchical($taxonomy); // bail early i no terms if (empty($terms)) { continue; } // sort into hierachial order! if ($is_hierarchical) { $terms = _get_term_children(0, $terms, $taxonomy); } // add placeholder $r[$label] = array(); // add choices foreach ($terms as $term) { $k = "{$taxonomy}:{$term->slug}"; $r[$label][$k] = acf_get_term_title($term); } } // return return $r; }
/** * _get_term_children() - Get array of child terms * * If $terms is an array of objects, then objects will returned from the function. * If $terms is an array of IDs, then an array of ids of children will be returned. * * @package WordPress * @subpackage Taxonomy * @access private * @since 2.3 * * @param int $term_id Look for this Term ID in $terms * @param array $terms List of Term IDs * @param string $taxonomy Term Context * @return array Empty if $terms is empty else returns full list of child terms. */ function &_get_term_children($term_id, $terms, $taxonomy) { $empty_array = array(); if ( empty($terms) ) return $empty_array; $term_list = array(); $has_children = _get_term_hierarchy($taxonomy); if ( ( 0 != $term_id ) && ! isset($has_children[$term_id]) ) return $empty_array; foreach ( $terms as $term ) { $use_id = false; if ( !is_object($term) ) { $term = get_term($term, $taxonomy); if ( is_wp_error( $term ) ) return $term; $use_id = true; } if ( $term->term_id == $term_id ) continue; if ( $term->parent == $term_id ) { if ( $use_id ) $term_list[] = $term->term_id; else $term_list[] = $term; if ( !isset($has_children[$term->term_id]) ) continue; if ( $children = _get_term_children($term->term_id, $terms, $taxonomy) ) $term_list = array_merge($term_list, $children); } } return $term_list; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * @covers ::_get_term_children * @ticket 24461 */ public function test__get_term_children_handles_cycles_when_terms_argument_contains_objects() { remove_filter('wp_update_term_parent', 'wp_check_term_hierarchy_for_loops', 10); $c1 = $this->factory->category->create_and_get(); $c2 = $this->factory->category->create_and_get(array('parent' => $c1->term_id)); $c3 = $this->factory->category->create_and_get(array('parent' => $c2->term_id)); wp_update_term($c1->term_id, 'category', array('parent' => $c3->term_id)); add_filter('wp_update_term_parent', 'wp_check_term_hierarchy_for_loops', 10, 3); $result = _get_term_children($c1->term_id, array($c1, $c2, $c3), 'category'); $this->assertEqualSets(array($c2, $c3), $result); }
function get_choices($options = array()) { // defaults $options = acf_parse_args($options, array('post_id' => 0, 's' => '', 'field_key' => '', 'paged' => 0)); // load field $field = acf_get_field($options['field_key']); if (!$field) { return false; } // vars $r = array(); $args = array(); $is_hierarchical = is_taxonomy_hierarchical($field['taxonomy']); $is_pagination = $options['paged'] > 0; $limit = 20; $offset = 20 * ($options['paged'] - 1); // hide empty $args['hide_empty'] = false; // pagination // - don't bother for hierarchial terms, we will need to load all terms anyway if (!$is_hierarchical && $is_pagination) { $args['offset'] = $offset; $args['number'] = $limit; } // search if ($options['s']) { $args['search'] = $options['s']; } // filters $args = apply_filters('acf/fields/taxonomy/query', $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/name=' . $field['name'], $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/key=' . $field['key'], $args, $field, $options['post_id']); // get terms $terms = get_terms($field['taxonomy'], $args); // sort into hierachial order! if ($is_hierarchical) { // get parent $parent = acf_maybe_get($args, 'parent', 0); $parent = acf_maybe_get($args, 'child_of', $parent); // this will fail if a search has taken place because parents wont exist if (empty($args['search'])) { $terms = _get_term_children($parent, $terms, $field['taxonomy']); } // fake pagination if ($is_pagination) { $terms = array_slice($terms, $offset, $limit); } } /// append to r foreach ($terms as $term) { // add to json $r[] = array('id' => $term->term_id, 'text' => $this->get_term_title($term, $field, $options['post_id'])); } // return return $r; }
function get_ajax_query($options = array()) { // defaults $options = acf_parse_args($options, array('post_id' => 0, 's' => '', 'field_key' => '', 'paged' => 0)); // load field $field = acf_get_field($options['field_key']); if (!$field) { return false; } // bail early if taxonomy does not exist if (!taxonomy_exists($field['taxonomy'])) { return false; } // vars $results = array(); $is_hierarchical = is_taxonomy_hierarchical($field['taxonomy']); $is_pagination = $options['paged'] > 0; $is_search = false; $limit = 20; $offset = 20 * ($options['paged'] - 1); // args $args = array('taxonomy' => $field['taxonomy'], 'hide_empty' => false); // pagination // - don't bother for hierarchial terms, we will need to load all terms anyway if ($is_pagination && !$is_hierarchical) { $args['number'] = $limit; $args['offset'] = $offset; } // search if ($options['s'] !== '') { // strip slashes (search may be integer) $s = wp_unslash(strval($options['s'])); // update vars $args['search'] = $s; $is_search = true; } // filters $args = apply_filters('acf/fields/taxonomy/query', $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/name=' . $field['name'], $args, $field, $options['post_id']); $args = apply_filters('acf/fields/taxonomy/query/key=' . $field['key'], $args, $field, $options['post_id']); // get terms $terms = acf_get_terms($args); // sort into hierachial order! if ($is_hierarchical) { // update vars $limit = acf_maybe_get($args, 'number', $limit); $offset = acf_maybe_get($args, 'offset', $offset); // get parent $parent = acf_maybe_get($args, 'parent', 0); $parent = acf_maybe_get($args, 'child_of', $parent); // this will fail if a search has taken place because parents wont exist if (!$is_search) { $terms = _get_term_children($parent, $terms, $field['taxonomy']); } // fake pagination if ($is_pagination) { $terms = array_slice($terms, $offset, $limit); } } /// append to r foreach ($terms as $term) { // add to json $results[] = array('id' => $term->term_id, 'text' => $this->get_term_title($term, $field, $options['post_id'])); } // vars $response = array('results' => $results, 'limit' => $limit); // return return $response; }
/** * 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; }
public static function flt_get_terms($terms, $taxonomies, $args) { if (!is_array($terms)) { return $terms; } if (empty($terms)) { return array(); } global $terms_interceptor; if ($terms_interceptor->skip_filtering($taxonomies, $args)) { return $terms; } extract($args, EXTR_SKIP); if ('ids' == $fields) { return $terms; } // if some args were forced to prevent core post-processing, restore actual values now if (!empty($args['actual_args'])) { extract($args['actual_args']); } if ('all' == $fields) { // buffer term names in case they were filtered previously $term_names = pp_get_property_array($terms, 'term_id', 'name'); } if (!empty($child_of)) { $children = _get_term_hierarchy(reset($taxonomies)); if (!empty($children)) { $terms = _get_term_children($child_of, $terms, reset($taxonomies)); } } // Replace DB-stored term counts with actual number of posts this user can read. // In addition, without the pp_tally_term_counts() call, WP will hide terms that have no public posts (even if this user can read some of the pvt posts). // Post counts will be incremented to include child terms only if $pad_counts is true if (!defined('XMLRPC_REQUEST') && 1 == count($taxonomies)) { global $pagenow; if (!is_admin() || !in_array($pagenow, array('post.php', 'post-new.php'))) { if ($hide_empty || !empty($args['actual_args']['hide_empty'])) { // need to tally for all terms in case some were hidden by core function due to lack of public posts $all_terms = get_terms(reset($taxonomies), array('fields' => 'all', 'pp_no_filter' => true, 'hide_empty' => false)); PP_TermsQueryLib::tally_term_counts($all_terms, reset($taxonomies), compact('pad_counts', 'skip_teaser', 'post_type')); foreach (array_keys($terms) as $k) { foreach (array_keys($all_terms) as $key) { if ($all_terms[$key]->term_taxonomy_id == $terms[$k]->term_taxonomy_id) { $terms[$k]->count = $all_terms[$key]->count; break; } } } } else { PP_TermsQueryLib::tally_term_counts($terms, reset($taxonomies), compact('pad_counts', 'skip_teaser', 'post_type')); } } } if ($hide_empty || !empty($args['actual_args']['hide_empty'])) { if ($hierarchical) { foreach ($taxonomies as $taxonomy) { if (empty($all_terms) || count($taxonomies) > 1) { $all_terms = get_terms($taxonomy, array('fields' => 'all', 'pp_no_filter' => true, 'hide_empty' => false)); } // Remove empty terms, but only if their descendants are all empty too. foreach ($terms as $k => $term) { if (!$term->count) { if ($descendants = _get_term_children($term->term_id, $all_terms, $taxonomy)) { foreach ($descendants as $child) { if ($child->count) { continue 2; } } } // It really is empty unset($terms[$k]); } } } } else { foreach ($terms as $key => $term) { if (!$term->count) { unset($terms[$key]); } } } } if ($hierarchical && !$parent && count($taxonomies) == 1) { require_once PPC_ABSPATH . '/lib/ancestry_lib_pp.php'; $ancestors = PP_Ancestry::get_term_ancestors(reset($taxonomies)); // array of all ancestor IDs for keyed term_id, with direct parent first $remap_args = array_merge(compact('child_of', 'parent', 'exclude'), array('orderby' => 'name', 'col_id' => 'term_id', 'col_parent' => 'parent')); PP_Ancestry::remap_tree($terms, $ancestors, $remap_args); } reset($terms); // === Standard WP post-processing for include, fields, number args === // $_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); } // === end standard WP block === // restore buffered term names in case they were filtered previously if ('all' == $fields) { pp_restore_property_array($terms, $term_names, 'term_id', 'name'); } return $terms; }
/** * 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; }