Example #1
0
/**
 * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
 *
 * The following information has to do the $args parameter and for what can be
 * contained in the string or array of that parameter, if it exists.
 *
 * The first argument is called, 'orderby' and has the default value of 'name'.
 * The other value that is supported is 'count'.
 *
 * The second argument is called, 'order' and has the default value of 'ASC'.
 * The only other value that will be acceptable is 'DESC'.
 *
 * The final argument supported is called, 'fields' and has the default value of
 * 'all'. There are multiple other options that can be used instead. Supported
 * values are as follows: 'all', 'ids', 'names', and finally
 * 'all_with_object_id'.
 *
 * The fields argument also decides what will be returned. If 'all' or
 * 'all_with_object_id' is choosen or the default kept intact, then all matching
 * terms objects will be returned. If either 'ids' or 'names' is used, then an
 * array of all matching term ids or term names will be returned respectively.
 *
 * @package WordPress
 * @subpackage Taxonomy
 * @since 2.3.0
 * @uses $wpdb
 *
 * @param int|array $object_id The id of the object(s) to retrieve.
 * @param string|array $taxonomies The taxonomies to retrieve terms from.
 * @param array|string $args Change what is returned
 * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if $taxonomy does not exist.
 */
function wp_get_object_terms($object_ids, $taxonomies, $args = array())
{
    global $wpdb;
    if (!is_array($taxonomies)) {
        $taxonomies = array($taxonomies);
    }
    foreach ((array) $taxonomies as $taxonomy) {
        if (!is_taxonomy($taxonomy)) {
            return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
        }
    }
    if (!is_array($object_ids)) {
        $object_ids = array($object_ids);
    }
    $object_ids = array_map('intval', $object_ids);
    $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
    $args = wp_parse_args($args, $defaults);
    $terms = array();
    if (count($taxonomies) > 1) {
        foreach ($taxonomies as $index => $taxonomy) {
            $t = get_taxonomy($taxonomy);
            if (isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args)) {
                unset($taxonomies[$index]);
                $terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args)));
            }
        }
    } else {
        $t = get_taxonomy($taxonomies[0]);
        if (isset($t->args) && is_array($t->args)) {
            $args = array_merge($args, $t->args);
        }
    }
    extract($args, EXTR_SKIP);
    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 ('term_order' == $orderby) {
                        $orderby = 'tr.term_order';
                    } else {
                        if ('none' == $orderby) {
                            $orderby = '';
                            $order = '';
                        } else {
                            $orderby = 't.term_id';
                        }
                    }
                }
            }
        }
    }
    // tt_ids queries can only be none or tr.term_taxonomy_id
    if ('tt_ids' == $fields && !empty($orderby)) {
        $orderby = 'tr.term_taxonomy_id';
    }
    if (!empty($orderby)) {
        $orderby = "ORDER BY {$orderby}";
    }
    $taxonomies = "'" . implode("', '", $taxonomies) . "'";
    $object_ids = implode(', ', $object_ids);
    $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';
            } else {
                if ('all_with_object_id' == $fields) {
                    $select_this = 't.*, tt.*, tr.object_id';
                }
            }
        }
    }
    $query = "SELECT {$select_this} FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.term_id = t.term_id INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ({$taxonomies}) AND tr.object_id IN ({$object_ids}) {$orderby} {$order}";
    if ('all' == $fields || 'all_with_object_id' == $fields) {
        $terms = array_merge($terms, $wpdb->get_results($query));
        update_term_cache($terms);
    } else {
        if ('ids' == $fields || 'names' == $fields) {
            $terms = array_merge($terms, $wpdb->get_col($query));
        } else {
            if ('tt_ids' == $fields) {
                $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM {$wpdb->term_relationships} AS tr INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ({$object_ids}) AND tt.taxonomy IN ({$taxonomies}) {$orderby} {$order}");
            }
        }
    }
    if (!$terms) {
        $terms = array();
    }
    return apply_filters('wp_get_object_terms', $terms, $object_ids, $taxonomies, $args);
}
 /**
  * Adds tags and categories to the sitemap.
  *
  * @since 1.3
  */
 protected function taxonomies()
 {
     global $wpdb;
     $taxonomy = $this->get_info('content_type');
     if (!($taxonomy == 'category' || $taxonomy == 'post_tag')) {
         return false;
     }
     $tax_not_in = '';
     $limit = $this->getLimit();
     $exclude = $this->get_info('exclude', array());
     if ($exclude && ($ids = wp_parse_id_list($exclude))) {
         $tax_not_in = 't.term_id NOT IN (' . implode(',', $ids) . ') AND';
     }
     // t.slug and tt.taxonomy are necessary to make get_term_link() work properly
     $terms = $wpdb->get_results("SELECT t.term_id, t.slug, tt.taxonomy, MAX(p.post_modified) AS `last_modified`\n\t\t\t FROM {$wpdb->terms} AS t\n\t\t\t INNER JOIN {$wpdb->term_taxonomy} AS tt USING(term_id)\n\t\t\t \tCROSS JOIN {$wpdb->term_relationships} AS tr USING(term_taxonomy_id)\n\t\t\t \tCROSS JOIN {$wpdb->posts} AS p ON p.ID = tr.object_id\n\t\t\t WHERE {$tax_not_in} tt.taxonomy = '{$taxonomy}' AND p.post_type = 'post' AND p.post_status = 'publish'\n\t\t\t GROUP BY t.term_id\n\t\t\t ORDER BY p.post_modified DESC\n\t\t\t LIMIT {$limit}");
     // This hack lets us save a lot of queries that would be performed when we call get_term_link()
     update_term_cache($terms);
     if ($terms) {
         $changefreq = $this->get_info('changefreq', 'none');
         $priority = $this->get_info('priority', 'none');
         foreach ($terms as $term) {
             $this->addUrlItem(get_term_link($term), $term->last_modified, $changefreq, $priority);
         }
     }
 }
/**
 * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
 *
 * The following information has to do the $args parameter and for what can be
 * contained in the string or array of that parameter, if it exists.
 *
 * The first argument is called, 'orderby' and has the default value of 'name'.
 * The other value that is supported is 'count'.
 *
 * The second argument is called, 'order' and has the default value of 'ASC'.
 * The only other value that will be acceptable is 'DESC'.
 *
 * The final argument supported is called, 'fields' and has the default value of
 * 'all'. There are multiple other options that can be used instead. Supported
 * values are as follows: 'all', 'ids', 'names', and finally
 * 'all_with_object_id'.
 *
 * The fields argument also decides what will be returned. If 'all' or
 * 'all_with_object_id' is chosen or the default kept intact, then all matching
 * terms objects will be returned. If either 'ids' or 'names' is used, then an
 * array of all matching term ids or term names will be returned respectively.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|array $object_ids The ID(s) of the object(s) to retrieve.
 * @param string|array $taxonomies The taxonomies to retrieve terms from.
 * @param array|string $args Change what is returned
 * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if any of the $taxonomies don't exist.
 */
function wp_get_object_terms($object_ids, $taxonomies, $args = array()) {
	global $wpdb;

	if ( empty( $object_ids ) || empty( $taxonomies ) )
		return array();

	if ( !is_array($taxonomies) )
		$taxonomies = array($taxonomies);

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

	if ( !is_array($object_ids) )
		$object_ids = array($object_ids);
	$object_ids = array_map('intval', $object_ids);

	$defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
	$args = wp_parse_args( $args, $defaults );

	$terms = array();
	if ( count($taxonomies) > 1 ) {
		foreach ( $taxonomies as $index => $taxonomy ) {
			$t = get_taxonomy($taxonomy);
			if ( isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args) ) {
				unset($taxonomies[$index]);
				$terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args)));
			}
		}
	} else {
		$t = get_taxonomy($taxonomies[0]);
		if ( isset($t->args) && is_array($t->args) )
			$args = array_merge($args, $t->args);
	}

	$orderby = $args['orderby'];
	$order = $args['order'];
	$fields = $args['fields'];

	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 ( 'term_order' == $orderby )
		$orderby = 'tr.term_order';
	else if ( 'none' == $orderby ) {
		$orderby = '';
		$order = '';
	} else {
		$orderby = 't.term_id';
	}

	// tt_ids queries can only be none or tr.term_taxonomy_id
	if ( ('tt_ids' == $fields) && !empty($orderby) )
		$orderby = 'tr.term_taxonomy_id';

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

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

	$taxonomies = "'" . implode("', '", array_map( 'esc_sql', $taxonomies ) ) . "'";
	$object_ids = implode(', ', $object_ids);

	$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';
	else if ( 'slugs' == $fields )
		$select_this = 't.slug';
	else if ( 'all_with_object_id' == $fields )
		$select_this = 't.*, tt.*, tr.object_id';

	$query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tr.object_id IN ($object_ids) $orderby $order";

	$objects = false;
	if ( 'all' == $fields || 'all_with_object_id' == $fields ) {
		$_terms = $wpdb->get_results( $query );
		foreach ( $_terms as $key => $term ) {
			$_terms[$key] = sanitize_term( $term, $taxonomy, 'raw' );
		}
		$terms = array_merge( $terms, $_terms );
		update_term_cache( $terms );
		$objects = true;
	} else if ( 'ids' == $fields || 'names' == $fields || 'slugs' == $fields ) {
		$_terms = $wpdb->get_col( $query );
		$_field = ( 'ids' == $fields ) ? 'term_id' : 'name';
		foreach ( $_terms as $key => $term ) {
			$_terms[$key] = sanitize_term_field( $_field, $term, $term, $taxonomy, 'raw' );
		}
		$terms = array_merge( $terms, $_terms );
	} else if ( 'tt_ids' == $fields ) {
		$terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) $orderby $order");
		foreach ( $terms as $key => $tt_id ) {
			$terms[$key] = sanitize_term_field( 'term_taxonomy_id', $tt_id, 0, $taxonomy, 'raw' ); // 0 should be the term id, however is not needed when using raw context.
		}
	}

	if ( ! $terms ) {
		$terms = array();
	} elseif ( $objects && 'all_with_object_id' !== $fields ) {
		$_tt_ids = array();
		$_terms = array();
		foreach ( $terms as $term ) {
			if ( in_array( $term->term_taxonomy_id, $_tt_ids ) ) {
				continue;
			}

			$_tt_ids[] = $term->term_taxonomy_id;
			$_terms[] = $term;
		}
		$terms = $_terms;
	} elseif ( ! $objects ) {
		$terms = array_values( array_unique( $terms ) );
	}
	/**
	 * Filter the terms for a given object or objects.
	 *
	 * @since 2.8.0
	 *
	 * @param array        $terms      An array of terms for the given object or objects.
	 * @param array|int    $object_ids Object ID or array of IDs.
	 * @param array|string $taxonomies A taxonomy or array of taxonomies.
	 * @param array        $args       An array of arguments for retrieving terms for
	 *                                 the given object(s).
	 */
	return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args );
}
Example #4
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;
 }
