From b16190c4969db36bd321cbbafe640594cc3d9d60 Mon Sep 17 00:00:00 2001 From: dd32 Date: Sat, 20 Mar 2010 02:23:52 +0000 Subject: [PATCH] Add hierarchical support for custom post_types in Rewrite Rules & Querying. See #12643 git-svn-id: http://svn.automattic.com/wordpress/trunk@13774 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/link-template.php | 19 ++++++++++++------- wp-includes/post.php | 17 ++++++++++------- wp-includes/query.php | 33 +++++++++++++++++++++++++++++---- wp-includes/rewrite.php | 3 ++- 4 files changed, 53 insertions(+), 19 deletions(-) diff --git a/wp-includes/link-template.php b/wp-includes/link-template.php index d2e76b8446..4b93688147 100644 --- a/wp-includes/link-template.php +++ b/wp-includes/link-template.php @@ -187,11 +187,16 @@ function get_post_permalink( $id = 0, $leavename = false, $sample = false ) { $draft_or_pending = 'draft' == $post->post_status || 'pending' == $post->post_status; + $post_type = get_post_type_object($post->post_type); + if ( !empty($post_link) && ( ( isset($post->post_status) && !$draft_or_pending ) || $sample ) ) { - $post_link = ( $leavename ) ? $post_link : str_replace("%$post->post_type%", $slug, $post_link); + if ( ! $leavename ) { + if ( $post_type->hierarchical ) + $slug = get_page_uri($id); + $post_link = str_replace("%$post->post_type%", $slug, $post_link); + } $post_link = home_url( user_trailingslashit($post_link) ); } else { - $post_type = get_post_type_object($post->post_type); if ( $post_type->query_var && ( isset($post->post_status) && !$draft_or_pending ) ) $post_link = add_query_arg($post_type->query_var, $slug, ''); else @@ -295,9 +300,8 @@ function get_attachment_link($id = false) { $link = false; - if (! $id) { + if ( ! $id) $id = (int) $post->ID; - } $object = get_post($id); if ( $wp_rewrite->using_permalinks() && ($object->post_parent > 0) && ($object->post_parent != $id) ) { @@ -306,17 +310,18 @@ function get_attachment_link($id = false) { $parentlink = _get_page_link( $object->post_parent ); // Ignores page_on_front else $parentlink = get_permalink( $object->post_parent ); + if ( is_numeric($object->post_name) || false !== strpos(get_option('permalink_structure'), '%category%') ) $name = 'attachment/' . $object->post_name; // // is paged so we use the explicit attachment marker else $name = $object->post_name; - if (strpos($parentlink, '?') === false) + + if ( strpos($parentlink, '?') === false ) $link = user_trailingslashit( trailingslashit($parentlink) . $name ); } - if (! $link ) { + if ( ! $link ) $link = trailingslashit(get_bloginfo('url')) . "?attachment_id=$id"; - } return apply_filters('attachment_link', $link, $id); } diff --git a/wp-includes/post.php b/wp-includes/post.php index bbf056ee32..a8df5633ab 100644 --- a/wp-includes/post.php +++ b/wp-includes/post.php @@ -854,7 +854,10 @@ function register_post_type($post_type, $args = array()) { $args->rewrite['slug'] = $post_type; if ( !isset($args->rewrite['with_front']) ) $args->rewrite['with_front'] = true; - $wp_rewrite->add_rewrite_tag("%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name="); + if ( $args->hierarchical ) + $wp_rewrite->add_rewrite_tag("%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name="); + else + $wp_rewrite->add_rewrite_tag("%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name="); $wp_rewrite->add_permastruct($post_type, "{$args->rewrite['slug']}/%$post_type%", $args->rewrite['with_front'], $args->permalink_epmask); } @@ -2749,7 +2752,7 @@ function &get_page(&$page, $output = OBJECT, $filter = 'raw') { * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. * @return mixed Null when complete. */ -function get_page_by_path($page_path, $output = OBJECT) { +function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { global $wpdb; $page_path = rawurlencode(urldecode($page_path)); $page_path = str_replace('%2F', '/', $page_path); @@ -2761,21 +2764,21 @@ function get_page_by_path($page_path, $output = OBJECT) { foreach( (array) $page_paths as $pathdir) $full_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir); - $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = %s AND (post_type = 'page' OR post_type = 'attachment')", $leaf_path )); + $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = %s AND (post_type = %s OR post_type = 'attachment')", $leaf_path, $post_type )); if ( empty($pages) ) return null; - foreach ($pages as $page) { + foreach ( $pages as $page ) { $path = '/' . $leaf_path; $curpage = $page; - while ($curpage->post_parent != 0) { - $curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = %d and post_type='page'", $curpage->post_parent )); + while ( $curpage->post_parent != 0 ) { + $curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = %d and post_type = %s", $curpage->post_parent, $post_type )); $path = '/' . $curpage->post_name . $path; } if ( $path == $full_path ) - return get_page($page->ID, $output); + return get_page($page->ID, $output, $post_type); } return null; diff --git a/wp-includes/query.php b/wp-includes/query.php index 7bd75e49d3..eca8e10258 100644 --- a/wp-includes/query.php +++ b/wp-includes/query.php @@ -1712,10 +1712,35 @@ class WP_Query { if ( $q['day'] ) $where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'"; - if ('' != $q['name']) { + if ( !empty($q['post_type']) && !empty($q[ $q['post_type'] ]) ) { + $q[ $q['post_type'] ] = str_replace('%2F', '/', urlencode(urldecode($q[ $q['post_type'] ]))); + $post_type_object = get_post_type_object($q['post_type']); + if ( ! $post_type_object->hierarchical || strpos($q[ $q['post_type'] ], '/') === false) { + $q['name'] = $q[ $q['post_type'] ] = sanitize_title($q[ $q['post_type'] ]); + $where .= " AND $wpdb->posts.post_name = '" . $q[ $q['post_type'] ] . "'"; + } else { + // Hierarchical post type, need to look deeper to see if its an attachment or this post_type + if ( isset($this->queried_object_id) ) { + $reqpage = $this->queried_object_id; + } else { + $reqpage = get_page_by_path($q[ $q['post_type'] ], OBJECT, $q['post_type']); + if ( !empty($reqpage) ) + $reqpage = $reqpage->ID; + else + $reqpage = 0; + } + $where .= " AND ($wpdb->posts.ID = '$reqpage')"; + $reqpage_obj = get_page($reqpage); + if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) { + $this->is_attachment = true; + $q['attachment_id'] = $reqpage; + $post_type = $q['post_type'] = 'attachment'; + } + } + } elseif ( '' != $q['name'] ) { $q['name'] = sanitize_title($q['name']); $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'"; - } else if ('' != $q['pagename']) { + } elseif ( '' != $q['pagename'] ) { if ( isset($this->queried_object_id) ) $reqpage = $this->queried_object_id; else { @@ -1727,7 +1752,7 @@ class WP_Query { } $page_for_posts = get_option('page_for_posts'); - if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) { + if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) { $q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename']))); $page_paths = '/' . trim($q['pagename'], '/'); $q['pagename'] = sanitize_title(basename($page_paths)); @@ -2802,4 +2827,4 @@ function setup_postdata($post) { return true; } -?> +?> \ No newline at end of file diff --git a/wp-includes/rewrite.php b/wp-includes/rewrite.php index 4d27722bc8..bf015fafe9 100644 --- a/wp-includes/rewrite.php +++ b/wp-includes/rewrite.php @@ -1436,8 +1436,9 @@ class WP_Rewrite { // For custom post types, we need to add on endpoints as well. foreach ( get_post_types( array('_builtin' => false ) ) as $ptype ) { if ( strpos($struct, "%$ptype%") !== false ) { + $ptype = get_post_type_object($ptype); $post = true; - $page = false; + $page = $ptype->hierarchical; // This is for page style attachment url's break; } }