diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php index 80b059da7..816b20e12 100644 --- a/wp-admin/includes/media.php +++ b/wp-admin/includes/media.php @@ -426,37 +426,6 @@ function media_upload_library() { return wp_iframe( 'media_upload_library_form', $errors ); } -function get_attachment_taxonomies($attachment) { - if ( is_int( $attachment ) ) - $attachment = get_post($attachment); - else if ( is_array($attachment) ) - $attachment = (object) $attachment; - - if ( ! is_object($attachment) ) - return array(); - - $filename = basename($attachment->guid); - - $objects = array('attachment'); - - if ( false !== strpos($filename, '.') ) - $objects[] = 'attachment:' . substr($filename, strrpos($filename, '.') + 1); - if ( !empty($attachment->post_mime_type) ) { - $objects[] = 'attachment:' . $attachment->post_mime_type; - if ( false !== strpos($attachment->post_mime_type, '/') ) - foreach ( explode('/', $attachment->post_mime_type) as $token ) - if ( !empty($token) ) - $objects[] = "attachment:$token"; - } - - $taxonomies = array(); - foreach ( $objects as $object ) - if ( $taxes = get_object_taxonomies($object) ) - $taxonomies = array_merge($taxonomies, $taxes); - - return array_unique($taxonomies); -} - function image_attachment_fields_to_edit($form_fields, $post) { if ( substr($post->post_mime_type, 0, 5) == 'image' ) { $form_fields['post_title']['required'] = true; diff --git a/wp-content/themes/default/image.php b/wp-content/themes/default/image.php index d8e36fd36..4545ff63a 100644 --- a/wp-content/themes/default/image.php +++ b/wp-content/themes/default/image.php @@ -23,6 +23,7 @@ This entry was posted on at and is filed under . + You can follow any responses to this entry through the feed. comment_status) && ('open' == $post->ping_status)) { diff --git a/wp-includes/category-template.php b/wp-includes/category-template.php index cceac1aef..ba2430207 100644 --- a/wp-includes/category-template.php +++ b/wp-includes/category-template.php @@ -475,6 +475,18 @@ function get_tag_link( $tag_id ) { } function get_the_tags( $id = 0 ) { + return apply_filters( 'get_the_tags', get_the_terms($id, 'post_tag') ); +} + +function get_the_tag_list( $before = '', $sep = '', $after = '' ) { + return apply_filters( 'the_tags', get_the_term_list(0, 'post_tag', $before, $sep, $after) ); +} + +function the_tags( $before = 'Tags: ', $sep = ', ', $after = '' ) { + return the_terms( 0, 'post_tag', $before, $sep, $after ); +} + +function get_the_terms( $id = 0, $taxonomy ) { global $post; $id = (int) $id; @@ -485,41 +497,39 @@ function get_the_tags( $id = 0 ) { if ( !$id ) $id = (int) $post->ID; - $tags = get_object_term_cache($id, 'post_tag'); - if ( false === $tags ) - $tags = wp_get_object_terms($id, 'post_tag'); + $terms = get_object_term_cache($id, $taxonomy); + if ( false === $terms ) + $terms = wp_get_object_terms($id, $taxonomy); - $tags = apply_filters( 'get_the_tags', $tags ); - if ( empty( $tags ) ) + if ( empty( $terms ) ) return false; - return $tags; + + return $terms; } -function get_the_tag_list( $before = '', $sep = '', $after = '' ) { - $tags = get_the_tags(); +function get_the_term_list( $id = 0, $taxonomy, $before = '', $sep = '', $after = '' ) { + $terms = get_the_terms($id, $taxonomy); - if ( empty( $tags ) ) + if ( is_wp_error($terms) ) + return $terms; + + if ( empty( $terms ) ) return false; - $tag_list = $before; - foreach ( $tags as $tag ) { - $link = get_tag_link($tag->term_id); + foreach ( $terms as $term ) { + $link = get_term_link($term, $taxonomy); if ( is_wp_error( $link ) ) return $link; - $tag_links[] = ''; + $term_links[] = ''; } - $tag_links = join( $sep, $tag_links ); - $tag_links = apply_filters( 'the_tags', $tag_links ); - $tag_list .= $tag_links; + $term_links = apply_filters( "term_links-$taxonomy", $term_links ); - $tag_list .= $after; - - return $tag_list; + return $before . join($sep, $term_links) . $after; } -function the_tags( $before = 'Tags: ', $sep = ', ', $after = '' ) { - $return = get_the_tag_list($before, $sep, $after); +function the_terms( $id, $taxonomy, $before = '', $sep = '', $after = '' ) { + $return = get_the_term_list($id, $taxonomy, $before, $sep, $after); if ( is_wp_error( $return ) ) return false; else diff --git a/wp-includes/classes.php b/wp-includes/classes.php index e2222980c..10623b476 100644 --- a/wp-includes/classes.php +++ b/wp-includes/classes.php @@ -14,7 +14,8 @@ class WP { var $did_permalink = false; function add_query_var($qv) { - $this->public_query_vars[] = $qv; + if ( !in_array($qv, $this->public_query_vars) ) + $this->public_query_vars[] = $qv; } function set_query_var($key, $value) { diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php index 967a4043d..27f29382a 100644 --- a/wp-includes/formatting.php +++ b/wp-includes/formatting.php @@ -1376,7 +1376,7 @@ function wp_sprintf_l($pattern, $args) { $args = (array) $args; $result = array_shift($args); if ( count($args) == 1 ) - $result .= $l['between_two'] . array_shift($args); + $result .= $l['between_only_two'] . array_shift($args); // Loop when more than two args while ( count($args) ) { $arg = array_shift($args); diff --git a/wp-includes/media.php b/wp-includes/media.php index 7a51e4f3c..b81fcfa26 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -438,4 +438,35 @@ function adjacent_image_link($prev = true) { echo wp_get_attachment_link($attachments[$k]->ID, 'thumbnail', true); } +function get_attachment_taxonomies($attachment) { + if ( is_int( $attachment ) ) + $attachment = get_post($attachment); + else if ( is_array($attachment) ) + $attachment = (object) $attachment; + + if ( ! is_object($attachment) ) + return array(); + + $filename = basename($attachment->guid); + + $objects = array('attachment'); + + if ( false !== strpos($filename, '.') ) + $objects[] = 'attachment:' . substr($filename, strrpos($filename, '.') + 1); + if ( !empty($attachment->post_mime_type) ) { + $objects[] = 'attachment:' . $attachment->post_mime_type; + if ( false !== strpos($attachment->post_mime_type, '/') ) + foreach ( explode('/', $attachment->post_mime_type) as $token ) + if ( !empty($token) ) + $objects[] = "attachment:$token"; + } + + $taxonomies = array(); + foreach ( $objects as $object ) + if ( $taxes = get_object_taxonomies($object) ) + $taxonomies = array_merge($taxonomies, $taxes); + + return array_unique($taxonomies); +} + ?> diff --git a/wp-includes/query.php b/wp-includes/query.php index 4fe77538f..008ea5f11 100644 --- a/wp-includes/query.php +++ b/wp-includes/query.php @@ -680,6 +680,12 @@ class WP_Query { if ( empty($qv['taxonomy']) || empty($qv['term']) ) { $this->is_tax = false; + foreach ( $GLOBALS['wp_taxonomies'] as $t ) { + if ( isset($t->query_var) && '' != $qv[$t->query_var] ) { + $this->is_tax = true; + break; + } + } } else { $this->is_tax = true; } @@ -1146,18 +1152,33 @@ class WP_Query { // Taxonomies if ( $this->is_tax ) { - $terms = get_terms($q['taxonomy'], array('slug'=>$q['term'])); - foreach ( $terms as $term ) - $term_ids[] = $term->term_id; - $post_ids = get_objects_in_term($term_ids, $q['taxonomy']); - - if ( count($post_ids) ) { - $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") "; - $post_type = 'any'; - $q['post_status'] = 'publish'; - $post_status_join = true; + if ( '' != $q['taxonomy'] ) { + $taxonomy = $q['taxonomy']; + $tt[$taxonomy] = $q['term']; + $terms = get_terms($q['taxonomy'], array('slug'=>$q['term'])); } else { - $whichcat = " AND 0 = 1"; + foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) { + if ( isset($t->query_var) && '' != $q[$t->query_var] ) { + $terms = get_terms($taxonomy, array('slug'=>$q[$t->query_var])); + if ( !is_wp_error($terms) ) + break; + } + } + } + if ( is_wp_error($terms) || empty($terms) ) { + $whichcat = " AND 0 "; + } else { + foreach ( $terms as $term ) + $term_ids[] = $term->term_id; + $post_ids = get_objects_in_term($term_ids, $taxonomy); + if ( !is_wp_error($post_ids) && count($post_ids) ) { + $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") "; + $post_type = 'any'; + $q['post_status'] = 'publish'; + $post_status_join = true; + } else { + $whichcat = " AND 0 "; + } } } @@ -1296,7 +1317,7 @@ class WP_Query { $statuswheres[] = "(" . join( ' OR ', $p_status ) . ")"; } if ( $post_status_join ) { - $join .= " INNER JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) "; + $join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) "; foreach ( $statuswheres as $index => $statuswhere ) $statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))"; } diff --git a/wp-includes/rewrite.php b/wp-includes/rewrite.php index dde1b1810..50f21dbe7 100644 --- a/wp-includes/rewrite.php +++ b/wp-includes/rewrite.php @@ -461,6 +461,12 @@ class WP_Rewrite { return $this->tag_structure; } + function get_extra_permastruct($name) { + if ( isset($this->extra_permastructs[$name]) ) + return $this->extra_permastructs[$name]; + return false; + } + function get_author_permastruct() { if (isset($this->author_structure)) { return $this->author_structure; @@ -832,15 +838,14 @@ class WP_Rewrite { $page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite); // Extra permastructs - $extra_rewrite = array(); foreach ( $this->extra_permastructs as $permastruct ) - $extra_rewrite = array_merge($extra_rewrite, $this->generate_rewrite_rules($permastruct, EP_NONE)); + $this->extra_rules_top = array_merge($this->extra_rules_top, $this->generate_rewrite_rules($permastruct, EP_NONE)); // Put them together. if ( $this->use_verbose_page_rules ) - $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $tag_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $extra_rewrite, $this->extra_rules); + $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $tag_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules); else - $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $tag_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $extra_rewrite, $page_rewrite, $this->extra_rules); + $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $default_feeds, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $tag_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules); do_action_ref_array('generate_rewrite_rules', array(&$this)); $this->rules = apply_filters('rewrite_rules_array', $this->rules); @@ -954,10 +959,10 @@ class WP_Rewrite { $wp->add_query_var($name); } - function add_permastruct($struct, $with_front = true) { + function add_permastruct($name, $struct, $with_front = true) { if ( $with_front ) $struct = $this->front . $struct; - $this->extra_permastructs[] = $struct; + $this->extra_permastructs[$name] = $struct; } function flush_rules() { diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php index a5a5f2365..588a9a5b0 100644 --- a/wp-includes/taxonomy.php +++ b/wp-includes/taxonomy.php @@ -34,15 +34,23 @@ $wp_taxonomies['link_category'] = (object) array('name' => 'link_category', 'obj * * @uses $wp_taxonomies * - * @param array|string $object_type Name of the type of taxonomy object + * @param array|string|object $object Name of the type of taxonomy object, or an object (row from posts) * @return array The names of all taxonomy of $object_type. */ -function get_object_taxonomies($object_type) { +function get_object_taxonomies($object) { global $wp_taxonomies; + if ( is_object($object) ) { + if ( $object->post_type == 'attachment' ) + return get_attachment_taxonomies($object); + $object = $object->post_type; + } + + $object = (array) $object; + $taxonomies = array(); foreach ( $wp_taxonomies as $taxonomy ) { - if ( in_array($object_type, (array) $taxonomy->object_type) ) + if ( array_intersect($object, (array) $taxonomy->object_type) ) $taxonomies[] = $taxonomy->name; } @@ -119,44 +127,51 @@ function is_taxonomy_hierarchical($taxonomy) { } /** - * register_taxonomy() - Create or modify a taxonomy object. + * register_taxonomy() - Create or modify a taxonomy object. Do not use before init. * * A simple function for creating or modifying a taxonomy object based on the parameters given. * The function will accept an array (third optional parameter), along with strings for the * taxonomy name and another string for the object type. * - * The function keeps a default set, allowing for the $args to be optional but allow the other - * functions to still work. It is possible to overwrite the default set, which contains two - * keys: hierarchical and update_count_callback. - * * Nothing is returned, so expect error maybe or use is_taxonomy() to check whether taxonomy exists. * * Optional $args contents: * hierarachical - has some defined purpose at other parts of the API and is a boolean value. * update_count_callback - works much like a hook, in that it will be called when the count is updated. + * rewrite - false to prevent rewrite, or array('slug'=>$slug) to customize permastruct; default will use $taxonomy as slug + * query_var - false to prevent queries, or string to customize query var (?$query_var=$term); default will use $taxonomy as query var * * @package WordPress * @subpackage Taxonomy * @since 2.3 * @uses $wp_taxonomies Inserts new taxonomy object into the list + * @uses $wp_rewrite Adds rewrite tags and permastructs + * @uses $wp Adds query vars * * @param string $taxonomy Name of taxonomy object * @param array|string $object_type Name of the object type for the taxonomy object. * @param array|string $args See above description for the two keys values. */ function register_taxonomy( $taxonomy, $object_type, $args = array() ) { - global $wp_taxonomies, $wp_rewrite; + global $wp_taxonomies, $wp_rewrite, $wp; - $defaults = array('hierarchical' => false, 'update_count_callback' => ''); + $defaults = array('hierarchical' => false, 'update_count_callback' => '', 'rewrite' => true, 'query_var' => true); $args = wp_parse_args($args, $defaults); - if ( !empty( $args['rewrite'] ) ) { + if ( false !== $args['query_var'] ) { + if ( empty($args['query_var']) ) + $args['query_var'] = $taxonomy; + $args['query_var'] = sanitize_title_with_dashes($args['query_var']); + $wp->add_query_var($args['query_var']); + } + + if ( false !== $args['rewrite'] ) { if ( !is_array($args['rewrite']) ) $args['rewrite'] = array(); if ( !isset($args['rewrite']['slug']) ) $args['rewrite']['slug'] = sanitize_title_with_dashes($taxonomy); - $wp_rewrite->add_rewrite_tag("%$taxonomy%", '([^/]+)', "taxonomy=$taxonomy&term="); - $wp_rewrite->add_permastruct("{$args['rewrite']['slug']}/%$taxonomy%"); + $wp_rewrite->add_rewrite_tag("%$taxonomy%", '([^/]+)', $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term=$term"); + $wp_rewrite->add_permastruct($taxonomy, "{$args['rewrite']['slug']}/%$taxonomy%"); } $args['name'] = $taxonomy; @@ -1036,6 +1051,22 @@ function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { $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 ) @@ -1067,10 +1098,10 @@ function wp_get_object_terms($object_ids, $taxonomies, $args = array()) { $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); + $terms = array_merge($terms, $wpdb->get_results($query)); update_term_cache($terms); } else if ( 'ids' == $fields || 'names' == $fields ) { - $terms = $wpdb->get_col($query); + $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"); } @@ -1899,4 +1930,99 @@ function _update_post_term_count( $terms ) { } } +/** + * get_term_link() - Generates a permalink for a taxonomy term archive + * + * @param object|int|string $term + * @param string $taxonomy + * @return string HTML link to taxonomy term archive + */ +function get_term_link( $term, $taxonomy ) { + global $wp_rewrite; + + $termlink = $wp_rewrite->get_extra_permastruct($taxonomy); + + if ( !is_object($term) ) { + if ( is_int($term) ) { + $term = &get_term($term, $taxonomy); + } else { + $term = &get_term_by('slug', $term, $taxonomy); + } + } + if ( is_wp_error( $term ) ) + return $term; + + $slug = $term->slug; + + if ( empty($termlink) ) { + $file = get_option('home') . '/'; + $t = get_taxonomy($taxonomy); + if ( $t->query_var ) + $termlink = "$file?$t->query_var=$slug"; + else + $termlink = "$file?taxonomy=$taxonomy&term=$slug"; + } else { + $termlink = str_replace("%$taxonomy%", $slug, $termlink); + $termlink = get_option('home') . user_trailingslashit($termlink, 'category'); + } + return apply_filters('term_link', $termlink, $term, $taxonomy); +} + +function the_taxonomies($args = array()) { + $defaults = array( + 'post' => 0, + 'before' => '', + 'sep' => ' ', + 'after' => '', + ); + + $r = wp_parse_args( $args, $defaults ); + extract( $r, EXTR_SKIP ); + + echo $before . join($sep, get_the_taxonomies($post)) . $after; +} + +function get_the_taxonomies($post = 0) { + if ( is_int($post) ) + $post =& get_post($post); + elseif ( !is_object($post) ) + $post =& $GLOBALS['post']; + + $taxonomies = array(); + + if ( !$post ) + return $taxonomies; + + $_template = '%s: %l.'; + + 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[] = "$term->name"; + + if ( $links ) + $taxonomies[$taxonomy] = wp_sprintf($t['template'], $t['label'], $links, $terms); + } + return $taxonomies; +} + +function get_post_taxonomies($post = 0) { + $post =& get_post($post); + + return get_object_taxonomies($post); +} + ?>