/**
 * wp_get_object_terms() - Retrieves the terms associated with the given object(s), in the supplied taxonomies.
 *
 * The following information has to do the $args parameter and for what can be contained in the string
 * or array of that parameter, if it exists.
 *
 * The first argument is called, 'orderby' and has the default value of 'name'. The other value that is
 * supported is 'count'.
 *
 * The second argument is called, 'order' and has the default value of 'ASC'. The only other value that
 * will be acceptable is 'DESC'.
 *
 * The final argument supported is called, 'fields' and has the default value of 'all'. There are
 * multiple other options that can be used instead. Supported values are as follows: 'all', 'ids',
 * 'names', and finally 'all_with_object_id'.
 *
 * The fields argument also decides what will be returned. If 'all' or 'all_with_object_id' is choosen or
 * the default kept intact, then all matching terms objects will be returned. If either 'ids' or 'names'
 * is used, then an array of all matching term ids or term names will be returned respectively.
 *
 * @package WordPress
 * @subpackage Taxonomy
 * @since 2.3
 * @uses $wpdb
 *
 * @param int|array $object_id The id of the object(s) to retrieve.
 * @param string|array $taxonomies The taxonomies to retrieve terms from.
 * @param array|string $args Change what is returned
 * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if $taxonomy does not exist.
 */
