+ $object_types = (array) $taxonomy->object_type;
+
+ foreach ( $object_types as &$object_type )
+ list( $object_type ) = explode( ':', $object_type );
+
+ $object_types = array_unique( $object_types );
+
+ if ( false !== ( $check_attachments = array_search( 'attachment', $object_types ) ) ) {
+ unset( $object_types[ $check_attachments ] );
+ $check_attachments = true;
+ }
+
+ if ( $object_types )
+ $object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
+
+ foreach ( (array) $terms as $term ) {
+ $count = 0;
+
+ // Attachments can be 'inherit' status, we need to base count off the parent's status if so
+ if ( $check_attachments )
+ $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status = 'publish' OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) = 'publish' ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
+
+ if ( $object_types )
+ $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('" . implode("', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
+
+
+ do_action( 'edit_term_taxonomy', $term, $taxonomy );
+ $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
+ do_action( 'edited_term_taxonomy', $term, $taxonomy );
+ }
+}
+
+/**
+ * Will update term count based on number of objects.
+ *
+ * Default callback for the link_category taxonomy.
+ *
+ * @package WordPress
+ * @subpackage Taxonomy
+ * @since 3.3.0
+ * @uses $wpdb
+ *
+ * @param array $terms List of Term taxonomy IDs
+ * @param object $taxonomy Current taxonomy object of terms
+ */
+function _update_generic_term_count( $terms, $taxonomy ) {
+ global $wpdb;
+
+ foreach ( (array) $terms as $term ) {
+ $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $term ) );
+
+ do_action( 'edit_term_taxonomy', $term, $taxonomy );
+ $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
+ do_action( 'edited_term_taxonomy', $term, $taxonomy );
+ }
+}
+
+/**
+ * Generates a permalink for a taxonomy term archive.
+ *
+ * @since 2.5.0
+ *
+ * @uses apply_filters() Calls 'term_link' with term link and term object, and taxonomy parameters.
+ * @uses apply_filters() For the post_tag Taxonomy, Calls 'tag_link' with tag link and tag ID as parameters.
+ * @uses apply_filters() For the category Taxonomy, Calls 'category_link' filter on category link and category ID.
+ *
+ * @param object|int|string $term
+ * @param string $taxonomy (optional if $term is object)
+ * @return string|WP_Error HTML link to taxonomy term archive on success, WP_Error if term does not exist.
+ */
+function get_term_link( $term, $taxonomy = '') {
+ global $wp_rewrite;
+
+ if ( !is_object($term) ) {
+ if ( is_int($term) ) {
+ $term = &get_term($term, $taxonomy);
+ } else {
+ $term = &get_term_by('slug', $term, $taxonomy);
+ }
+ }
+
+ if ( !is_object($term) )
+ $term = new WP_Error('invalid_term', __('Empty Term'));
+
+ if ( is_wp_error( $term ) )
+ return $term;
+
+ $taxonomy = $term->taxonomy;
+
+ $termlink = $wp_rewrite->get_extra_permastruct($taxonomy);
+
+ $slug = $term->slug;
+ $t = get_taxonomy($taxonomy);
+
+ if ( empty($termlink) ) {
+ if ( 'category' == $taxonomy )
+ $termlink = '?cat=' . $term->term_id;
+ elseif ( $t->query_var )
+ $termlink = "?$t->query_var=$slug";
+ else
+ $termlink = "?taxonomy=$taxonomy&term=$slug";
+ $termlink = home_url($termlink);
+ } else {
+ if ( $t->rewrite['hierarchical'] ) {
+ $hierarchical_slugs = array();
+ $ancestors = get_ancestors($term->term_id, $taxonomy);
+ foreach ( (array)$ancestors as $ancestor ) {
+ $ancestor_term = get_term($ancestor, $taxonomy);
+ $hierarchical_slugs[] = $ancestor_term->slug;
+ }
+ $hierarchical_slugs = array_reverse($hierarchical_slugs);
+ $hierarchical_slugs[] = $slug;
+ $termlink = str_replace("%$taxonomy%", implode('/', $hierarchical_slugs), $termlink);
+ } else {
+ $termlink = str_replace("%$taxonomy%", $slug, $termlink);
+ }
+ $termlink = home_url( user_trailingslashit($termlink, 'category') );
+ }
+ // Back Compat filters.
+ if ( 'post_tag' == $taxonomy )
+ $termlink = apply_filters( 'tag_link', $termlink, $term->term_id );
+ elseif ( 'category' == $taxonomy )
+ $termlink = apply_filters( 'category_link', $termlink, $term->term_id );
+
+ return apply_filters('term_link', $termlink, $term, $taxonomy);
+}
+
+/**
+ * Display the taxonomies of a post with available options.
+ *
+ * This function can be used within the loop to display the taxonomies for a
+ * post without specifying the Post ID. You can also use it outside the Loop to
+ * display the taxonomies for a specific post.
+ *
+ * The available defaults are:
+ * 'post' : default is 0. The post ID to get taxonomies of.
+ * 'before' : default is empty string. Display before taxonomies list.
+ * 'sep' : default is empty string. Separate every taxonomy with value in this.
+ * 'after' : default is empty string. Display this after the taxonomies list.
+ * 'template' : The template to use for displaying the taxonomy terms.
+ *
+ * @since 2.5.0
+ * @uses get_the_taxonomies()
+ *
+ * @param array $args Override the defaults.
+ */
+function the_taxonomies($args = array()) {
+ $defaults = array(
+ 'post' => 0,
+ 'before' => '',
+ 'sep' => ' ',
+ 'after' => '',
+ 'template' => '%s: %l.'
+ );
+
+ $r = wp_parse_args( $args, $defaults );
+ extract( $r, EXTR_SKIP );
+
+ echo $before . join($sep, get_the_taxonomies($post, $r)) . $after;
+}
+
+/**
+ * Retrieve all taxonomies associated with a post.
+ *
+ * This function can be used within the loop. It will also return an array of
+ * the taxonomies with links to the taxonomy and name.
+ *
+ * @since 2.5.0
+ *
+ * @param int $post Optional. Post ID or will use Global Post ID (in loop).
+ * @param array $args Override the defaults.
+ * @return array
+ */
+function get_the_taxonomies($post = 0, $args = array() ) {
+ if ( is_int($post) )
+ $post =& get_post($post);
+ elseif ( !is_object($post) )
+ $post =& $GLOBALS['post'];
+
+ $args = wp_parse_args( $args, array(
+ 'template' => '%s: %l.',
+ ) );
+ extract( $args, EXTR_SKIP );
+
+ $taxonomies = array();
+
+ if ( !$post )
+ return $taxonomies;
+
+ foreach ( get_object_taxonomies($post) as $taxonomy ) {
+ $t = (array) get_taxonomy($taxonomy);
+ if ( empty($t['label']) )
+ $t['label'] = $taxonomy;
+ if ( empty($t['args']) )
+ $t['args'] = array();
+ if ( empty($t['template']) )
+ $t['template'] = $template;
+
+ $terms = get_object_term_cache($post->ID, $taxonomy);
+ if ( empty($terms) )
+ $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']);
+
+ $links = array();
+
+ foreach ( $terms as $term )
+ $links[] = "<a href='" . esc_attr( get_term_link($term) ) . "'>$term->name</a>";
+
+ if ( $links )
+ $taxonomies[$taxonomy] = wp_sprintf($t['template'], $t['label'], $links, $terms);
+ }
+ return $taxonomies;
+}
+
+/**
+ * Retrieve all taxonomies of a post with just the names.
+ *
+ * @since 2.5.0
+ * @uses get_object_taxonomies()
+ *
+ * @param int $post Optional. Post ID
+ * @return array
+ */
+function get_post_taxonomies($post = 0) {
+ $post =& get_post($post);
+
+ return get_object_taxonomies($post);
+}
+
+/**
+ * Determine if the given object is associated with any of the given terms.
+ *
+ * The given terms are checked against the object's terms' term_ids, names and slugs.
+ * Terms given as integers will only be checked against the object's terms' term_ids.
+ * If no terms are given, determines if object is associated with any terms in the given taxonomy.
+ *
+ * @since 2.7.0
+ * @uses get_object_term_cache()
+ * @uses wp_get_object_terms()
+ *
+ * @param int $object_id ID of the object (post ID, link ID, ...)
+ * @param string $taxonomy Single taxonomy name
+ * @param int|string|array $terms Optional. Term term_id, name, slug or array of said
+ * @return bool|WP_Error. WP_Error on input error.
+ */
+function is_object_in_term( $object_id, $taxonomy, $terms = null ) {
+ if ( !$object_id = (int) $object_id )
+ return new WP_Error( 'invalid_object', __( 'Invalid object ID' ) );
+
+ $object_terms = get_object_term_cache( $object_id, $taxonomy );
+ if ( empty( $object_terms ) )
+ $object_terms = wp_get_object_terms( $object_id, $taxonomy );
+
+ if ( is_wp_error( $object_terms ) )
+ return $object_terms;
+ if ( empty( $object_terms ) )
+ return false;
+ if ( empty( $terms ) )
+ return ( !empty( $object_terms ) );
+
+ $terms = (array) $terms;
+
+ if ( $ints = array_filter( $terms, 'is_int' ) )
+ $strs = array_diff( $terms, $ints );
+ else
+ $strs =& $terms;
+
+ foreach ( $object_terms as $object_term ) {
+ if ( $ints && in_array( $object_term->term_id, $ints ) ) return true; // If int, check against term_id
+ if ( $strs ) {
+ if ( in_array( $object_term->term_id, $strs ) ) return true;
+ if ( in_array( $object_term->name, $strs ) ) return true;
+ if ( in_array( $object_term->slug, $strs ) ) return true;
+ }