wp/wp-includes/canonical.php
changeset 18 be944660c56a
parent 16 a86126ab1dd4
child 19 3d72ae0968f4
--- a/wp/wp-includes/canonical.php	Tue Dec 15 15:52:01 2020 +0100
+++ b/wp/wp-includes/canonical.php	Wed Sep 21 18:19:35 2022 +0200
@@ -77,6 +77,7 @@
 
 	$redirect     = $original;
 	$redirect_url = false;
+	$redirect_obj = false;
 
 	// Notice fixing.
 	if ( ! isset( $redirect['path'] ) ) {
@@ -102,6 +103,7 @@
 
 	if ( is_feed() && $post_id ) {
 		$redirect_url = get_post_comments_feed_link( $post_id, get_query_var( 'feed' ) );
+		$redirect_obj = get_post( $post_id );
 
 		if ( $redirect_url ) {
 			$redirect['query'] = _remove_qs_args_if_not_in_url(
@@ -126,6 +128,7 @@
 			}
 
 			$redirect_url = get_permalink( $post_id );
+			$redirect_obj = get_post( $post_id );
 
 			if ( $redirect_url ) {
 				$redirect['query'] = _remove_qs_args_if_not_in_url(
@@ -148,8 +151,9 @@
 		if ( $redirect_post ) {
 			$post_type_obj = get_post_type_object( $redirect_post->post_type );
 
-			if ( $post_type_obj->public && 'auto-draft' !== $redirect_post->post_status ) {
+			if ( $post_type_obj && $post_type_obj->public && 'auto-draft' !== $redirect_post->post_status ) {
 				$redirect_url = get_permalink( $redirect_post );
+				$redirect_obj = get_post( $redirect_post );
 
 				$redirect['query'] = _remove_qs_args_if_not_in_url(
 					$redirect['query'],
@@ -197,6 +201,7 @@
 
 			if ( $post_id ) {
 				$redirect_url = get_permalink( $post_id );
+				$redirect_obj = get_post( $post_id );
 
 				$redirect['path']  = rtrim( $redirect['path'], (int) get_query_var( 'page' ) . '/' );
 				$redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
@@ -223,27 +228,32 @@
 		) {
 			if ( ! empty( $_GET['attachment_id'] ) ) {
 				$redirect_url = get_attachment_link( get_query_var( 'attachment_id' ) );
+				$redirect_obj = get_post( get_query_var( 'attachment_id' ) );
 
 				if ( $redirect_url ) {
 					$redirect['query'] = remove_query_arg( 'attachment_id', $redirect['query'] );
 				}
 			} else {
 				$redirect_url = get_attachment_link();
+				$redirect_obj = get_post();
 			}
 		} elseif ( is_single() && ! empty( $_GET['p'] ) && ! $redirect_url ) {
 			$redirect_url = get_permalink( get_query_var( 'p' ) );
+			$redirect_obj = get_post( get_query_var( 'p' ) );
 
 			if ( $redirect_url ) {
 				$redirect['query'] = remove_query_arg( array( 'p', 'post_type' ), $redirect['query'] );
 			}
 		} elseif ( is_single() && ! empty( $_GET['name'] ) && ! $redirect_url ) {
 			$redirect_url = get_permalink( $wp_query->get_queried_object_id() );
+			$redirect_obj = get_post( $wp_query->get_queried_object_id() );
 
 			if ( $redirect_url ) {
 				$redirect['query'] = remove_query_arg( 'name', $redirect['query'] );
 			}
 		} elseif ( is_page() && ! empty( $_GET['page_id'] ) && ! $redirect_url ) {
 			$redirect_url = get_permalink( get_query_var( 'page_id' ) );
+			$redirect_obj = get_post( get_query_var( 'page_id' ) );
 
 			if ( $redirect_url ) {
 				$redirect['query'] = remove_query_arg( 'page_id', $redirect['query'] );
@@ -256,6 +266,7 @@
 			&& 'page' === get_option( 'show_on_front' ) && get_query_var( 'page_id' ) === (int) get_option( 'page_for_posts' )
 		) {
 			$redirect_url = get_permalink( get_option( 'page_for_posts' ) );
+			$redirect_obj = get_post( get_option( 'page_for_posts' ) );
 
 			if ( $redirect_url ) {
 				$redirect['query'] = remove_query_arg( 'page_id', $redirect['query'] );
@@ -310,6 +321,7 @@
 				&& $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE $wpdb->posts.post_author = %d AND $wpdb->posts.post_status = 'publish' LIMIT 1", $author->ID ) )
 			) {
 				$redirect_url = get_author_posts_url( $author->ID, $author->user_nicename );
+				$redirect_obj = $author;
 
 				if ( $redirect_url ) {
 					$redirect['query'] = remove_query_arg( 'author', $redirect['query'] );
@@ -385,6 +397,7 @@
 					|| ! has_term( $category->term_id, 'category', $wp_query->get_queried_object_id() )
 				) {
 					$redirect_url = get_permalink( $wp_query->get_queried_object_id() );
+					$redirect_obj = get_post( $wp_query->get_queried_object_id() );
 				}
 			}
 		}
@@ -395,6 +408,7 @@
 
 			if ( ! $redirect_url ) {
 				$redirect_url = get_permalink( get_queried_object_id() );
+				$redirect_obj = get_post( get_queried_object_id() );
 			}
 
 			if ( $page > 1 ) {
@@ -740,6 +754,28 @@
 		$requested_url = preg_replace_callback( '|%[a-fA-F0-9][a-fA-F0-9]|', 'lowercase_octets', $requested_url );
 	}
 
+	if ( $redirect_obj instanceof WP_Post ) {
+		$post_status_obj = get_post_status_object( get_post_status( $redirect_obj ) );
+		/*
+		 * Unset the redirect object and URL if they are not readable by the user.
+		 * This condition is a little confusing as the condition needs to pass if
+		 * the post is not readable by the user. That's why there are ! (not) conditions
+		 * throughout.
+		 */
+		if (
+			// Private post statuses only redirect if the user can read them.
+			! (
+				$post_status_obj->private &&
+				current_user_can( 'read_post', $redirect_obj->ID )
+			) &&
+			// For other posts, only redirect if publicly viewable.
+			! is_post_publicly_viewable( $redirect_obj )
+		) {
+			$redirect_obj = false;
+			$redirect_url = false;
+		}
+	}
+
 	/**
 	 * Filters the canonical redirect URL.
 	 *
@@ -895,7 +931,12 @@
 
 		// If any of post_type, year, monthnum, or day are set, use them to refine the query.
 		if ( get_query_var( 'post_type' ) ) {
-			$where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
+			if ( is_array( get_query_var( 'post_type' ) ) ) {
+				// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
+				$where .= " AND post_type IN ('" . join( "', '", esc_sql( get_query_var( 'post_type' ) ) ) . "')";
+			} else {
+				$where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
+			}
 		} else {
 			$where .= " AND post_type IN ('" . implode( "', '", get_post_types( array( 'public' => true ) ) ) . "')";
 		}