function wp_get_object_terms($object_ids, $taxonomies, $args = array()) {
	global $wpdb;

	if ( !is_array($taxonomies) )
		$taxonomies = array($taxonomies);

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

	if ( !is_array($object_ids) )
		$object_ids = array($object_ids);
	$object_ids = array_map('intval', $object_ids);

	$defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
	$args = wp_parse_args( $args, $defaults );

	$terms = array();
	if ( count($taxonomies) > 1 ) {
		foreach ( $taxonomies as $index => $taxonomy ) {
			$t = get_taxonomy($taxonomy);
			if ( is_array($t->args) && $args != array_merge($args, $t->args) ) {
				unset($taxonomies[$index]);
				$terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args)));
			}
		}
	} else {
		$t = get_taxonomy($taxonomies[0]);
		if ( is_array($t->args) )
			$args = array_merge($args, $t->args);
	}

	extract($args, EXTR_SKIP);

	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 ( 'term_order' == $orderby )
		$orderby = 'tr.term_order';
	else
		$orderby = 't.term_id';

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

	$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';
	else if ( 'all_with_object_id' == $fields )
		$select_this = 't.*, tt.*, tr.object_id';

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

	if ( 'all' == $fields || 'all_with_object_id' == $fields ) {
		$terms = array_merge($terms, $wpdb->get_results($query));
		update_term_cache($terms);
	} else if ( 'ids' == $fields || 'names' == $fields ) {
		$terms = array_merge($terms, $wpdb->get_col($query));
	} else if ( 'tt_ids' == $fields ) {
		$terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) ORDER BY tr.term_taxonomy_id $order");
	}

	if ( ! $terms )
		return array();

	return $terms;
}
Example #6
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)
 {
     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;
 }
 function flt_get_terms($results, $taxonomies, $args)
 {
     global $wpdb;
     $empty_array = array();
     //d_echo( 'flt_get_terms input:' );
     $single_taxonomy = false;
     if (!is_array($taxonomies)) {
         $single_taxonomy = true;
         $taxonomies = array($taxonomies);
     } elseif (count($taxonomies) < 2) {
         $single_taxonomy = true;
     }
     // === END Role Scoper MODIFICATION ===
     foreach ((array) $taxonomies as $taxonomy) {
         if (!taxonomy_exists($taxonomy)) {
             // === BEGIN Role Scoper MODIFICATION: this caused plugin activation error in some situations (though at that time, the error object was created and return on a single line, not byRef as now) ===
             //
             //$error = & new WP_Error('invalid_taxonomy', __awp('Invalid Taxonomy'));
             //return $error;
             return array();
             //
             // === END Role Scoper MODIFICATION ===
         }
     }
     // === BEGIN Role Scoper ADDITION: global var; various special case exemption checks ===
     //
     global $scoper;
     if ($tx_obj = get_taxonomy($taxonomies[0])) {
         // don't require use_taxonomies setting for link_categories or other non-post taxonomies
         if (array_intersect($tx_obj->object_type, get_post_types(array('public' => true)))) {
             $use_taxonomies = scoper_get_option('use_taxonomies');
             if (empty($use_taxonomies[$taxonomy])) {
                 return $results;
             }
         }
     }
     // no backend filter for administrators
     $parent_or = '';
     if (is_admin() || defined('XMLRPC_REQUEST')) {
         if (is_content_administrator_rs()) {
             return $results;
         } else {
             if ($tx = $scoper->taxonomies->get($taxonomies[0])) {
                 // is a Category Edit form being displayed?
                 if (!empty($tx->uri_vars)) {
                     $term_id = $scoper->data_sources->detect('id', $tx);
                 } else {
                     $term_id = $scoper->data_sources->detect('id', $tx->source);
                 }
                 if ($term_id) {
                     // don't filter current parent category out of selection UI even if current user can't manage it
                     $parent_or = " OR t.term_id = (SELECT parent FROM {$wpdb->term_taxonomy} WHERE term_id = '{$term_id}') ";
                 }
             }
         }
     }
     // need to skip cache retrieval if QTranslate is filtering get_terms with a priority of 1 or less
     static $no_cache;
     if (!isset($no_cache)) {
         $no_cache = defined('SCOPER_NO_TERMS_CACHE') || !defined('SCOPER_QTRANSLATE_COMPAT') && awp_is_plugin_active('qtranslate');
     }
     // this filter currently only supports a single taxonomy for each get_terms call
     // (although the terms_where filter does support multiple taxonomies and this function could be made to do so)
     if (!$single_taxonomy) {
         return $results;
     }
     // link category roles / restrictions are only scoped for management (TODO: abstract this)
     if ($single_taxonomy && 'link_category' == $taxonomies[0] && $scoper->is_front()) {
         return $results;
     }
     // depth is not really a get_terms arg, but remap exclude arg to exclude_tree if wp_list_terms called with depth=1
     if (!empty($args['exclude']) && empty($args['exclude_tree']) && !empty($args['depth']) && 1 == $args['depth']) {
         $args['exclude_tree'] = $args['exclude'];
     }
     // don't offer to set a category as its own parent
     if ('edit-tags.php' == $GLOBALS['pagenow']) {
         if ($tx_obj->hierarchical) {
             if ($editing_cat_id = $scoper->data_sources->get_from_uri('id', 'term')) {
                 if (!empty($args['exclude'])) {
                     $args['exclude'] .= ',';
                 }
                 $args['exclude'] .= $editing_cat_id;
             }
         }
     }
     // we'll need this array in most cases, to support a disjointed tree with some parents missing (note alternate function call - was _get_term_hierarchy)
     $children = ScoperAncestry::get_terms_children($taxonomies[0]);
     //
     // === END Role Scoper ADDITION ===
     // =================================
     $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' => '', 'skip_teaser' => false, 'depth' => 0, 'remap_parents' => -1, 'enforce_actual_depth' => -1, 'remap_thru_excluded_parent' => -1, 'post_type' => '');
     // Role Scoper arguments added above
     $args = wp_parse_args($args, $defaults);
     $args['number'] = (int) $args['number'];
     $args['offset'] = absint($args['offset']);
     $args['child_of'] = (int) $args['child_of'];
     // Role Scoper modification: null value will confuse children array check
     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);
     // === BEGIN Role Scoper MODIFICATION: use the $children array we already have ===
     //
     if ('nav-menus.php' == $GLOBALS['pagenow']) {
         if ('nav_menu' != $taxonomies[0]) {
             if (!scoper_get_option('admin_nav_menu_filter_items')) {
                 return $results;
             } else {
                 $hide_empty = 1;
             }
         }
     }
     if ($child_of && !isset($children[$child_of])) {
         return array();
     }
     if ($parent && !isset($children[$parent])) {
         return array();
     }
     if ($post_type && is_string($post_type)) {
         $post_type = explode(',', $post_type);
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     $is_term_admin = in_array($GLOBALS['pagenow'], array('edit-tags.php', 'edit-link-categories.php'));
     $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);
     // === BEGIN Role Scoper MODIFICATION: cache key specific to access type and user/groups ===
     // support Quick Post Widget plugin
     if (isset($name) && 'quick_post_cat' == $name) {
         $required_operation = 'edit';
         $post_type = 'post';
         $remap_parents = true;
     } elseif (isset($name) && 'quick_post_new_cat_parent' == $name) {
         $is_term_admin = true;
         $required_operation = '';
         $remap_parents = true;
     } else {
         $required_operation = '';
     }
     $object_src_name = $scoper->taxonomies->member_property($taxonomies[0], 'object_source', 'name');
     $ckey = md5($key . serialize($scoper->get_terms_reqd_caps($taxonomies[0], $required_operation, $is_term_admin)));
     global $current_rs_user;
     $cache_flag = 'rs_get_terms';
     $cache = $current_rs_user->cache_get($cache_flag);
     if (false !== $cache) {
         if (!is_array($cache)) {
             $cache = array();
         }
         if (!$no_cache && isset($cache[$ckey])) {
             // RS Modification: alternate filter name (get_terms filter is already applied by WP)
             remove_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
             $terms = apply_filters('get_terms', $cache[$ckey], $taxonomies, $args);
             $terms = apply_filters('get_terms_rs', $terms, $taxonomies, $args);
             add_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
             return $terms;
         }
     }
     // buffer term names in case they were filtered previously
     if ('all' == $fields) {
         $term_names = scoper_get_property_array($results, 'term_id', 'name');
     }
     //
     // === END Role Scoper MODIFICATION ===
     // =====================================
     $_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 = '';
                         $order = '';
                     } else {
                         if (empty($_orderby) || 'id' == $_orderby) {
                             $orderby = 't.term_id';
                         } elseif ('order' == $_orderby) {
                             $orderby = 't.term_order';
                         } else {
                             $orderby = 't.name';
                         }
                     }
                 }
             }
         }
     }
     $orderby = apply_filters('get_terms_orderby', $orderby, $args);
     if (!empty($orderby)) {
         $orderby = "ORDER BY {$orderby}";
     }
     $where = '';
     // === Role Scoper MODIFICATION: if an include argument is provided, strip out non-matching terms after filtering is done. ===
     /*
     $inclusions = '';
     if ( !empty($include) ) {
     	$exclude = '';
     	$exclude_tree = '';
     	$interms = wp_parse_id_list($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;
     */
     // === END Role Scoper MODIFICATION ===
     $exclusions = '';
     if (!empty($exclude_tree)) {
         // === BEGIN Role Scoper MODIFICATION: temporarily unhook this filter for unfiltered get_terms calls ===
         remove_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
         // === END Role Scoper MODIFICATION ===
         $excluded_trunks = wp_parse_id_list($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 ($excluded_children as $exterm) {
                 if (empty($exclusions)) {
                     $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
                 } else {
                     $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
                 }
             }
         }
         // === BEGIN Role Scoper MODIFICATION: re-hook this filter
         add_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
         // === END Role Scoper MODIFICATION ===
     }
     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 .= ')';
     }
     // WPML attempts to pull taxonomy out of debug_backtrace() unless set in $_GET or $_POST; previous filter execution throws it off
     if (defined('ICL_SITEPRESS_VERSION') && !isset($_GET['taxonomy'])) {
         $_GET['taxonomy'] = current($taxonomies);
     }
     $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;
         // === BEGIN Role Scoper MODIFICATION: otherwise termroles only work if parent terms also have role
         if ($parent || 'ids' != $fields) {
             $where .= " AND tt.parent = '{$parent}'";
         }
         // === END Role Scoper MODIFICATION ===
     }
     // === BEGIN Role Scoper MODIFICATION: instead, manually remove truly empty cats at the bottom of this function, so we don't exclude cats with private but readable posts
     //if ( $hide_empty && !$hierarchical )
     //	$where .= ' AND tt.count > 0';
     // === END Role Scoper MODIFICATION ===
     // 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.term_taxonomy_id', 'tt.parent', 'tt.count');
             break;
         case 'names':
             $selects = array('t.term_id', 'tt.term_taxonomy_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));
     // === BEGIN Role Scoper MODIFICATION: run the query through scoping filter
     //
     $query_base = "SELECT DISTINCT {$select_this} FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE 1=1 AND tt.taxonomy IN ({$in_taxonomies}) {$where} {$parent_or} {$orderby} {$order} {$limit}";
     // only force application of scoped query filter if we're NOT doing a teaser
     if ('all' == $fields) {
         $do_teaser = $scoper->is_front() && empty($skip_teaser) && scoper_get_otype_option('do_teaser', 'post');
     } else {
         $do_teaser = false;
     }
     $query = apply_filters('terms_request_rs', $query_base, $taxonomies[0], array('skip_teaser' => !$do_teaser, 'is_term_admin' => $is_term_admin, 'required_operation' => $required_operation, 'post_type' => $post_type));
     // if no filering was applied because the teaser is enabled, prevent a redundant query
     if (!empty($exclude_tree) || $query_base != $query || $parent || 'all' != $fields) {
         $terms = scoper_get_results($query);
     } else {
         $terms = $results;
     }
     if ('count' == $fields) {
         $term_count = $wpdb->get_var($query);
         return $term_count;
     }
     if ('all' == $fields && empty($include)) {
         update_term_cache($terms);
     }
     // RS: don't cache an empty array, just in case something went wrong
     if (empty($terms)) {
         return array();
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     // === BEGIN Role Scoper ADDITION: Support a disjointed terms tree with some parents hidden
     //
     if ('all' == $fields) {
         $ancestors = ScoperAncestry::get_term_ancestors($taxonomy);
         // array of all ancestor IDs for keyed term_id, with direct parent first
         if ($parent > 0 || !$hierarchical) {
             // in Category Edit form, need to list all editable cats even if parent is not editable
             $remap_parents = false;
             $enforce_actual_depth = true;
             $remap_thru_excluded_parent = false;
         } else {
             // if these settings were passed into this get_terms call, use them
             if (is_admin()) {
                 $remap_parents = true;
             } else {
                 if (-1 === $remap_parents) {
                     $remap_parents = scoper_get_option('remap_term_parents');
                 }
                 if ($remap_parents) {
                     if (-1 === $enforce_actual_depth) {
                         $enforce_actual_depth = scoper_get_option('enforce_actual_term_depth');
                     }
                     if (-1 === $remap_thru_excluded_parent) {
                         $remap_thru_excluded_parent = scoper_get_option('remap_thru_excluded_term_parent');
                     }
                 }
             }
         }
         $remap_args = compact('child_of', 'parent', 'depth', 'orderby', 'remap_parents', 'enforce_actual_depth', 'remap_thru_excluded_parent');
         // one or more of these args may have been modified after extraction
         ScoperHardway::remap_tree($terms, $ancestors, 'term_id', 'parent', $remap_args);
     }
     //
     // === END Role Scoper ADDITION ===
     // ================================
     // === BEGIN Role Scoper MODIFICATION: call alternate functions
     // rs_tally_term_counts() replaces _pad_term_counts()
     // rs_get_term_descendants replaces _get_term_children()
     //
     if (($child_of || $hierarchical) && !empty($children)) {
         $terms = rs_get_term_descendants($child_of, $terms, $taxonomies[0]);
     }
     if (!$terms) {
         return array();
     }
     // Replace DB-stored term counts with actual number of posts this user can read.
     // In addition, without the rs_tally_term_counts call, WP will hide categories that have no public posts (even if this user can read some of the pvt posts).
     // Post counts will be incremented to include child categories only if $pad_counts is true
     if (!defined('XMLRPC_REQUEST') && in_array($fields, array('all', 'ids', 'names')) && !$is_term_admin) {
         if (!is_admin() || !in_array($GLOBALS['pagenow'], array('post.php', 'post-new.php'))) {
             //-- RoleScoper Modification - alternate function call (was _pad_term_counts) --//
             rs_tally_term_counts($terms, $taxonomies[0], array('pad_counts' => $pad_counts, 'skip_teaser' => !$do_teaser, 'post_type' => $post_type));
         }
     }
     // Make sure we show empty categories that have children.
     if ($hierarchical && $hide_empty) {
         foreach ($terms as $k => $term) {
             if (!$term->count) {
                 //-- RoleScoper Modification - call alternate function (was _get_term_children) --//
                 if ($children = rs_get_term_descendants($term->term_id, $terms, $taxonomies[0])) {
                     foreach ($children as $child) {
                         if ($child->count) {
                             continue 2;
                         }
                     }
                 }
                 // It really is empty
                 unset($terms[$k]);
             }
         }
     }
     reset($terms);
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     // === BEGIN Role Scoper ADDITION: hide empty cats based on actual query result instead of 'count > 0' clause, so we don't exclude cats with private but readable posts
     if ($terms && empty($hierarchical) && !empty($hide_empty)) {
         foreach ($terms as $key => $term) {
             if (!$term->count) {
                 unset($terms[$key]);
             }
         }
     }
     //
     // === END Role Scoper ADDITION ===
     // ================================
     if (!empty($include)) {
         $interms = wp_parse_id_list($include);
         foreach ($terms as $key => $term) {
             if (!in_array($term->term_id, $interms)) {
                 unset($terms[$key]);
             }
         }
     }
     $_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);
     }
     // === BEGIN Role Scoper MODIFICATION: cache key is specific to user/group
     //
     if (!$no_cache) {
         $cache[$ckey] = $terms;
         $current_rs_user->cache_set($cache, $cache_flag);
     }
     // RS Modification: alternate filter name (get_terms filter is already applied by WP)
     remove_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
     $terms = apply_filters('get_terms', $terms, $taxonomies, $args);
     $terms = apply_filters('get_terms_rs', $terms, $taxonomies, $args);
     add_filter('get_terms', array('ScoperHardwayTaxonomy', 'flt_get_terms'), 0, 3);
     // restore buffered term names in case they were filtered previously
     if ('all' == $fields) {
         scoper_restore_property_array($terms, $term_names, 'term_id', 'name');
     }
     //
     // === END Role Scoper MODIFICATION ===
     // ====================================
     //dump($terms);
     return $terms;
 }
 /**
  * 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;
 }
Example #9
0
 /**
  * Retrieve the terms in a given taxonomy or list of taxonomies.
  *
  * NOTE: This is the Connections equivalent of @see get_terms() in WordPress core ../wp-includes/taxonomy.php
  *
  * Filters:
  *    cn_get_terms_atts - The method variables.
  *        Passes: (array) $atts, (array) $taxonomies
  *        Return: $atts
  *
  *    cn_get_terms_fields - The fields for the SELECT query clause.
  *        Passes: (array) $select, (array) $atts, (array) $taxonomies
  *        Return: $select
  *
  *    cn_term_inclusions - Query clause which includes terms.
  *        Passes: (string) $inclusions, (array) $atts, (array) $taxonomies
  *        Return: $inclusions
  *
  *    cn_term_exclusions - Query clause which excludes terms.
  *        Passes: (string) $exclusions, (array) $atts, (array) $taxonomies
  *        Return: $exclusions
  *
  *    cn_term_orderby - The ORDER BY query clause.
  *        Passes: (string) $orderBy, (array) $atts, (array) $taxonomies
  *        Return: $orderBy
  *
  *    cn_terms_clauses - An array containing the the query clause segments.
  *        Passes: (array) $pieces, (array) $taxonomies, (array) $atts
  *        Return: $pieces
  *
  * Accepted option for the $atts property are:
  *
  *    get ( string )
  *        Default: ''
  *        Valid:   all
  *        If set to 'all' instead of its default empty string,
  *        returns terms regardless of ancestry or whether the terms are empty.
  *
  *    fields ( string )
  *        Default: 'all'
  *        Valid:   all | ids | id=>parent | names | count | id=>name | id=>slug
  *        Default is 'all', which returns an array of term objects.
  *        If 'fields' is 'ids' or 'names', returns an array of integers or strings, respectively.
  *
  *    include ( string | array )
  *        Default: array()
  *        Valid:   An indexed array, comma- or space-delimited string of term_id.
  *
  *    exclude_tree ( string | array )
  *        Default: array()
  *        Valid:   An indexed array, comma- or space-delimited string of term_id.
  *        If 'include' is non-empty, 'exclude_tree' is ignored.
  *
  *    exclude ( string | array )
  *        Default: array()
  *        Valid:   An indexed array, comma- or space-delimited string of term_id.
  *        If 'include' is non-empty, 'exclude' is ignored.
  *
  *    slug ( string | array  )
  *        Default: ''
  *        Slug or array of slugs to return term(s) for.
  *
  *    hide_empty ( bool )
  *        Default: TRUE
  *        Will not return empty terms, which means terms whose count is 0.
  *
  *    hierarchical ( bool )
  *        Default: TRUE
  *        Whether to include terms that have non-empty descendants, even if 'hide_empty' is set to TRUE.
  *
  *    orderby ( string | array )
  *        Default: name
  *        Valid:   term_id | name | slug | term_group | parent | count | include
  *
  *    order ( string | array )
  *        Default: ASC
  *        Valid:   ASC | DESC
  *
  *    number ( int )
  *        Default: 0
  *        The maximum number of terms to return. Default is to return them all.
  *
  *    offset ( int )
  *        Default: 0
  *        The number by which to offset the terms query.
  *
  *    search ( string )
  *        Default: ''
  *        Returned terms' names will contain the value of 'search', case-insensitive.
  *
  *    name__like ( string )
  *        Default: ''
  *        Return terms' names will contain the value of 'name__like', case-insensitive.
  *
  *    description__like ( string )
  *        Default: ''
  *        Return terms' descriptions will contain the value of 'description__like', case-insensitive.
  *
  *    child_of ( int )
  *        Default: 0
  *        The 'child_of' argument, when used, should be set to the integer of a term ID.
  *        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.
  *
  *    parent ( string | int )
  *        Default: ''
  *        The integer of a term ID.
  *        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.
  *
  *    pad_counts ( bool )
  *        Default: FALSE
  *        If set to true, include the quantity of a term's children
  *        in the quantity of each term's 'count' property.
  *
  * @access public
  * @since  8.1
  * @static
  *
  * @global $wpdb
  *
  * @param  string|array $taxonomies Taxonomy name or array of taxonomy names.
  * @param  array        $atts
  *
  * @uses   apply_filters()
  * @uses   wp_parse_args()
  * @uses   wp_parse_id_list()
  * @uses   sanitize_title()
  * @uses   wpdb::prepare()
  * @uses   $wpdb::esc_like()
  * @uses   absint()
  * @uses   wpdb::get_results()
  * @uses   cnTerm::filter()
  * @uses   cnTerm::descendants()
  * @uses   cnTerm::childrenIDs()
  * @uses   cnTerm::padCounts()
  * @uses   cnTerm::children()
  *
  * @return array|WP_Error Indexed array of term objects. Will return WP_Error, if any of $taxonomies do not exist.*
  */
 public static function getTaxonomyTerms($taxonomies = array('category'), $atts = array())
 {
     /** @var $wpdb wpdb */
     global $wpdb;
     $select = array();
     $where = array();
     $orderBy = array();
     $orderByClause = '';
     /*
      * @TODO $taxonomies need to be checked against registered taxonomies.
      * Presently $taxonomies only support a string rather than array.
      * Additionally, category is the only supported taxonomy.
      */
     $single_taxonomy = !is_array($taxonomies) || 1 === count($taxonomies);
     if (!is_array($taxonomies)) {
         $taxonomies = array($taxonomies);
     }
     $defaults = array('get' => '', 'orderby' => 'name', 'order' => 'ASC', 'hide_empty' => TRUE, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(), 'fields' => 'all', 'slug' => '', 'parent' => '', 'hierarchical' => TRUE, 'child_of' => 0, 'name__like' => '', 'meta_query' => array(), 'pad_counts' => FALSE, 'offset' => 0, 'number' => 0, 'search' => '');
     /**
      * Filter the terms query arguments.
      *
      * @since 8.1
      *
      * @param array        $atts       An array of arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $atts = apply_filters('cn_get_terms_args', $atts, $taxonomies);
     $atts = wp_parse_args($atts, $defaults);
     // @TODO Implement is_taxonomy_hierarchical().
     if (!$single_taxonomy || '' !== $atts['parent'] && 0 !== $atts['parent']) {
         $atts['child_of'] = 0;
         $atts['hierarchical'] = FALSE;
         $atts['pad_counts'] = FALSE;
     }
     if ('all' == $atts['get']) {
         $atts['child_of'] = 0;
         $atts['hide_empty'] = 0;
         $atts['hierarchical'] = FALSE;
         $atts['pad_counts'] = FALSE;
     }
     if ($atts['child_of']) {
         $hierarchy = self::childrenIDs(reset($taxonomies));
         if (!isset($hierarchy[$atts['child_of']])) {
             return array();
         }
     }
     if ($atts['parent']) {
         $hierarchy = self::childrenIDs(reset($taxonomies));
         if (!isset($hierarchy[$atts['parent']])) {
             return array();
         }
     }
     // $args can be whatever, only use the args defined in defaults to compute the key
     $filter_key = has_filter('cn_term_exclusions') ? serialize($GLOBALS['wp_filter']['cn_term_exclusions']) : '';
     $key = md5(serialize(wp_array_slice_assoc($atts, array_keys($defaults))) . serialize($taxonomies) . $filter_key);
     $last_changed = wp_cache_get('last_changed', 'cn_terms');
     if (!$last_changed) {
         $last_changed = microtime();
         wp_cache_set('last_changed', $last_changed, 'cn_terms');
     }
     $cache_key = "cn_get_terms:{$key}:{$last_changed}";
     $cache = wp_cache_get($cache_key, 'cn_terms');
     if (FALSE !== $cache) {
         /**
          * Filter the given taxonomy's terms cache.
          *
          * @since 8.1.6
          *
          * @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('cn_terms', $cache, $taxonomies, $atts);
         return $cache;
     }
     /*
      * Construct the ORDER By query clause.
      */
     if (is_array($atts['orderby'])) {
         foreach ($atts['orderby'] as $i => $value) {
             if (!isset($order)) {
                 $order = 'ASC';
             }
             switch ($value) {
                 case 'id':
                 case 'term_id':
                     $orderField = 't.term_id';
                     break;
                 case 'slug':
                     $orderField = 't.slug';
                     break;
                 case 'include':
                     $include = implode(',', wp_parse_id_list($atts['include']));
                     $orderField = "FIELD( t.term_id, {$include} )";
                     break;
                 case 'term_group':
                     $orderField = 't.term_group';
                     break;
                 case 'none':
                     $orderField = '';
                     // If an `none` order field was supplied, break out of both the switch and foreach statements.
                     break 2;
                 case 'parent':
                     $orderField = 'tt.parent';
                     break;
                 case 'count':
                     $orderField = 'tt.count';
                     break;
                 default:
                     $orderField = 't.name';
                     break;
             }
             // Set the $order to align with $atts['orderby'].
             if (is_array($atts['order']) && isset($atts['order'][$i])) {
                 $order = $atts['order'][$i];
                 // If an aligned $atts['order'] does not exist use the last $order set otherwise use $atts['order'].
             } else {
                 $order = is_array($atts['order']) ? $order : $atts['order'];
             }
             $order = strtoupper($order);
             $order = in_array($order, array('ASC', 'DESC')) ? $order : 'ASC';
             $orderBy[] = sprintf('%s %s', $orderField, $order);
         }
         // The @var $value will be set to the last value from the $atts['orderby'] foreach loop.
         // If a `none` $atts['orderby'] was found in the supplied array, no order by clause will be set.
         if (!empty($orderBy) && $value != 'none') {
             $orderByClause = 'ORDER BY ' . implode(', ', $orderBy);
         }
     } else {
         switch ($atts['orderby']) {
             case 'id':
             case 'term_id':
                 $atts['orderby'] = 't.term_id';
                 break;
             case 'slug':
                 $atts['orderby'] = 't.slug';
                 break;
             case 'include':
                 $include = implode(',', wp_parse_id_list($atts['include']));
                 $atts['orderby'] = "FIELD( t.term_id, {$include} )";
                 break;
             case 'term_group':
                 $atts['orderby'] = 't.term_group';
                 break;
             case 'none':
                 $atts['orderby'] = '';
                 break;
             case 'parent':
                 $atts['orderby'] = 'tt.parent';
                 break;
             case 'count':
                 $atts['orderby'] = 'tt.count';
                 break;
             default:
                 $atts['orderby'] = 't.name';
                 break;
         }
         if (is_array($atts['order'])) {
             // $atts['orderby'] was a string but an array was passed for $atts['order'], assume the 0 index.
             $order = $atts['order'][0];
         } else {
             $order = $atts['order'];
         }
         if (!empty($atts['orderby'])) {
             $order = strtoupper($order);
             $order = in_array($order, array('ASC', 'DESC')) ? $order : 'ASC';
             $orderByClause = 'ORDER BY ' . sprintf('%s %s', $atts['orderby'], $order);
         }
     }
     /*
      * Filter the ORDER BY clause of the terms query.
      *
      * @since 8.1
      *
      * @param string       $orderBy    ORDER BY clause of the terms query.
      * @param array        $atts       An array of terms query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $orderBy = apply_filters('cn_terms_orderby', $orderByClause, $atts, $taxonomies);
     /*
      * Start construct the WHERE query clause.
      */
     $where[] = 'tt.taxonomy IN (\'' . implode('\', \'', $taxonomies) . '\')';
     /*
      * Define the included terms.
      */
     $inclusions = '';
     if (!empty($atts['include'])) {
         $atts['exclude'] = '';
         $atts['exclude_tree'] = '';
         $inclusions = implode(',', wp_parse_id_list($atts['include']));
     }
     if (!empty($inclusions)) {
         $inclusions = 'AND t.term_id IN ( ' . $inclusions . ' )';
     }
     /**
      * Filter the terms to be included in the terms query.
      *
      * @since 8.1
      *
      * @param string       $inclusions IN clause of the terms query.
      * @param array        $atts       An array of terms query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $inclusions = apply_filters('cn_term_inclusions', $inclusions, $atts, $taxonomies);
     if (!empty($inclusions)) {
         $where[] = $inclusions;
     }
     /*
      * Define the excluded terms.
      */
     $exclusions = '';
     if (!empty($atts['exclude_tree'])) {
         $atts['exclude_tree'] = wp_parse_id_list($atts['exclude_tree']);
         $excluded_children = $atts['exclude_tree'];
         foreach ($atts['exclude_tree'] as $extrunk) {
             $excluded_children = array_merge($excluded_children, (array) cnTerm::getTaxonomyTerms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids', 'hide_empty' => 0)));
         }
         $exclusions = implode(',', array_map('intval', $excluded_children));
     }
     if (!empty($atts['exclude'])) {
         $exterms = wp_parse_id_list($atts['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 8.1
      *
      * @param string       $exclusions NOT IN clause of the terms query.
      * @param array        $atts       An array of terms query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $exclusions = apply_filters('cn_term_exclusions', $exclusions, $atts, $taxonomies);
     if (!empty($exclusions)) {
         $where[] = $exclusions;
     }
     if (!empty($atts['slug'])) {
         if (is_array($atts['slug'])) {
             $slug = array_map('sanitize_title', $atts['slug']);
             $where[] = " AND t.slug IN ('" . implode("', '", $slug) . "')";
         } else {
             $slug = sanitize_title($atts['slug']);
             $where[] = " AND t.slug = '{$slug}'";
         }
     }
     if (!empty($atts['name__like'])) {
         //$atts['name__like'] = like_escape( $atts['name__like'] );
         $where[] = $wpdb->prepare(" AND t.name LIKE %s", '%' . $wpdb->esc_like($atts['name__like']) . '%');
         //$where[]            = $wpdb->prepare( 'AND t.name LIKE %s', '%' . $atts['name__like'] . '%' );
     }
     if (!empty($atts['description__like'])) {
         //$atts['description__like'] = like_escape( $atts['description__like'] );
         $where[] = $wpdb->prepare(" AND tt.description LIKE %s", '%' . $wpdb->esc_like($atts['description__like']) . '%');
         //$where[]                   = $wpdb->prepare( 'AND tt.description LIKE %s', '%' . $atts['description__like'] . '%' );
     }
     if ('' !== $atts['parent']) {
         $where[] = $wpdb->prepare('AND tt.parent = %d', $atts['parent']);
     }
     if ('count' == $atts['fields']) {
         $atts['hierarchical'] = FALSE;
     }
     if ($atts['hide_empty'] && !$atts['hierarchical']) {
         $where[] = 'AND tt.count > 0';
     }
     // Do not limit the query results when we have to descend the family tree.
     if ($atts['number'] && !$atts['hierarchical'] && !$atts['child_of'] && '' === $atts['parent']) {
         $atts['number'] = absint($atts['number']);
         $atts['offset'] = absint($atts['offset']);
         if ($atts['offset']) {
             $limit = $wpdb->prepare('LIMIT %d,%d', $atts['offset'], $atts['number']);
         } else {
             $limit = $wpdb->prepare('LIMIT %d', $atts['number']);
         }
     } else {
         $limit = '';
     }
     if (!empty($atts['search'])) {
         //$atts['search'] = like_escape( $atts['search'] );
         $atts['search'] = $wpdb->esc_like($atts['search']);
         $where[] = $wpdb->prepare('AND ( (t.name LIKE %s) OR (t.slug LIKE %s) )', '%' . $atts['search'] . '%', '%' . $atts['search'] . '%');
     }
     switch ($atts['fields']) {
         case 'all':
             $select = array('t.*', 'tt.*');
             break;
         case 'ids':
         case 'id=>parent':
             $select = array('t.term_id', 'tt.parent', 'tt.count');
             break;
         case 'names':
             $select = array('t.term_id', 'tt.parent', 'tt.count', 't.name');
             break;
         case 'count':
             $orderBy = '';
             //$order   = '';
             $select = array('COUNT(*)');
             break;
         case 'id=>name':
             $select = array('t.term_id', 't.name');
             break;
         case 'id=>slug':
             $select = array('t.term_id', 't.slug');
             break;
     }
     /**
      * Filter the fields to select in the terms query.
      *
      * @since 8.1
      *
      * @param array        $select     An array of fields to select for the terms query.
      * @param array        $atts       An array of term query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $fields = implode(', ', apply_filters('cn_get_terms_fields', $select, $atts, $taxonomies));
     $join = 'INNER JOIN ' . CN_TERM_TAXONOMY_TABLE . ' AS tt ON t.term_id = tt.term_id';
     $pieces = array('fields', 'join', 'where', 'orderBy', 'limit');
     /**
      * Filter the terms query SQL clauses.
      *
      * @since 8.1
      *
      * @param array        $pieces     Terms query SQL clauses.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      * @param array        $atts       An array of terms query arguments.
      */
     $clauses = apply_filters('cn_terms_clauses', compact($pieces), $taxonomies, $atts);
     foreach ($pieces as $piece) {
         ${$piece} = isset($clauses[$piece]) ? $clauses[$piece] : '';
     }
     $sql = sprintf('SELECT %1$s FROM %2$s AS t %3$s WHERE %4$s %5$s%6$s', $fields, CN_TERMS_TABLE, $join, implode(' ', $where), $orderBy, empty($limit) ? '' : ' ' . $limit);
     if ('count' == $atts['fields']) {
         $term_count = $wpdb->get_var($sql);
         return $term_count;
     }
     $terms = $wpdb->get_results($sql);
     if ('all' == $atts['fields']) {
         foreach ($taxonomies as $taxonomy) {
             update_term_cache($terms, 'cn_' . $taxonomy);
         }
     }
     if (empty($terms)) {
         wp_cache_add($cache_key, array(), 'cn_terms', DAY_IN_SECONDS);
         $terms = apply_filters('cn_terms', array(), $taxonomies, $atts);
         return $terms;
     }
     if ($atts['child_of']) {
         $children = self::childrenIDs(reset($taxonomies));
         if (!empty($children)) {
             $terms = self::descendants($atts['child_of'], $terms, reset($taxonomies));
         }
     }
     /*
      * @todo Add method to adjust counts based on user visibility permissions.
      */
     // Update term counts to include children.
     if ($atts['pad_counts'] && 'all' == $atts['fields']) {
         self::padCounts($terms, reset($taxonomies));
     }
     // Make sure we show empty categories that have children.
     if ($atts['hierarchical'] && $atts['hide_empty'] && is_array($terms)) {
         foreach ($terms as $k => $term) {
             if (!$term->count) {
                 $children = self::children($term->term_id, reset($taxonomies));
                 if (is_array($children)) {
                     foreach ($children as $child_id) {
                         $child = self::filter($child_id, reset($taxonomies));
                         if ($child->count) {
                             continue 2;
                         }
                     }
                 }
                 // It really is empty
                 unset($terms[$k]);
             }
         }
     }
     reset($terms);
     $_terms = array();
     if ('id=>parent' == $atts['fields']) {
         while ($term = array_shift($terms)) {
             $_terms[$term->term_id] = $term->parent;
         }
     } elseif ('ids' == $atts['fields']) {
         while ($term = array_shift($terms)) {
             $_terms[] = $term->term_id;
         }
     } elseif ('names' == $atts['fields']) {
         while ($term = array_shift($terms)) {
             $_terms[] = $term->name;
         }
     } elseif ('id=>name' == $atts['fields']) {
         while ($term = array_shift($terms)) {
             $_terms[$term->term_id] = $term->name;
         }
     } elseif ('id=>slug' == $atts['fields']) {
         while ($term = array_shift($terms)) {
             $_terms[$term->term_id] = $term->slug;
         }
     }
     if (!empty($_terms)) {
         $terms = $_terms;
     }
     if ($atts['number'] && is_array($terms) && count($terms) > $atts['number']) {
         $terms = array_slice($terms, $atts['offset'], $atts['number']);
     }
     wp_cache_add($cache_key, $terms, 'cn_terms', DAY_IN_SECONDS);
     $terms = apply_filters('cn_terms', $terms, $taxonomies, $atts);
     return $terms;
 }
 /**
  * @ticket 35462
  */
 public function test_term_objects_should_not_be_modified_by_update_term_cache()
 {
     register_taxonomy('wptests_tax', 'post');
     $t = self::factory()->term->create(array('taxonomy' => 'wptests_tax'));
     $p = self::factory()->post->create();
     wp_set_object_terms($p, $t, 'wptests_tax');
     $terms = wp_get_object_terms($p, 'wptests_tax', array('fields' => 'all_with_object_id'));
     update_term_cache($terms);
     foreach ($terms as $term) {
         $this->assertSame($p, $term->object_id);
     }
 }
Example #11
0
 /**
  * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
  *
  * The following information has to do the $args parameter and for what can be
  * contained in the string or array of that parameter, if it exists.
  *
  * The first argument is called, 'orderby' and has the default value of 'name'.
  * The other value that is supported is 'count'.
  *
  * The second argument is called, 'order' and has the default value of 'ASC'.
  * The only other value that will be acceptable is 'DESC'.
  *
  * The final argument supported is called, 'fields' and has the default value of
  * 'all'. There are multiple other options that can be used instead. Supported
  * values are as follows: 'all', 'ids', 'names', and finally
  * 'all_with_object_id'.
  *
  * The fields argument also decides what will be returned. If 'all' or
  * 'all_with_object_id' is chosen or the default kept intact, then all matching
  * terms objects will be returned. If either 'ids' or 'names' is used, then an
  * array of all matching term ids or term names will be returned respectively.
  *
  * @see  wp_get_object_terms()
  * @uses $wpdb
  *
  * @param int|array    $object_ids The ID(s) of the object(s) to retrieve.
  * @param string|array $taxonomies The taxonomies to retrieve terms from.
  * @param array|string $args       Change what is returned
  *
  * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if $taxonomy does not exist.
  */
 function get_gmedia_terms($object_ids, $taxonomies, $args = array())
 {
     /** @var $wpdb wpdb */
     global $wpdb;
     $gmOptions = get_option('gmediaOptions');
     if (!is_array($taxonomies)) {
         $taxonomies = array($taxonomies);
     }
     foreach ((array) $taxonomies as $taxonomy) {
         if (!isset($gmOptions['taxonomies'][$taxonomy])) {
             return new WP_Error('gm_invalid_taxonomy', __('Invalid Taxonomy'));
         }
     }
     if (!is_array($object_ids)) {
         $object_ids = array($object_ids);
     }
     $object_ids = array_map('intval', $object_ids);
     $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all', 'unique' => true);
     $args = wp_parse_args($args, $defaults);
     $terms = array();
     /** @var $orderby
      * @var  $order
      * @var  $fields
      * @var  $unique
      */
     extract($args, EXTR_SKIP);
     if ($unique) {
         $groupby = 'GROUP BY t.term_id';
     } else {
         $groupby = '';
     }
     if ('count' == $orderby) {
         $orderby = 't.count';
     } else {
         if ('name' == $orderby) {
             $orderby = 't.name';
         } else {
             if ('global' == $orderby) {
                 $orderby = 't.global';
             } else {
                 if ('term_order' == $orderby) {
                     $orderby = 'tr.term_order';
                 } else {
                     if ('none' == $orderby) {
                         $orderby = '';
                         $order = '';
                     } else {
                         $orderby = 't.term_id';
                     }
                 }
             }
         }
     }
     if (!empty($orderby)) {
         $orderby = "ORDER BY {$orderby}";
     }
     $taxonomies = "'" . implode("', '", $taxonomies) . "'";
     $object_ids = implode(', ', $object_ids);
     $select_this = '';
     if ('all' == $fields) {
         $select_this = 't.*';
     } else {
         if ('ids' == $fields) {
             $select_this = 't.term_id';
         } else {
             if ('names' == $fields) {
                 $select_this = 't.name';
             } else {
                 if ('all_with_object_id' == $fields) {
                     $select_this = 't.*, tr.gmedia_id';
                     $groupby = '';
                 }
             }
         }
     }
     $query = "SELECT {$select_this} FROM {$wpdb->prefix}gmedia_term AS t INNER JOIN {$wpdb->prefix}gmedia_term_relationships AS tr ON tr.gmedia_term_id = t.term_id WHERE t.taxonomy IN ({$taxonomies}) AND tr.gmedia_id IN ({$object_ids}) {$groupby} {$orderby} {$order}";
     if ('all' == $fields || 'all_with_object_id' == $fields) {
         $terms = array_merge($terms, $wpdb->get_results($query));
         // todo ? maybe move function to plugin core
         update_term_cache($terms);
     } else {
         if ('ids' == $fields || 'names' == $fields) {
             $terms = array_merge($terms, $wpdb->get_col($query));
         }
     }
     if (!$terms) {
         $terms = array();
     }
     return apply_filters('get_gmedia_terms', $terms, $object_ids, $taxonomies, $args);
 }
Example #12
0
/**
 * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
 *
 * The following information has to do the $args parameter and for what can be
 * contained in the string or array of that parameter, if it exists.
 *
 * The first argument is called, 'orderby' and has the default value of 'name'.
 * The other value that is supported is 'count'.
 *
 * The second argument is called, 'order' and has the default value of 'ASC'.
 * The only other value that will be acceptable is 'DESC'.
 *
 * The final argument supported is called, 'fields' and has the default value of
 * 'all'. There are multiple other options that can be used instead. Supported
 * values are as follows: 'all', 'ids', 'names', and finally
 * 'all_with_object_id'.
 *
 * The fields argument also decides what will be returned. If 'all' or
 * 'all_with_object_id' is chosen or the default kept intact, then all matching
 * terms objects will be returned. If either 'ids' or 'names' is used, then an
 * array of all matching term ids or term names will be returned respectively.
 *
 * @package WordPress
 * @subpackage Taxonomy
 * @since 2.3.0
 * @uses $wpdb
 *
 * @param int|array $object_ids The ID(s) of the object(s) to retrieve.
 * @param string|array $taxonomies The taxonomies to retrieve terms from.
 * @param array|string $args Change what is returned
 * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if any of the $taxonomies don't exist.
 */
function wp_get_object_terms($object_ids, $taxonomies, $args = array())
{
    global $wpdb;
    if (empty($object_ids) || empty($taxonomies)) {
        return array();
    }
    if (!is_array($taxonomies)) {
        $taxonomies = array($taxonomies);
    }
    foreach ((array) $taxonomies as $taxonomy) {
        if (!taxonomy_exists($taxonomy)) {
            return new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
        }
    }
    if (!is_array($object_ids)) {
        $object_ids = array($object_ids);
    }
    $object_ids = array_map('intval', $object_ids);
    $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
    $args = wp_parse_args($args, $defaults);
    $terms = array();
    if (count($taxonomies) > 1) {
        foreach ($taxonomies as $index => $taxonomy) {
            $t = get_taxonomy($taxonomy);
            if (isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args)) {
                unset($taxonomies[$index]);
                $terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args)));
            }
        }
    } else {
        $t = get_taxonomy($taxonomies[0]);
        if (isset($t->args) && is_array($t->args)) {
            $args = array_merge($args, $t->args);
        }
    }
    extract($args, EXTR_SKIP);
    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 ('term_order' == $orderby) {
                        $orderby = 'tr.term_order';
                    } else {
                        if ('none' == $orderby) {
                            $orderby = '';
                            $order = '';
                        } else {
                            $orderby = 't.term_id';
                        }
                    }
                }
            }
        }
    }
    // tt_ids queries can only be none or tr.term_taxonomy_id
    if ('tt_ids' == $fields && !empty($orderby)) {
        $orderby = 'tr.term_taxonomy_id';
    }
    if (!empty($orderby)) {
        $orderby = "ORDER BY {$orderby}";
    }
    $order = strtoupper($order);
    if ('' !== $order && !in_array($order, array('ASC', 'DESC'))) {
        $order = 'ASC';
    }
    $taxonomies = "'" . implode("', '", $taxonomies) . "'";
    $object_ids = implode(', ', $object_ids);
    $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';
            } else {
                if ('slugs' == $fields) {
                    $select_this = 't.slug';
                } else {
                    if ('all_with_object_id' == $fields) {
                        $select_this = 't.*, tt.*, tr.object_id';
                    }
                }
            }
        }
    }
    $query = "SELECT {$select_this} FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.term_id = t.term_id INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ({$taxonomies}) AND tr.object_id IN ({$object_ids}) {$orderby} {$order}";
    if ('all' == $fields || 'all_with_object_id' == $fields) {
        $_terms = $wpdb->get_results($query);
        foreach ($_terms as $key => $term) {
            $_terms[$key] = sanitize_term($term, $taxonomy, 'raw');
        }
        $terms = array_merge($terms, $_terms);
        update_term_cache($terms);
    } else {
        if ('ids' == $fields || 'names' == $fields || 'slugs' == $fields) {
            $_terms = $wpdb->get_col($query);
            $_field = 'ids' == $fields ? 'term_id' : 'name';
            foreach ($_terms as $key => $term) {
                $_terms[$key] = sanitize_term_field($_field, $term, $term, $taxonomy, 'raw');
            }
            $terms = array_merge($terms, $_terms);
        } else {
            if ('tt_ids' == $fields) {
                $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM {$wpdb->term_relationships} AS tr INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ({$object_ids}) AND tt.taxonomy IN ({$taxonomies}) {$orderby} {$order}");
                foreach ($terms as $key => $tt_id) {
                    $terms[$key] = sanitize_term_field('term_taxonomy_id', $tt_id, 0, $taxonomy, 'raw');
                    // 0 should be the term id, however is not needed when using raw context.
                }
            }
        }
    }
    if (!$terms) {
        $terms = array();
    }
    return apply_filters('wp_get_object_terms', $terms, $object_ids, $taxonomies, $args);
}
Example #13
0
/**
 * Returns the terms associated with the given object(s), in the supplied taxonomies.
 * @param int|array $object_id The id of the object(s)) to retrieve for.
 * @param string|array $taxonomies The taxonomies to retrieve terms from.
 * @return array The requested term data.
 */
