+/**
+ * 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;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Determine if the given object type is associated with the given taxonomy.
+ *
+ * @since 3.0.0
+ * @uses get_object_taxonomies()
+ *
+ * @param string $object_type Object type string
+ * @param string $taxonomy Single taxonomy name
+ * @return bool True if object is associated with the taxonomy, otherwise false.
+ */
+function is_object_in_taxonomy($object_type, $taxonomy) {
+ $taxonomies = get_object_taxonomies($object_type);
+
+ if ( empty($taxonomies) )
+ return false;
+
+ if ( in_array($taxonomy, $taxonomies) )
+ return true;
+
+ return false;
+}
+
+/**
+ * Get an array of ancestor IDs for a given object.
+ *
+ * @param int $object_id The ID of the object
+ * @param string $object_type The type of object for which we'll be retrieving ancestors.
+ * @return array of ancestors from lowest to highest in the hierarchy.
+ */
+function get_ancestors($object_id = 0, $object_type = '') {
+ $object_id = (int) $object_id;
+
+ $ancestors = array();
+
+ if ( empty( $object_id ) ) {
+ return apply_filters('get_ancestors', $ancestors, $object_id, $object_type);
+ }
+
+ if ( is_taxonomy_hierarchical( $object_type ) ) {
+ $term = get_term($object_id, $object_type);
+ while ( ! is_wp_error($term) && ! empty( $term->parent ) && ! in_array( $term->parent, $ancestors ) ) {
+ $ancestors[] = (int) $term->parent;
+ $term = get_term($term->parent, $object_type);
+ }
+ } elseif ( null !== get_post_type_object( $object_type ) ) {
+ $object = get_post($object_id);
+ if ( ! is_wp_error( $object ) && isset( $object->ancestors ) && is_array( $object->ancestors ) )
+ $ancestors = $object->ancestors;
+ else {
+ while ( ! is_wp_error($object) && ! empty( $object->post_parent ) && ! in_array( $object->post_parent, $ancestors ) ) {
+ $ancestors[] = (int) $object->post_parent;
+ $object = get_post($object->post_parent);
+ }
+ }
+ }
+
+ return apply_filters('get_ancestors', $ancestors, $object_id, $object_type);
+}
+
+/**
+ * Returns the term's parent's term_ID
+ *
+ * @since 3.1.0
+ *
+ * @param int $term_id
+ * @param string $taxonomy
+ *
+ * @return int|bool false on error
+ */
+function wp_get_term_taxonomy_parent_id( $term_id, $taxonomy ) {
+ $term = get_term( $term_id, $taxonomy );
+ if ( !$term || is_wp_error( $term ) )
+ return false;
+ return (int) $term->parent;
+}
+
+/**
+ * Checks the given subset of the term hierarchy for hierarchy loops.
+ * Prevents loops from forming and breaks those that it finds.
+ *
+ * Attached to the wp_update_term_parent filter.
+ *
+ * @since 3.1.0
+ * @uses wp_find_hierarchy_loop()
+ *
+ * @param int $parent term_id of the parent for the term we're checking.
+ * @param int $term_id The term we're checking.
+ * @param string $taxonomy The taxonomy of the term we're checking.
+ *
+ * @return int The new parent for the term.
+ */
+function wp_check_term_hierarchy_for_loops( $parent, $term_id, $taxonomy ) {
+ // Nothing fancy here - bail
+ if ( !$parent )
+ return 0;
+
+ // Can't be its own parent
+ if ( $parent == $term_id )
+ return 0;
+
+ // Now look for larger loops
+
+ if ( !$loop = wp_find_hierarchy_loop( 'wp_get_term_taxonomy_parent_id', $term_id, $parent, array( $taxonomy ) ) )
+ return $parent; // No loop
+
+ // Setting $parent to the given value causes a loop
+ if ( isset( $loop[$term_id] ) )
+ return 0;
+
+ // There's a loop, but it doesn't contain $term_id. Break the loop.
+ foreach ( array_keys( $loop ) as $loop_member )
+ wp_update_term( $loop_member, $taxonomy, array( 'parent' => 0 ) );
+
+ return $parent;
+}