wp/wp-includes/canonical.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    44 
    44 
    45 	if ( isset( $_SERVER['REQUEST_METHOD'] ) && ! in_array( strtoupper( $_SERVER['REQUEST_METHOD'] ), array( 'GET', 'HEAD' ), true ) ) {
    45 	if ( isset( $_SERVER['REQUEST_METHOD'] ) && ! in_array( strtoupper( $_SERVER['REQUEST_METHOD'] ), array( 'GET', 'HEAD' ), true ) ) {
    46 		return;
    46 		return;
    47 	}
    47 	}
    48 
    48 
    49 	// If we're not in wp-admin and the post has been published and preview nonce
    49 	/*
    50 	// is non-existent or invalid then no need for preview in query.
    50 	 * If we're not in wp-admin and the post has been published and preview nonce
       
    51 	 * is non-existent or invalid then no need for preview in query.
       
    52 	 */
    51 	if ( is_preview() && get_query_var( 'p' ) && 'publish' === get_post_status( get_query_var( 'p' ) ) ) {
    53 	if ( is_preview() && get_query_var( 'p' ) && 'publish' === get_post_status( get_query_var( 'p' ) ) ) {
    52 		if ( ! isset( $_GET['preview_id'] )
    54 		if ( ! isset( $_GET['preview_id'] )
    53 			|| ! isset( $_GET['preview_nonce'] )
    55 			|| ! isset( $_GET['preview_nonce'] )
    54 			|| ! wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . (int) $_GET['preview_id'] )
    56 			|| ! wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . (int) $_GET['preview_id'] )
    55 		) {
    57 		) {
   312 
   314 
   313 				if ( $redirect_url ) {
   315 				if ( $redirect_url ) {
   314 					$redirect['query'] = remove_query_arg( 'year', $redirect['query'] );
   316 					$redirect['query'] = remove_query_arg( 'year', $redirect['query'] );
   315 				}
   317 				}
   316 			}
   318 			}
   317 		} elseif ( is_author() && ! empty( $_GET['author'] ) && preg_match( '|^[0-9]+$|', $_GET['author'] ) ) {
   319 		} elseif ( is_author() && ! empty( $_GET['author'] )
       
   320 			&& is_string( $_GET['author'] ) && preg_match( '|^[0-9]+$|', $_GET['author'] )
       
   321 		) {
   318 			$author = get_userdata( get_query_var( 'author' ) );
   322 			$author = get_userdata( get_query_var( 'author' ) );
   319 
   323 
   320 			if ( false !== $author
   324 			if ( false !== $author
   321 				&& $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 ) )
   325 				&& $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 ) )
   322 			) {
   326 			) {
   329 			}
   333 			}
   330 		} elseif ( is_category() || is_tag() || is_tax() ) { // Terms (tags/categories).
   334 		} elseif ( is_category() || is_tag() || is_tax() ) { // Terms (tags/categories).
   331 			$term_count = 0;
   335 			$term_count = 0;
   332 
   336 
   333 			foreach ( $wp_query->tax_query->queried_terms as $tax_query ) {
   337 			foreach ( $wp_query->tax_query->queried_terms as $tax_query ) {
   334 				$term_count += count( $tax_query['terms'] );
   338 				if ( isset( $tax_query['terms'] ) && is_countable( $tax_query['terms'] ) ) {
       
   339 					$term_count += count( $tax_query['terms'] );
       
   340 				}
   335 			}
   341 			}
   336 
   342 
   337 			$obj = $wp_query->get_queried_object();
   343 			$obj = $wp_query->get_queried_object();
   338 
   344 
   339 			if ( $term_count <= 1 && ! empty( $obj->term_id ) ) {
   345 			if ( $term_count <= 1 && ! empty( $obj->term_id ) ) {
   385 							}
   391 							}
   386 						}
   392 						}
   387 					}
   393 					}
   388 				}
   394 				}
   389 			}
   395 			}
   390 		} elseif ( is_single() && strpos( $wp_rewrite->permalink_structure, '%category%' ) !== false ) {
   396 		} elseif ( is_single() && str_contains( $wp_rewrite->permalink_structure, '%category%' ) ) {
   391 			$category_name = get_query_var( 'category_name' );
   397 			$category_name = get_query_var( 'category_name' );
   392 
   398 
   393 			if ( $category_name ) {
   399 			if ( $category_name ) {
   394 				$category = get_category_by_path( $category_name );
   400 				$category = get_category_by_path( $category_name );
   395 
   401 
   514 			$redirect['path'] = preg_replace( '|/' . preg_quote( $wp_rewrite->index, '|' ) . '/?$|', '/', $redirect['path'] );
   520 			$redirect['path'] = preg_replace( '|/' . preg_quote( $wp_rewrite->index, '|' ) . '/?$|', '/', $redirect['path'] );
   515 			$redirect['path'] = user_trailingslashit( $redirect['path'] );
   521 			$redirect['path'] = user_trailingslashit( $redirect['path'] );
   516 
   522 
   517 			if ( ! empty( $addl_path )
   523 			if ( ! empty( $addl_path )
   518 				&& $wp_rewrite->using_index_permalinks()
   524 				&& $wp_rewrite->using_index_permalinks()
   519 				&& strpos( $redirect['path'], '/' . $wp_rewrite->index . '/' ) === false
   525 				&& ! str_contains( $redirect['path'], '/' . $wp_rewrite->index . '/' )
   520 			) {
   526 			) {
   521 				$redirect['path'] = trailingslashit( $redirect['path'] ) . $wp_rewrite->index . '/';
   527 				$redirect['path'] = trailingslashit( $redirect['path'] ) . $wp_rewrite->index . '/';
   522 			}
   528 			}
   523 
   529 
   524 			if ( ! empty( $addl_path ) ) {
   530 			if ( ! empty( $addl_path ) ) {
   537 			}
   543 			}
   538 
   544 
   539 			wp_redirect( $redirect_url, 301 );
   545 			wp_redirect( $redirect_url, 301 );
   540 			die();
   546 			die();
   541 		}
   547 		}
       
   548 	}
       
   549 
       
   550 	$is_attachment_redirect = false;
       
   551 
       
   552 	if ( is_attachment() && ! get_option( 'wp_attachment_pages_enabled' ) ) {
       
   553 		$attachment_id        = get_query_var( 'attachment_id' );
       
   554 		$attachment_post      = get_post( $attachment_id );
       
   555 		$attachment_parent_id = $attachment_post ? $attachment_post->post_parent : 0;
       
   556 
       
   557 		$attachment_url = wp_get_attachment_url( $attachment_id );
       
   558 		if ( $attachment_url !== $redirect_url ) {
       
   559 			/*
       
   560 			* If an attachment is attached to a post, it inherits the parent post's status. Fetch the
       
   561 			* parent post to check its status later.
       
   562 			*/
       
   563 			if ( $attachment_parent_id ) {
       
   564 				$redirect_obj = get_post( $attachment_parent_id );
       
   565 			}
       
   566 			$redirect_url = $attachment_url;
       
   567 		}
       
   568 
       
   569 		$is_attachment_redirect = true;
   542 	}
   570 	}
   543 
   571 
   544 	$redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] );
   572 	$redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] );
   545 
   573 
   546 	// Tack on any additional query vars.
   574 	// Tack on any additional query vars.
   644 		$redirect['path'] = str_replace( '/' . $wp_rewrite->index . '/', '/', $redirect['path'] );
   672 		$redirect['path'] = str_replace( '/' . $wp_rewrite->index . '/', '/', $redirect['path'] );
   645 	}
   673 	}
   646 
   674 
   647 	// Trailing slashes.
   675 	// Trailing slashes.
   648 	if ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks()
   676 	if ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks()
       
   677 		&& ! $is_attachment_redirect
   649 		&& ! is_404() && ( ! is_front_page() || is_front_page() && get_query_var( 'paged' ) > 1 )
   678 		&& ! is_404() && ( ! is_front_page() || is_front_page() && get_query_var( 'paged' ) > 1 )
   650 	) {
   679 	) {
   651 		$user_ts_type = '';
   680 		$user_ts_type = '';
   652 
   681 
   653 		if ( get_query_var( 'paged' ) > 0 ) {
   682 		if ( get_query_var( 'paged' ) > 0 ) {
   673 	) {
   702 	) {
   674 		$redirect['path'] = untrailingslashit( $redirect['path'] );
   703 		$redirect['path'] = untrailingslashit( $redirect['path'] );
   675 	}
   704 	}
   676 
   705 
   677 	// Strip multiple slashes out of the URL.
   706 	// Strip multiple slashes out of the URL.
   678 	if ( strpos( $redirect['path'], '//' ) > -1 ) {
   707 	if ( str_contains( $redirect['path'], '//' ) ) {
   679 		$redirect['path'] = preg_replace( '|/+|', '/', $redirect['path'] );
   708 		$redirect['path'] = preg_replace( '|/+|', '/', $redirect['path'] );
   680 	}
   709 	}
   681 
   710 
   682 	// Always trailing slash the Front Page URL.
   711 	// Always trailing slash the Front Page URL.
   683 	if ( trailingslashit( $redirect['path'] ) === trailingslashit( $user_home['path'] ) ) {
   712 	if ( trailingslashit( $redirect['path'] ) === trailingslashit( $user_home['path'] ) ) {
   685 	}
   714 	}
   686 
   715 
   687 	$original_host_low = strtolower( $original['host'] );
   716 	$original_host_low = strtolower( $original['host'] );
   688 	$redirect_host_low = strtolower( $redirect['host'] );
   717 	$redirect_host_low = strtolower( $redirect['host'] );
   689 
   718 
   690 	// Ignore differences in host capitalization, as this can lead to infinite redirects.
   719 	/*
   691 	// Only redirect no-www <=> yes-www.
   720 	 * Ignore differences in host capitalization, as this can lead to infinite redirects.
       
   721 	 * Only redirect no-www <=> yes-www.
       
   722 	 */
   692 	if ( $original_host_low === $redirect_host_low
   723 	if ( $original_host_low === $redirect_host_low
   693 		|| ( 'www.' . $original_host_low !== $redirect_host_low
   724 		|| ( 'www.' . $original_host_low !== $redirect_host_low
   694 			&& 'www.' . $redirect_host_low !== $original_host_low )
   725 			&& 'www.' . $redirect_host_low !== $original_host_low )
   695 	) {
   726 	) {
   696 		$redirect['host'] = $original['host'];
   727 		$redirect['host'] = $original['host'];
   732 
   763 
   733 	if ( ! $redirect_url || $redirect_url === $requested_url ) {
   764 	if ( ! $redirect_url || $redirect_url === $requested_url ) {
   734 		return;
   765 		return;
   735 	}
   766 	}
   736 
   767 
   737 	// Hex encoded octets are case-insensitive.
   768 	// Hex-encoded octets are case-insensitive.
   738 	if ( false !== strpos( $requested_url, '%' ) ) {
   769 	if ( str_contains( $requested_url, '%' ) ) {
   739 		if ( ! function_exists( 'lowercase_octets' ) ) {
   770 		if ( ! function_exists( 'lowercase_octets' ) ) {
   740 			/**
   771 			/**
   741 			 * Converts the first hex-encoded octet match to lowercase.
   772 			 * Converts the first hex-encoded octet match to lowercase.
   742 			 *
   773 			 *
   743 			 * @since 3.1.0
   774 			 * @since 3.1.0
   916 	if ( null !== $pre ) {
   947 	if ( null !== $pre ) {
   917 		return $pre;
   948 		return $pre;
   918 	}
   949 	}
   919 
   950 
   920 	if ( get_query_var( 'name' ) ) {
   951 	if ( get_query_var( 'name' ) ) {
       
   952 		$publicly_viewable_statuses   = array_filter( get_post_stati(), 'is_post_status_viewable' );
       
   953 		$publicly_viewable_post_types = array_filter( get_post_types( array( 'exclude_from_search' => false ) ), 'is_post_type_viewable' );
       
   954 
   921 		/**
   955 		/**
   922 		 * Filters whether to perform a strict guess for a 404 redirect.
   956 		 * Filters whether to perform a strict guess for a 404 redirect.
   923 		 *
   957 		 *
   924 		 * Returning a truthy value from the filter will redirect only exact post_name matches.
   958 		 * Returning a truthy value from the filter will redirect only exact post_name matches.
   925 		 *
   959 		 *
   936 		}
   970 		}
   937 
   971 
   938 		// If any of post_type, year, monthnum, or day are set, use them to refine the query.
   972 		// If any of post_type, year, monthnum, or day are set, use them to refine the query.
   939 		if ( get_query_var( 'post_type' ) ) {
   973 		if ( get_query_var( 'post_type' ) ) {
   940 			if ( is_array( get_query_var( 'post_type' ) ) ) {
   974 			if ( is_array( get_query_var( 'post_type' ) ) ) {
   941 				// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
   975 				$post_types = array_intersect( get_query_var( 'post_type' ), $publicly_viewable_post_types );
       
   976 				if ( empty( $post_types ) ) {
       
   977 					return false;
       
   978 				}
   942 				$where .= " AND post_type IN ('" . join( "', '", esc_sql( get_query_var( 'post_type' ) ) ) . "')";
   979 				$where .= " AND post_type IN ('" . join( "', '", esc_sql( get_query_var( 'post_type' ) ) ) . "')";
   943 			} else {
   980 			} else {
       
   981 				if ( ! in_array( get_query_var( 'post_type' ), $publicly_viewable_post_types, true ) ) {
       
   982 					return false;
       
   983 				}
   944 				$where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
   984 				$where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
   945 			}
   985 			}
   946 		} else {
   986 		} else {
   947 			$where .= " AND post_type IN ('" . implode( "', '", get_post_types( array( 'public' => true ) ) ) . "')";
   987 			$where .= " AND post_type IN ('" . implode( "', '", esc_sql( $publicly_viewable_post_types ) ) . "')";
   948 		}
   988 		}
   949 
   989 
   950 		if ( get_query_var( 'year' ) ) {
   990 		if ( get_query_var( 'year' ) ) {
   951 			$where .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) );
   991 			$where .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) );
   952 		}
   992 		}
   955 		}
   995 		}
   956 		if ( get_query_var( 'day' ) ) {
   996 		if ( get_query_var( 'day' ) ) {
   957 			$where .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) );
   997 			$where .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) );
   958 		}
   998 		}
   959 
   999 
   960 		$publicly_viewable_statuses = array_filter( get_post_stati(), 'is_post_status_viewable' );
       
   961 		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
  1000 		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
   962 		$post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE $where AND post_status IN ('" . implode( "', '", esc_sql( $publicly_viewable_statuses ) ) . "')" );
  1001 		$post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE $where AND post_status IN ('" . implode( "', '", esc_sql( $publicly_viewable_statuses ) ) . "')" );
   963 
  1002 
   964 		if ( ! $post_id ) {
  1003 		if ( ! $post_id ) {
   965 			return false;
  1004 			return false;
  1007 		exit;
  1046 		exit;
  1008 	}
  1047 	}
  1009 
  1048 
  1010 	$logins = array(
  1049 	$logins = array(
  1011 		home_url( 'wp-login.php', 'relative' ),
  1050 		home_url( 'wp-login.php', 'relative' ),
       
  1051 		home_url( 'login.php', 'relative' ),
  1012 		home_url( 'login', 'relative' ),
  1052 		home_url( 'login', 'relative' ),
  1013 		site_url( 'login', 'relative' ),
  1053 		site_url( 'login', 'relative' ),
  1014 	);
  1054 	);
  1015 
  1055 
  1016 	if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $logins, true ) ) {
  1056 	if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $logins, true ) ) {