function wp_get_object_terms($object_ids, $taxonomies, $args = array())
{
    global $wpdb;
    if (!is_array($taxonomies)) {
        $taxonomies = array($taxonomies);
    }
    foreach ($taxonomies as $taxonomy) {
        if (!is_taxonomy($taxonomy)) {
            return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
        }
    }
    if (!is_array($object_ids)) {
        $object_ids = array($object_ids);
    }
    $object_ids = array_map('intval', $object_ids);
    $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
    $args = wp_parse_args($args, $defaults);
    extract($args, EXTR_SKIP);
    if ('count' == $orderby) {
        $orderby = 'tt.count';
    } else {
        if ('name' == $orderby) {
            $orderby = 't.name';
        }
    }
    $taxonomies = "'" . implode("', '", $taxonomies) . "'";
    $object_ids = implode(', ', $object_ids);
    if ('all' == $fields) {
        $select_this = 't.*, tt.*';
    } else {
        if ('ids' == $fields) {
            $select_this = 't.term_id';
        } else {
            if ('names' == $fields) {
                $select_this = 't.name';
            } else {
                if ('all_with_object_id' == $fields) {
                    $select_this = 't.*, tt.*, tr.object_id';
                }
            }
        }
    }
    $query = "SELECT {$select_this} FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.term_id = t.term_id INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ({$taxonomies}) AND tr.object_id IN ({$object_ids}) ORDER BY {$orderby} {$order}";
    if ('all' == $fields || 'all_with_object_id' == $fields) {
        $terms = $wpdb->get_results($query);
        update_term_cache($terms);
    } else {
        if ('ids' == $fields || 'names' == $fields) {
            $terms = $wpdb->get_col($query);
        } else {
            if ('tt_ids' == $fields) {
                $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM {$wpdb->term_relationships} AS tr INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ({$object_ids}) AND tt.taxonomy IN ({$taxonomies}) ORDER BY tr.term_taxonomy_id {$order}");
            }
        }
    }
    if (!$terms) {
        return array();
    }
    return $terms;
}
Example #14
0
 /**
  * Function called when query parameters are processed by Wordpress.
  * 
  * @param $query query parameters
  * @return array() $query processed
  *
  * @since 1.0
  */
 function filter_request($query)
 {
     global $q_config, $wp_query, $wp;
     if (isset($wp->matched_query)) {
         $query = wp_parse_args($wp->matched_query);
     }
     foreach (get_post_types() as $post_type) {
         if (array_key_exists($post_type, $query) && !in_array($post_type, array('post', 'page'))) {
             $query['post_type'] = $post_type;
         }
     }
     $page_foundit = false;
     // -> page
     if (isset($query['pagename']) || isset($query['page_id'])) {
         $page = wp_cache_get('qts_page_request');
         if (!$page) {
             $page = isset($query['page_id']) ? get_page($query['page_id']) : $this->get_page_by_path($query['pagename']);
         }
         if (!$page) {
             return $query;
         }
         $id = $page->ID;
         $cache_array = array($page);
         update_post_caches($cache_array, 'page');
         // caching query :)
         wp_cache_delete('qts_page_request');
         $query['pagename'] = get_page_uri($page);
         $function = 'get_page_link';
         // -> custom post type
     } elseif (isset($query['post_type'])) {
         $page_slug = isset($query['name']) && !empty($query['name']) ? $query['name'] : $query[$query['post_type']];
         $page = $this->get_page_by_path($page_slug, OBJECT, $query['post_type']);
         if (!$page) {
             return $query;
         }
         $id = $page->ID;
         $cache_array = array($page);
         update_post_caches($cache_array, $query['post_type']);
         // caching query :)
         $query['name'] = $query[$query['post_type']] = get_page_uri($page);
         $function = 'get_post_permalink';
         // -> post
     } elseif (isset($query['name']) || isset($query['p'])) {
         $post = isset($query['p']) ? get_post($query['p']) : $this->get_page_by_path($query['name'], OBJECT, 'post');
         if (!$post) {
             return $query;
         }
         $query['name'] = $post->post_name;
         $id = $post->ID;
         $cache_array = array($post);
         update_post_caches($cache_array);
         $function = 'get_permalink';
         // -> category
     } elseif (isset($query['category_name']) || isset($query['cat'])) {
         if (isset($query['category_name'])) {
             $term_slug = $this->get_last_slash($query['category_name']);
         }
         $term = isset($query['cat']) ? get_term($query['cat'], 'category') : $this->get_term_by('slug', $term_slug, 'category');
         if (!$term) {
             return $query;
         }
         $cache_array = array($term);
         update_term_cache($cache_array, 'category');
         // caching query :)
         $id = $term->term_id;
         $query['category_name'] = $term->slug;
         // uri
         $function = 'get_category_link';
         // -> tag
     } elseif (isset($query['tag'])) {
         $term = $this->get_term_by('slug', $query['tag'], 'post_tag');
         if (!$term) {
             return $query;
         }
         $cache_array = array($term);
         update_term_cache($cache_array, 'post_tag');
         // caching query :)
         $id = $term->term_id;
         $query['tag'] = $term->slug;
         $function = 'get_tag_link';
     }
     // -> taxonomy
     $taxonomies = get_taxonomies(array('public' => true, '_builtin' => false));
     foreach ($taxonomies as $term_name) {
         if (isset($query[$term_name])) {
             $term_slug = $this->get_last_slash($query[$term_name]);
             $term = $this->get_term_by('slug', $term_slug, $term_name);
             if (!$term) {
                 return $query;
             }
             $cache_array = array($term);
             update_term_cache($cache_array, $term_name);
             // caching query :)
             $id = $term;
             $query[$term_name] = $term->slug;
             $function = 'get_term_link';
         }
     }
     // -> home url
     if (empty($query)) {
         $function = 'home_url';
         $id = '';
     }
     if (isset($function)) {
         // parse all languages links
         foreach ($q_config['enabled_languages'] as $lang) {
             $this->lang = $lang;
             $this->current_url[$lang] = apply_filters('qts_url_args', call_user_func($function, $id));
         }
         $this->lang = false;
     }
     return $query;
 }
 /**
  * Retrieves the terms associated with the given object(s), in the
  * supplied taxonomies.
  * 
  * This is a copy of WordPress' wp_get_object_terms function with a bunch
  * of edits to use term_order as a default sorting param.
  * 
  * @since    1.0
  * 
  * @param    array           $terms The post's terms
  * @param    int|array       $object_ids The ID(s) of the object(s) to retrieve.
  * @param    string|array    $taxonomies The taxonomies to retrieve terms from.
  * @param    array|string    $args Change what is returned
  * 
  * @return   array|WP_Error  The requested term data or empty array if no
  *                           terms found. WP_Error if any of the $taxonomies
  *                           don't exist.
  */
 public static function get_ordered_object_terms($terms, $object_ids, $taxonomies, $args)
 {
     $total = count($terms);
     $original_terms = $terms;
     // Term ordering is killing quick/bulk edit, avoid it
     if (is_admin() && (function_exists('get_current_screen') && 'edit-movie' == get_current_screen()->id)) {
         return $terms;
     }
     $taxonomies = explode(', ', str_replace("'", "", $taxonomies));
     if (empty($object_ids) || $taxonomies != "'collection', 'actor', 'genre'" && (!in_array('collection', $taxonomies) && !in_array('actor', $taxonomies) && !in_array('genre', $taxonomies))) {
         return $terms;
     }
     global $wpdb;
     foreach ((array) $taxonomies as $taxonomy) {
         if (!taxonomy_exists($taxonomy)) {
             return new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
         }
     }
     if (!is_array($object_ids)) {
         $object_ids = array($object_ids);
     }
     $object_ids = array_map('intval', $object_ids);
     $defaults = array('orderby' => 'term_order', 'order' => 'ASC', 'fields' => 'all');
     $args = wp_parse_args($args, $defaults);
     $terms = array();
     if (count($taxonomies) > 1) {
         foreach ($taxonomies as $index => $taxonomy) {
             $t = get_taxonomy($taxonomy);
             if (isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args)) {
                 unset($taxonomies[$index]);
                 $terms = array_merge($terms, self::get_ordered_object_terms($object_ids, $taxonomy, array_merge($args, $t->args)));
             }
         }
     } else {
         $t = get_taxonomy($taxonomies[0]);
         if (isset($t->args) && is_array($t->args)) {
             $args = array_merge($args, $t->args);
         }
     }
     extract($args, EXTR_SKIP);
     $orderby = "ORDER BY tr.term_order";
     $order = 'ASC';
     $taxonomies = "'" . implode("', '", $taxonomies) . "'";
     $object_ids = implode(', ', $object_ids);
     $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';
             } else {
                 if ('slugs' == $fields) {
                     $select_this = 't.slug';
                 } else {
                     if ('all_with_object_id' == $fields) {
                         $select_this = 't.*, tt.*, tr.object_id';
                     }
                 }
             }
         }
     }
     $query = "SELECT {$select_this} FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.term_id = t.term_id INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ({$taxonomies}) AND tr.object_id IN ({$object_ids}) {$orderby} {$order}";
     if ('all' == $fields || 'all_with_object_id' == $fields) {
         $_terms = $wpdb->get_results($query);
         foreach ($_terms as $key => $term) {
             $_terms[$key] = sanitize_term($term, $taxonomy, 'raw');
         }
         $terms = array_merge($terms, $_terms);
         update_term_cache($terms);
     } else {
         if ('ids' == $fields || 'names' == $fields || 'slugs' == $fields) {
             $_terms = $wpdb->get_col($query);
             $_field = 'ids' == $fields ? 'term_id' : 'name';
             foreach ($_terms as $key => $term) {
                 $_terms[$key] = sanitize_term_field($_field, $term, $term, $taxonomy, 'raw');
             }
             $terms = array_merge($terms, $_terms);
         } else {
             if ('tt_ids' == $fields) {
                 $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM {$wpdb->term_relationships} AS tr INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ({$object_ids}) AND tt.taxonomy IN ({$taxonomies}) {$orderby} {$order}");
                 foreach ($terms as $key => $tt_id) {
                     $terms[$key] = sanitize_term_field('term_taxonomy_id', $tt_id, 0, $taxonomy, 'raw');
                     // 0 should be the term id, however is not needed when using raw context.
                 }
             }
         }
     }
     if (!$terms) {
         $terms = array();
     }
     if ($total != count($terms)) {
         $terms = $original_terms;
     }
     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;
	}
Example #17
0
/**
 * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
 *
 * @since 2.3.0
 * @since 4.2.0 Added support for 'taxonomy', 'parent', and 'term_taxonomy_id' values of `$orderby`.
 *              Introduced `$parent` argument.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|array    $object_ids The ID(s) of the object(s) to retrieve.
 * @param string|array $taxonomies The taxonomies to retrieve terms from.
 * @param array|string $args {
 *     Array of arguments.
 *     @type string $orderby Field by which results should be sorted. Accepts 'name', 'count', 'slug', 'term_group',
 *                           'term_order', 'taxonomy', 'parent', or 'term_taxonomy_id'. Default 'name'.
 *     @type string $order   Sort order. Accepts 'ASC' or 'DESC'. Default 'ASC'.
 *     @type string $fields  Fields to return for matched terms. Accepts 'all', 'ids', 'names', and
 *                           'all_with_object_id'. Note that 'all' or 'all_with_object_id' will result in an array of
 *                           term objects being returned, 'ids' will return an array of integers, and 'names' an array
 *                           of strings.
 *     @type int    $parent  Optional. Limit results to the direct children of a given term ID.
 * }
 * @return array|WP_Error The requested term data or empty array if no terms found.
 *                        WP_Error if any of the $taxonomies don't exist.
 */
function wp_get_object_terms($object_ids, $taxonomies, $args = array()) {
	global $wpdb;

	if ( empty( $object_ids ) || empty( $taxonomies ) )
		return array();

	if ( !is_array($taxonomies) )
		$taxonomies = array($taxonomies);

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

	if ( !is_array($object_ids) )
		$object_ids = array($object_ids);
	$object_ids = array_map('intval', $object_ids);

	$defaults = array(
		'orderby' => 'name',
		'order'   => 'ASC',
		'fields'  => 'all',
		'parent'  => '',
	);
	$args = wp_parse_args( $args, $defaults );

	$terms = array();
	if ( count($taxonomies) > 1 ) {
		foreach ( $taxonomies as $index => $taxonomy ) {
			$t = get_taxonomy($taxonomy);
			if ( isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args) ) {
				unset($taxonomies[$index]);
				$terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args)));
			}
		}
	} else {
		$t = get_taxonomy($taxonomies[0]);
		if ( isset($t->args) && is_array($t->args) )
			$args = array_merge($args, $t->args);
	}

	$orderby = $args['orderby'];
	$order = $args['order'];
	$fields = $args['fields'];

	if ( in_array( $orderby, array( 'term_id', 'name', 'slug', 'term_group' ) ) ) {
		$orderby = "t.$orderby";
	} elseif ( in_array( $orderby, array( 'count', 'parent', 'taxonomy', 'term_taxonomy_id' ) ) ) {
		$orderby = "tt.$orderby";
	} elseif ( 'term_order' === $orderby ) {
		$orderby = 'tr.term_order';
	} elseif ( 'none' === $orderby ) {
		$orderby = '';
		$order = '';
	} else {
		$orderby = 't.term_id';
	}

	// tt_ids queries can only be none or tr.term_taxonomy_id
	if ( ('tt_ids' == $fields) && !empty($orderby) )
		$orderby = 'tr.term_taxonomy_id';

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

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

	$taxonomy_array = $taxonomies;
	$object_id_array = $object_ids;
	$taxonomies = "'" . implode("', '", $taxonomies) . "'";
	$object_ids = implode(', ', $object_ids);

	$select_this = '';
	if ( 'all' == $fields ) {
		$select_this = 't.*, tt.*';
	} elseif ( 'ids' == $fields ) {
		$select_this = 't.term_id';
	} elseif ( 'names' == $fields ) {
		$select_this = 't.name';
	} elseif ( 'slugs' == $fields ) {
		$select_this = 't.slug';
	} elseif ( 'all_with_object_id' == $fields ) {
		$select_this = 't.*, tt.*, tr.object_id';
	}

	$where = array(
		"tt.taxonomy IN ($taxonomies)",
		"tr.object_id IN ($object_ids)",
	);

	if ( '' !== $args['parent'] ) {
		$where[] = $wpdb->prepare( 'tt.parent = %d', $args['parent'] );
	}

	$where = implode( ' AND ', $where );

	$query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE $where $orderby $order";

	$objects = false;
	if ( 'all' == $fields || 'all_with_object_id' == $fields ) {
		$_terms = $wpdb->get_results( $query );
		foreach ( $_terms as $key => $term ) {
			$_terms[$key] = sanitize_term( $term, $taxonomy, 'raw' );
		}
		$terms = array_merge( $terms, $_terms );
		update_term_cache( $terms );
		$objects = true;
	} elseif ( 'ids' == $fields || 'names' == $fields || 'slugs' == $fields ) {
		$_terms = $wpdb->get_col( $query );
		$_field = ( 'ids' == $fields ) ? 'term_id' : 'name';
		foreach ( $_terms as $key => $term ) {
			$_terms[$key] = sanitize_term_field( $_field, $term, $term, $taxonomy, 'raw' );
		}
		$terms = array_merge( $terms, $_terms );
	} elseif ( 'tt_ids' == $fields ) {
		$terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) $orderby $order");
		foreach ( $terms as $key => $tt_id ) {
			$terms[$key] = sanitize_term_field( 'term_taxonomy_id', $tt_id, 0, $taxonomy, 'raw' ); // 0 should be the term id, however is not needed when using raw context.
		}
	}

	if ( ! $terms ) {
		$terms = array();
	} elseif ( $objects && 'all_with_object_id' !== $fields ) {
		$_tt_ids = array();
		$_terms = array();
		foreach ( $terms as $term ) {
			if ( in_array( $term->term_taxonomy_id, $_tt_ids ) ) {
				continue;
			}

			$_tt_ids[] = $term->term_taxonomy_id;
			$_terms[] = $term;
		}
		$terms = $_terms;
	} elseif ( ! $objects ) {
		$terms = array_values( array_unique( $terms ) );
	}

	/**
	 * Filter the terms for a given object or objects.
	 *
	 * @since 4.2.0
	 *
	 * @param array $terms           An array of terms for the given object or objects.
	 * @param array $object_id_array Array of object IDs for which `$terms` were retrieved.
	 * @param array $taxonomy_array  Array of taxonomies from which `$terms` were retrieved.
	 * @param array $args            An array of arguments for retrieving terms for the given
	 *                               object(s). See wp_get_object_terms() for details.
	 */
	$terms = apply_filters( 'get_object_terms', $terms, $object_id_array, $taxonomy_array, $args );

	/**
	 * Filter the terms for a given object or objects.
	 *
	 * The `$taxonomies` parameter passed to this filter is formatted as a SQL fragment. The
	 * {@see 'get_object_terms'} filter is recommended as an alternative.
	 *
	 * @since 2.8.0
	 *
	 * @param array     $terms      An array of terms for the given object or objects.
	 * @param int|array $object_ids Object ID or array of IDs.
	 * @param string    $taxonomies SQL-formatted (comma-separated and quoted) list of taxonomy names.
	 * @param array     $args       An array of arguments for retrieving terms for the given object(s).
	 *                              See {@see wp_get_object_terms()} for details.
	 */
	return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args );
}
Example #18
0
/**
 * Adds any terms from the given IDs to the cache that do not already exist in cache.
 *
 * @since 4.6.0
 * @access private
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $term_ids          Array of term IDs.
 * @param bool  $update_meta_cache Optional. Whether to update the meta cache. Default true.
 */
function _prime_term_caches($term_ids, $update_meta_cache = true)
{
    global $wpdb;
    $non_cached_ids = _get_non_cached_ids($term_ids, 'terms');
    if (!empty($non_cached_ids)) {
        $fresh_terms = $wpdb->get_results(sprintf("SELECT t.*, tt.* FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.term_id IN (%s)", join(",", array_map('intval', $non_cached_ids))));
        update_term_cache($fresh_terms, $update_meta_cache);
        if ($update_meta_cache) {
            update_termmeta_cache($non_cached_ids);
        }
    }
}
Example #19
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 = '', $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;
	}
/**
 * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
 *
 * @since 2.3.0
 * @since 4.2.0 Added support for 'taxonomy', 'parent', and 'term_taxonomy_id' values of `$orderby`.
 *              Introduced `$parent` argument.
 * @since 4.4.0 Introduced `$meta_query` and `$update_term_meta_cache` arguments. When `$fields` is 'all' or
 *              'all_with_object_id', an array of `WP_Term` objects will be returned.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|array    $object_ids The ID(s) of the object(s) to retrieve.
 * @param string|array $taxonomies The taxonomies to retrieve terms from.
 * @param array|string $args {
 *     Array of arguments.
 *     @type string $orderby                Field by which results should be sorted. Accepts 'name', 'count', 'slug',
 *                                          'term_group', 'term_order', 'taxonomy', 'parent', or 'term_taxonomy_id'.
 *                                          Default 'name'.
 *     @type string $order                  Sort order. Accepts 'ASC' or 'DESC'. Default 'ASC'.
 *     @type string $fields                 Fields to return for matched terms. Accepts 'all', 'ids', 'names', and
 *                                          'all_with_object_id'. Note that 'all' or 'all_with_object_id' will result
 *                                          in an array of term objects being returned, 'ids' will return an array of
 *                                          integers, and 'names' an array of strings.
 *     @type int    $parent                 Optional. Limit results to the direct children of a given term ID.
 *     @type bool   $update_term_meta_cache Whether to prime termmeta cache for matched terms. Only applies when
 *                                          `$fields` is 'all', 'all_with_object_id', or 'term_id'. Default true.
 *     @type array  $meta_query             Meta query clauses to limit retrieved terms by. See `WP_Meta_Query`.
 *                                          Default empty.
 * }
 * @return array|WP_Error The requested term data or empty array if no terms found.
 *                        WP_Error if any of the $taxonomies don't exist.
 */
function wp_get_object_terms($object_ids, $taxonomies, $args = array())
{
    global $wpdb;
    if (empty($object_ids) || empty($taxonomies)) {
        return array();
    }
    if (!is_array($taxonomies)) {
        $taxonomies = array($taxonomies);
    }
    foreach ($taxonomies as $taxonomy) {
        if (!taxonomy_exists($taxonomy)) {
            return new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
        }
    }
    if (!is_array($object_ids)) {
        $object_ids = array($object_ids);
    }
    $object_ids = array_map('intval', $object_ids);
    $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all', 'parent' => '', 'update_term_meta_cache' => true, 'meta_query' => '');
    $args = wp_parse_args($args, $defaults);
    $terms = array();
    if (count($taxonomies) > 1) {
        foreach ($taxonomies as $index => $taxonomy) {
            $t = get_taxonomy($taxonomy);
            if (isset($t->args) && is_array($t->args) && $args != array_merge($args, $t->args)) {
                unset($taxonomies[$index]);
                $terms = array_merge($terms, wp_get_object_terms($object_ids, $taxonomy, array_merge($args, $t->args)));
            }
        }
    } else {
        $t = get_taxonomy($taxonomies[0]);
        if (isset($t->args) && is_array($t->args)) {
            $args = array_merge($args, $t->args);
        }
    }
    $orderby = $args['orderby'];
    $order = $args['order'];
    $fields = $args['fields'];
    if (in_array($orderby, array('term_id', 'name', 'slug', 'term_group'))) {
        $orderby = "t.{$orderby}";
    } elseif (in_array($orderby, array('count', 'parent', 'taxonomy', 'term_taxonomy_id'))) {
        $orderby = "tt.{$orderby}";
    } elseif ('term_order' === $orderby) {
        $orderby = 'tr.term_order';
    } elseif ('none' === $orderby) {
        $orderby = '';
        $order = '';
    } else {
        $orderby = 't.term_id';
    }
    // tt_ids queries can only be none or tr.term_taxonomy_id
    if ('tt_ids' == $fields && !empty($orderby)) {
        $orderby = 'tr.term_taxonomy_id';
    }
    if (!empty($orderby)) {
        $orderby = "ORDER BY {$orderby}";
    }
    $order = strtoupper($order);
    if ('' !== $order && !in_array($order, array('ASC', 'DESC'))) {
        $order = 'ASC';
    }
    $taxonomy_array = $taxonomies;
    $object_id_array = $object_ids;
    $taxonomies = "'" . implode("', '", $taxonomies) . "'";
    $object_ids = implode(', ', $object_ids);
    $select_this = '';
    if ('all' == $fields) {
        $select_this = 't.*, tt.*';
    } elseif ('ids' == $fields) {
        $select_this = 't.term_id';
    } elseif ('names' == $fields) {
        $select_this = 't.name';
    } elseif ('slugs' == $fields) {
        $select_this = 't.slug';
    } elseif ('all_with_object_id' == $fields) {
        $select_this = 't.*, tt.*, tr.object_id';
    }
    $where = array("tt.taxonomy IN ({$taxonomies})", "tr.object_id IN ({$object_ids})");
    if ('' !== $args['parent']) {
        $where[] = $wpdb->prepare('tt.parent = %d', $args['parent']);
    }
    // Meta query support.
    $meta_query_join = '';
    if (!empty($args['meta_query'])) {
        $mquery = new WP_Meta_Query($args['meta_query']);
        $mq_sql = $mquery->get_sql('term', 't', 'term_id');
        $meta_query_join .= $mq_sql['join'];
        // Strip leading AND.
        $where[] = preg_replace('/^\\s*AND/', '', $mq_sql['where']);
    }
    $where = implode(' AND ', $where);
    $query = "SELECT {$select_this} FROM {$wpdb->terms} AS t INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.term_id = t.term_id INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id {$meta_query_join} WHERE {$where} {$orderby} {$order}";
    $objects = false;
    if ('all' == $fields || 'all_with_object_id' == $fields) {
        $_terms = $wpdb->get_results($query);
        $object_id_index = array();
        foreach ($_terms as $key => $term) {
            $term = sanitize_term($term, $taxonomy, 'raw');
            $_terms[$key] = $term;
            if (isset($term->object_id)) {
                $object_id_index[$key] = $term->object_id;
            }
        }
        update_term_cache($_terms);
        $_terms = array_map('get_term', $_terms);
        // Re-add the object_id data, which is lost when fetching terms from cache.
        if ('all_with_object_id' === $fields) {
            foreach ($_terms as $key => $_term) {
                if (isset($object_id_index[$key])) {
                    $_term->object_id = $object_id_index[$key];
                }
            }
        }
        $terms = array_merge($terms, $_terms);
        $objects = true;
    } elseif ('ids' == $fields || 'names' == $fields || 'slugs' == $fields) {
        $_terms = $wpdb->get_col($query);
        $_field = 'ids' == $fields ? 'term_id' : 'name';
        foreach ($_terms as $key => $term) {
            $_terms[$key] = sanitize_term_field($_field, $term, $term, $taxonomy, 'raw');
        }
        $terms = array_merge($terms, $_terms);
    } elseif ('tt_ids' == $fields) {
        $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM {$wpdb->term_relationships} AS tr INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ({$object_ids}) AND tt.taxonomy IN ({$taxonomies}) {$orderby} {$order}");
        foreach ($terms as $key => $tt_id) {
            $terms[$key] = sanitize_term_field('term_taxonomy_id', $tt_id, 0, $taxonomy, 'raw');
            // 0 should be the term id, however is not needed when using raw context.
        }
    }
    // Update termmeta cache, if necessary.
    if ($args['update_term_meta_cache'] && ('all' === $fields || 'all_with_object_ids' === $fields || 'term_id' === $fields)) {
        if ('term_id' === $fields) {
            $term_ids = $fields;
        } else {
            $term_ids = wp_list_pluck($terms, 'term_id');
        }
        update_termmeta_cache($term_ids);
    }
    if (!$terms) {
        $terms = array();
    } elseif ($objects && 'all_with_object_id' !== $fields) {
        $_tt_ids = array();
        $_terms = array();
        foreach ($terms as $term) {
            if (in_array($term->term_taxonomy_id, $_tt_ids)) {
                continue;
            }
            $_tt_ids[] = $term->term_taxonomy_id;
            $_terms[] = $term;
        }
        $terms = $_terms;
    } elseif (!$objects) {
        $terms = array_values(array_unique($terms));
    }
    /**
     * Filter the terms for a given object or objects.
     *
     * @since 4.2.0
     *
     * @param array $terms           An array of terms for the given object or objects.
     * @param array $object_id_array Array of object IDs for which `$terms` were retrieved.
     * @param array $taxonomy_array  Array of taxonomies from which `$terms` were retrieved.
     * @param array $args            An array of arguments for retrieving terms for the given
     *                               object(s). See wp_get_object_terms() for details.
     */
    $terms = apply_filters('get_object_terms', $terms, $object_id_array, $taxonomy_array, $args);
    /**
     * Filter the terms for a given object or objects.
     *
     * The `$taxonomies` parameter passed to this filter is formatted as a SQL fragment. The
     * {@see 'get_object_terms'} filter is recommended as an alternative.
     *
     * @since 2.8.0
     *
     * @param array     $terms      An array of terms for the given object or objects.
     * @param int|array $object_ids Object ID or array of IDs.
     * @param string    $taxonomies SQL-formatted (comma-separated and quoted) list of taxonomy names.
     * @param array     $args       An array of arguments for retrieving terms for the given object(s).
     *                              See {@see wp_get_object_terms()} for details.
     */
    return apply_filters('wp_get_object_terms', $terms, $object_ids, $taxonomies, $args);
}
Example #21
0
 /**
  * Filter the terms for a given object or objects.
  *
  * @since 1.0.0
  * @access public
  *
  * @see wp_get_object_terms()
  *
  * @param array        $terms      An array of terms for the given object or objects.
  * @param array|int    $object_ids Object ID or array of IDs.
  * @param array|string $taxonomies A taxonomy or array of taxonomies.
  * @param array        $args       An array of arguments for retrieving terms for
  *                                 the given object(s).
  */
 function get_object_terms($terms, $object_ids, $taxonomies, $args)
 {
     // 'term_order' == $args['orderby'] ... Enable only specified orderby argument.
     $do_term_order = true;
     if (!$terms || is_wp_error($terms) || !$do_term_order) {
         return $terms;
     }
     global $wpdb;
     extract($args, EXTR_SKIP);
     if ('term_order' != $args['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 ('term_order' == $orderby) {
                             $orderby = 'tr.term_order';
                         } else {
                             if ('none' == $orderby) {
                                 $orderby = '';
                                 $order = '';
                             } else {
                                 $orderby = 't.term_id';
                             }
                         }
                     }
                 }
             }
         }
         // tt_ids queries can only be none or tr.term_taxonomy_id
         if ('tt_ids' == $fields && !empty($orderby)) {
             $orderby = 'tr.term_taxonomy_id';
         }
         $orderby = implode(',', array_filter(array('tr.term_order ASC', $orderby)));
     } else {
         $orderby = 'tr.term_order';
         $order = 'ASC';
     }
     $order = strtoupper($order);
     if ('' !== $order && !in_array($order, array('ASC', 'DESC'))) {
         $order = 'ASC';
     }
     $field = '';
     $select_this = '';
     $values = array();
     switch ($fields) {
         case 'all':
             $field = 'term_id';
             $select_this = 't.*, tt.*, tr.term_order';
             $values = wp_list_pluck($terms, $field);
             break;
         case 'ids':
             $field = 'term_id';
             $select_this = 't.term_id, tt.taxonomy';
             $values = $terms;
             break;
         case 'names':
             $field = 'name';
             $select_this = 't.name, t.term_id, tt.taxonomy';
             $values = array_map(array($this, 'add_quote'), $terms);
             break;
         case 'slugs':
             $field = 'slug';
             $select_this = 't.slug, t.term_id, tt.taxonomy';
             $values = array_map(array($this, 'add_quote'), $terms);
             break;
         case 'all_with_object_id':
             $field = 'term_id';
             $select_this = 't.*, tt.*, tr.term_order, tr.object_id';
             $values = wp_list_pluck($terms, $field);
             break;
         case 'tt_ids':
             $values = $terms;
             break;
     }
     $values = implode(',', $values);
     $query = "SELECT {$select_this}" . " FROM {$wpdb->terms} AS t" . " INNER JOIN {$wpdb->term_taxonomy} AS tt ON tt.term_id = t.term_id" . " LEFT  JOIN {$wpdb->term_relationships} AS tr ON (tr.term_taxonomy_id = tt.term_taxonomy_id AND tr.object_id = 0)" . " WHERE t.{$field} IN ({$values})" . " ORDER BY {$orderby} {$order}";
     if ('all' == $fields || 'all_with_object_id' == $fields) {
         $terms = $wpdb->get_results($query);
         foreach ($terms as $key => $term) {
             $terms[$key] = sanitize_term($term, $term->taxonomy, 'raw');
         }
         update_term_cache($terms);
     } else {
         if ('ids' == $fields || 'names' == $fields || 'slugs' == $fields) {
             $terms = $wpdb->get_results($query);
             $_field = 'ids' == $fields ? 'term_id' : 'name';
             foreach ($terms as $key => $term) {
                 $terms[$key] = sanitize_term_field($_field, $term->{$field}, $term->term_id, $term->taxonomy, 'raw');
             }
         } else {
             if ('tt_ids' == $fields) {
                 $terms = $wpdb->get_results("SELECT tt.term_taxonomy_id, tt.taxonomy" . " FROM {$wpdb->term_taxonomy} AS tt" . " LEFT JOIN {$wpdb->term_relationships} AS tr ON (tr.term_taxonomy_id = tt.term_taxonomy_id AND tr.object_id = 0)" . " WHERE tt.term_taxonomy_id IN ({$values})" . " ORDER BY {$orderby} {$order}");
                 foreach ($terms as $key => $term) {
                     $terms[$key] = sanitize_term_field('term_taxonomy_id', $term->term_taxonomy_id, 0, $term->taxonomy, 'raw');
                 }
             }
         }
     }
     return $terms;
 }