[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> canonical.php (source)

   1  <?php
   2  /**
   3   * Canonical API to handle WordPress Redirecting
   4   *
   5   * Based on "Permalink Redirect" from Scott Yang and "Enforce www. Preference"
   6   * by Mark Jaquith
   7   *
   8   * @package WordPress
   9   * @since 2.3.0
  10   */
  11  
  12  /**
  13   * Redirects incoming links to the proper URL based on the site url.
  14   *
  15   * Search engines consider www.somedomain.com and somedomain.com to be two
  16   * different URLs when they both go to the same location. This SEO enhancement
  17   * prevents penalty for duplicate content by redirecting all incoming links to
  18   * one or the other.
  19   *
  20   * Prevents redirection for feeds, trackbacks, searches, and
  21   * admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7+,
  22   * page/post previews, WP admin, Trackbacks, robots.txt, favicon.ico, searches,
  23   * or on POST requests.
  24   *
  25   * Will also attempt to find the correct link when a user enters a URL that does
  26   * not exist based on exact WordPress query. Will instead try to parse the URL
  27   * or query in an attempt to figure the correct page to go to.
  28   *
  29   * @since 2.3.0
  30   *
  31   * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
  32   * @global bool       $is_IIS
  33   * @global WP_Query   $wp_query   WordPress Query object.
  34   * @global wpdb       $wpdb       WordPress database abstraction object.
  35   * @global WP         $wp         Current WordPress environment instance.
  36   *
  37   * @param string $requested_url Optional. The URL that was requested, used to
  38   *      figure if redirect is needed.
  39   * @param bool $do_redirect Optional. Redirect to the new URL.
  40   * @return string|void The string of the URL, if redirect needed.
  41   */
  42  function redirect_canonical( $requested_url = null, $do_redirect = true ) {
  43      global $wp_rewrite, $is_IIS, $wp_query, $wpdb, $wp;
  44  
  45      if ( isset( $_SERVER['REQUEST_METHOD'] ) && ! in_array( strtoupper( $_SERVER['REQUEST_METHOD'] ), array( 'GET', 'HEAD' ), true ) ) {
  46          return;
  47      }
  48  
  49      // If we're not in wp-admin and the post has been published and preview nonce
  50      // is non-existent or invalid then no need for preview in query.
  51      if ( is_preview() && get_query_var( 'p' ) && 'publish' == get_post_status( get_query_var( 'p' ) ) ) {
  52          if ( ! isset( $_GET['preview_id'] )
  53              || ! isset( $_GET['preview_nonce'] )
  54              || ! wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . (int) $_GET['preview_id'] ) ) {
  55              $wp_query->is_preview = false;
  56          }
  57      }
  58  
  59      if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || is_favicon() || ( $is_IIS && ! iis7_supports_permalinks() ) ) {
  60          return;
  61      }
  62  
  63      if ( ! $requested_url && isset( $_SERVER['HTTP_HOST'] ) ) {
  64          // Build the URL in the address bar.
  65          $requested_url  = is_ssl() ? 'https://' : 'http://';
  66          $requested_url .= $_SERVER['HTTP_HOST'];
  67          $requested_url .= $_SERVER['REQUEST_URI'];
  68      }
  69  
  70      $original = @parse_url( $requested_url );
  71      if ( false === $original ) {
  72          return;
  73      }
  74  
  75      $redirect     = $original;
  76      $redirect_url = false;
  77  
  78      // Notice fixing.
  79      if ( ! isset( $redirect['path'] ) ) {
  80          $redirect['path'] = '';
  81      }
  82      if ( ! isset( $redirect['query'] ) ) {
  83          $redirect['query'] = '';
  84      }
  85  
  86      /*
  87       * If the original URL ended with non-breaking spaces, they were almost
  88       * certainly inserted by accident. Let's remove them, so the reader doesn't
  89       * see a 404 error with no obvious cause.
  90       */
  91      $redirect['path'] = preg_replace( '|(%C2%A0)+$|i', '', $redirect['path'] );
  92  
  93      // It's not a preview, so remove it from URL.
  94      if ( get_query_var( 'preview' ) ) {
  95          $redirect['query'] = remove_query_arg( 'preview', $redirect['query'] );
  96      }
  97  
  98      $id = get_query_var( 'p' );
  99  
 100      if ( is_feed() && $id ) {
 101          $redirect_url = get_post_comments_feed_link( $id, get_query_var( 'feed' ) );
 102          if ( $redirect_url ) {
 103              $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type', 'feed' ), $redirect_url );
 104              $redirect['path']  = parse_url( $redirect_url, PHP_URL_PATH );
 105          }
 106      }
 107  
 108      if ( is_singular() && 1 > $wp_query->post_count && $id ) {
 109  
 110          $vars = $wpdb->get_results( $wpdb->prepare( "SELECT post_type, post_parent FROM $wpdb->posts WHERE ID = %d", $id ) );
 111  
 112          if ( ! empty( $vars[0] ) ) {
 113              $vars = $vars[0];
 114              if ( 'revision' == $vars->post_type && $vars->post_parent > 0 ) {
 115                  $id = $vars->post_parent;
 116              }
 117  
 118              $redirect_url = get_permalink( $id );
 119              if ( $redirect_url ) {
 120                  $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
 121              }
 122          }
 123      }
 124  
 125      // These tests give us a WP-generated permalink.
 126      if ( is_404() ) {
 127  
 128          // Redirect ?page_id, ?p=, ?attachment_id= to their respective URLs.
 129          $id            = max( get_query_var( 'p' ), get_query_var( 'page_id' ), get_query_var( 'attachment_id' ) );
 130          $redirect_post = $id ? get_post( $id ) : false;
 131          if ( $redirect_post ) {
 132              $post_type_obj = get_post_type_object( $redirect_post->post_type );
 133              if ( $post_type_obj->public && 'auto-draft' != $redirect_post->post_status ) {
 134                  $redirect_url      = get_permalink( $redirect_post );
 135                  $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
 136              }
 137          }
 138  
 139          if ( get_query_var( 'day' ) && get_query_var( 'monthnum' ) && get_query_var( 'year' ) ) {
 140              $year  = get_query_var( 'year' );
 141              $month = get_query_var( 'monthnum' );
 142              $day   = get_query_var( 'day' );
 143              $date  = sprintf( '%04d-%02d-%02d', $year, $month, $day );
 144              if ( ! wp_checkdate( $month, $day, $year, $date ) ) {
 145                  $redirect_url      = get_month_link( $year, $month );
 146                  $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'year', 'monthnum', 'day' ), $redirect_url );
 147              }
 148          } elseif ( get_query_var( 'monthnum' ) && get_query_var( 'year' ) && 12 < get_query_var( 'monthnum' ) ) {
 149              $redirect_url      = get_year_link( get_query_var( 'year' ) );
 150              $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'year', 'monthnum' ), $redirect_url );
 151          }
 152  
 153          if ( ! $redirect_url ) {
 154              $redirect_url = redirect_guess_404_permalink();
 155              if ( $redirect_url ) {
 156                  $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'page', 'feed', 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
 157              }
 158          }
 159  
 160          if ( get_query_var( 'page' ) && $wp_query->post &&
 161              false !== strpos( $wp_query->post->post_content, '<!--nextpage-->' ) ) {
 162              $redirect['path']  = rtrim( $redirect['path'], (int) get_query_var( 'page' ) . '/' );
 163              $redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
 164              $redirect_url      = get_permalink( $wp_query->post->ID );
 165          }
 166      } elseif ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) {
 167          // Rewriting of old ?p=X, ?m=2004, ?m=200401, ?m=20040101.
 168          if ( is_attachment() &&
 169              ! array_diff( array_keys( $wp->query_vars ), array( 'attachment', 'attachment_id' ) ) &&
 170              ! $redirect_url ) {
 171              if ( ! empty( $_GET['attachment_id'] ) ) {
 172                  $redirect_url = get_attachment_link( get_query_var( 'attachment_id' ) );
 173                  if ( $redirect_url ) {
 174                      $redirect['query'] = remove_query_arg( 'attachment_id', $redirect['query'] );
 175                  }
 176              } else {
 177                  $redirect_url = get_attachment_link();
 178              }
 179          } elseif ( is_single() && ! empty( $_GET['p'] ) && ! $redirect_url ) {
 180              $redirect_url = get_permalink( get_query_var( 'p' ) );
 181              if ( $redirect_url ) {
 182                  $redirect['query'] = remove_query_arg( array( 'p', 'post_type' ), $redirect['query'] );
 183              }
 184          } elseif ( is_single() && ! empty( $_GET['name'] ) && ! $redirect_url ) {
 185              $redirect_url = get_permalink( $wp_query->get_queried_object_id() );
 186              if ( $redirect_url ) {
 187                  $redirect['query'] = remove_query_arg( 'name', $redirect['query'] );
 188              }
 189          } elseif ( is_page() && ! empty( $_GET['page_id'] ) && ! $redirect_url ) {
 190              $redirect_url = get_permalink( get_query_var( 'page_id' ) );
 191              if ( $redirect_url ) {
 192                  $redirect['query'] = remove_query_arg( 'page_id', $redirect['query'] );
 193              }
 194          } elseif ( is_page() && ! is_feed() && 'page' == get_option( 'show_on_front' ) && get_queried_object_id() == get_option( 'page_on_front' ) && ! $redirect_url ) {
 195              $redirect_url = home_url( '/' );
 196          } elseif ( is_home() && ! empty( $_GET['page_id'] ) && 'page' == get_option( 'show_on_front' ) && get_query_var( 'page_id' ) == get_option( 'page_for_posts' ) && ! $redirect_url ) {
 197              $redirect_url = get_permalink( get_option( 'page_for_posts' ) );
 198              if ( $redirect_url ) {
 199                  $redirect['query'] = remove_query_arg( 'page_id', $redirect['query'] );
 200              }
 201          } elseif ( ! empty( $_GET['m'] ) && ( is_year() || is_month() || is_day() ) ) {
 202              $m = get_query_var( 'm' );
 203              switch ( strlen( $m ) ) {
 204                  case 4: // Yearly.
 205                      $redirect_url = get_year_link( $m );
 206                      break;
 207                  case 6: // Monthly.
 208                      $redirect_url = get_month_link( substr( $m, 0, 4 ), substr( $m, 4, 2 ) );
 209                      break;
 210                  case 8: // Daily.
 211                      $redirect_url = get_day_link( substr( $m, 0, 4 ), substr( $m, 4, 2 ), substr( $m, 6, 2 ) );
 212                      break;
 213              }
 214              if ( $redirect_url ) {
 215                  $redirect['query'] = remove_query_arg( 'm', $redirect['query'] );
 216              }
 217              // Now moving on to non ?m=X year/month/day links.
 218          } elseif ( is_day() && get_query_var( 'year' ) && get_query_var( 'monthnum' ) && ! empty( $_GET['day'] ) ) {
 219              $redirect_url = get_day_link( get_query_var( 'year' ), get_query_var( 'monthnum' ), get_query_var( 'day' ) );
 220              if ( $redirect_url ) {
 221                  $redirect['query'] = remove_query_arg( array( 'year', 'monthnum', 'day' ), $redirect['query'] );
 222              }
 223          } elseif ( is_month() && get_query_var( 'year' ) && ! empty( $_GET['monthnum'] ) ) {
 224              $redirect_url = get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) );
 225              if ( $redirect_url ) {
 226                  $redirect['query'] = remove_query_arg( array( 'year', 'monthnum' ), $redirect['query'] );
 227              }
 228          } elseif ( is_year() && ! empty( $_GET['year'] ) ) {
 229              $redirect_url = get_year_link( get_query_var( 'year' ) );
 230              if ( $redirect_url ) {
 231                  $redirect['query'] = remove_query_arg( 'year', $redirect['query'] );
 232              }
 233          } elseif ( is_author() && ! empty( $_GET['author'] ) && preg_match( '|^[0-9]+$|', $_GET['author'] ) ) {
 234              $author = get_userdata( get_query_var( 'author' ) );
 235              if ( ( false !== $author ) && $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 ) ) ) {
 236                  $redirect_url = get_author_posts_url( $author->ID, $author->user_nicename );
 237                  if ( $redirect_url ) {
 238                      $redirect['query'] = remove_query_arg( 'author', $redirect['query'] );
 239                  }
 240              }
 241          } elseif ( is_category() || is_tag() || is_tax() ) { // Terms (tags/categories).
 242  
 243              $term_count = 0;
 244              foreach ( $wp_query->tax_query->queried_terms as $tax_query ) {
 245                  $term_count += count( $tax_query['terms'] );
 246              }
 247  
 248              $obj = $wp_query->get_queried_object();
 249              if ( $term_count <= 1 && ! empty( $obj->term_id ) ) {
 250                  $tax_url = get_term_link( (int) $obj->term_id, $obj->taxonomy );
 251                  if ( $tax_url && ! is_wp_error( $tax_url ) ) {
 252                      if ( ! empty( $redirect['query'] ) ) {
 253                          // Strip taxonomy query vars off the URL.
 254                          $qv_remove = array( 'term', 'taxonomy' );
 255                          if ( is_category() ) {
 256                              $qv_remove[] = 'category_name';
 257                              $qv_remove[] = 'cat';
 258                          } elseif ( is_tag() ) {
 259                              $qv_remove[] = 'tag';
 260                              $qv_remove[] = 'tag_id';
 261                          } else {
 262                              // Custom taxonomies will have a custom query var, remove those too.
 263                              $tax_obj = get_taxonomy( $obj->taxonomy );
 264                              if ( false !== $tax_obj->query_var ) {
 265                                  $qv_remove[] = $tax_obj->query_var;
 266                              }
 267                          }
 268  
 269                          $rewrite_vars = array_diff( array_keys( $wp_query->query ), array_keys( $_GET ) );
 270  
 271                          // Check to see if all the query vars are coming from the rewrite, none are set via $_GET.
 272                          if ( ! array_diff( $rewrite_vars, array_keys( $_GET ) ) ) {
 273                              // Remove all of the per-tax query vars.
 274                              $redirect['query'] = remove_query_arg( $qv_remove, $redirect['query'] );
 275  
 276                              // Create the destination URL for this taxonomy.
 277                              $tax_url = parse_url( $tax_url );
 278                              if ( ! empty( $tax_url['query'] ) ) {
 279                                  // Taxonomy accessible via ?taxonomy=...&term=... or any custom query var.
 280                                  parse_str( $tax_url['query'], $query_vars );
 281                                  $redirect['query'] = add_query_arg( $query_vars, $redirect['query'] );
 282                              } else {
 283                                  // Taxonomy is accessible via a "pretty URL".
 284                                  $redirect['path'] = $tax_url['path'];
 285                              }
 286                          } else {
 287                              // Some query vars are set via $_GET. Unset those from $_GET that exist via the rewrite.
 288                              foreach ( $qv_remove as $_qv ) {
 289                                  if ( isset( $rewrite_vars[ $_qv ] ) ) {
 290                                      $redirect['query'] = remove_query_arg( $_qv, $redirect['query'] );
 291                                  }
 292                              }
 293                          }
 294                      }
 295                  }
 296              }
 297          } elseif ( is_single() && strpos( $wp_rewrite->permalink_structure, '%category%' ) !== false ) {
 298              $cat = get_query_var( 'category_name' );
 299              if ( $cat ) {
 300                  $category = get_category_by_path( $cat );
 301                  if ( ( ! $category || is_wp_error( $category ) ) || ! has_term( $category->term_id, 'category', $wp_query->get_queried_object_id() ) ) {
 302                      $redirect_url = get_permalink( $wp_query->get_queried_object_id() );
 303                  }
 304              }
 305          }
 306  
 307              // Post paging.
 308          if ( is_singular() && get_query_var( 'page' ) ) {
 309              if ( ! $redirect_url ) {
 310                  $redirect_url = get_permalink( get_queried_object_id() );
 311              }
 312  
 313              $page = get_query_var( 'page' );
 314              if ( $page > 1 ) {
 315                  if ( is_front_page() ) {
 316                      $redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( "$wp_rewrite->pagination_base/$page", 'paged' );
 317                  } else {
 318                      $redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( $page, 'single_paged' );
 319                  }
 320              }
 321                  $redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
 322          }
 323  
 324              // Paging and feeds.
 325          if ( get_query_var( 'paged' ) || is_feed() || get_query_var( 'cpage' ) ) {
 326              while ( preg_match( "#/$wp_rewrite->pagination_base/?[0-9]+?(/+)?$#", $redirect['path'] ) || preg_match( '#/(comments/?)?(feed|rss|rdf|atom|rss2)(/+)?$#', $redirect['path'] ) || preg_match( "#/{$wp_rewrite->comments_pagination_base}-[0-9]+(/+)?$#", $redirect['path'] ) ) {
 327                  // Strip off paging and feed.
 328                  $redirect['path'] = preg_replace( "#/$wp_rewrite->pagination_base/?[0-9]+?(/+)?$#", '/', $redirect['path'] ); // Strip off any existing paging.
 329                  $redirect['path'] = preg_replace( '#/(comments/?)?(feed|rss2?|rdf|atom)(/+|$)#', '/', $redirect['path'] ); // Strip off feed endings.
 330                  $redirect['path'] = preg_replace( "#/{$wp_rewrite->comments_pagination_base}-[0-9]+?(/+)?$#", '/', $redirect['path'] ); // Strip off any existing comment paging.
 331              }
 332  
 333              $addl_path = '';
 334              if ( is_feed() && in_array( get_query_var( 'feed' ), $wp_rewrite->feeds, true ) ) {
 335                  $addl_path = ! empty( $addl_path ) ? trailingslashit( $addl_path ) : '';
 336                  if ( ! is_singular() && get_query_var( 'withcomments' ) ) {
 337                      $addl_path .= 'comments/';
 338                  }
 339                  if ( ( 'rss' == get_default_feed() && 'feed' == get_query_var( 'feed' ) ) || 'rss' == get_query_var( 'feed' ) ) {
 340                      $addl_path .= user_trailingslashit( 'feed/' . ( ( get_default_feed() == 'rss2' ) ? '' : 'rss2' ), 'feed' );
 341                  } else {
 342                      $addl_path .= user_trailingslashit( 'feed/' . ( ( get_default_feed() == get_query_var( 'feed' ) || 'feed' == get_query_var( 'feed' ) ) ? '' : get_query_var( 'feed' ) ), 'feed' );
 343                  }
 344                  $redirect['query'] = remove_query_arg( 'feed', $redirect['query'] );
 345              } elseif ( is_feed() && 'old' == get_query_var( 'feed' ) ) {
 346                  $old_feed_files = array(
 347                      'wp-atom.php'         => 'atom',
 348                      'wp-commentsrss2.php' => 'comments_rss2',
 349                      'wp-feed.php'         => get_default_feed(),
 350                      'wp-rdf.php'          => 'rdf',
 351                      'wp-rss.php'          => 'rss2',
 352                      'wp-rss2.php'         => 'rss2',
 353                  );
 354                  if ( isset( $old_feed_files[ basename( $redirect['path'] ) ] ) ) {
 355                      $redirect_url = get_feed_link( $old_feed_files[ basename( $redirect['path'] ) ] );
 356                      wp_redirect( $redirect_url, 301 );
 357                      die();
 358                  }
 359              }
 360  
 361              if ( get_query_var( 'paged' ) > 0 ) {
 362                  $paged             = get_query_var( 'paged' );
 363                  $redirect['query'] = remove_query_arg( 'paged', $redirect['query'] );
 364                  if ( ! is_feed() ) {
 365                      if ( $paged > 1 && ! is_single() ) {
 366                          $addl_path = ( ! empty( $addl_path ) ? trailingslashit( $addl_path ) : '' ) . user_trailingslashit( "$wp_rewrite->pagination_base/$paged", 'paged' );
 367                      } elseif ( ! is_single() ) {
 368                          $addl_path = ! empty( $addl_path ) ? trailingslashit( $addl_path ) : '';
 369                      }
 370                  } elseif ( $paged > 1 ) {
 371                      $redirect['query'] = add_query_arg( 'paged', $paged, $redirect['query'] );
 372                  }
 373              }
 374  
 375              if ( get_option( 'page_comments' ) && (
 376              ( 'newest' == get_option( 'default_comments_page' ) && get_query_var( 'cpage' ) > 0 ) ||
 377              ( 'newest' != get_option( 'default_comments_page' ) && get_query_var( 'cpage' ) > 1 )
 378              ) ) {
 379                  $addl_path         = ( ! empty( $addl_path ) ? trailingslashit( $addl_path ) : '' ) . user_trailingslashit( $wp_rewrite->comments_pagination_base . '-' . get_query_var( 'cpage' ), 'commentpaged' );
 380                  $redirect['query'] = remove_query_arg( 'cpage', $redirect['query'] );
 381              }
 382  
 383              $redirect['path'] = user_trailingslashit( preg_replace( '|/' . preg_quote( $wp_rewrite->index, '|' ) . '/?$|', '/', $redirect['path'] ) ); // Strip off trailing /index.php/.
 384              if ( ! empty( $addl_path ) && $wp_rewrite->using_index_permalinks() && strpos( $redirect['path'], '/' . $wp_rewrite->index . '/' ) === false ) {
 385                  $redirect['path'] = trailingslashit( $redirect['path'] ) . $wp_rewrite->index . '/';
 386              }
 387              if ( ! empty( $addl_path ) ) {
 388                  $redirect['path'] = trailingslashit( $redirect['path'] ) . $addl_path;
 389              }
 390              $redirect_url = $redirect['scheme'] . '://' . $redirect['host'] . $redirect['path'];
 391          }
 392  
 393          if ( 'wp-register.php' == basename( $redirect['path'] ) ) {
 394              if ( is_multisite() ) {
 395                  /** This filter is documented in wp-login.php */
 396                  $redirect_url = apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) );
 397              } else {
 398                  $redirect_url = wp_registration_url();
 399              }
 400  
 401              wp_redirect( $redirect_url, 301 );
 402              die();
 403          }
 404      }
 405  
 406      // Tack on any additional query vars.
 407      $redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] );
 408      if ( $redirect_url && ! empty( $redirect['query'] ) ) {
 409          parse_str( $redirect['query'], $_parsed_query );
 410          $redirect = @parse_url( $redirect_url );
 411  
 412          if ( ! empty( $_parsed_query['name'] ) && ! empty( $redirect['query'] ) ) {
 413              parse_str( $redirect['query'], $_parsed_redirect_query );
 414  
 415              if ( empty( $_parsed_redirect_query['name'] ) ) {
 416                  unset( $_parsed_query['name'] );
 417              }
 418          }
 419  
 420          $_parsed_query = array_combine(
 421              rawurlencode_deep( array_keys( $_parsed_query ) ),
 422              rawurlencode_deep( array_values( $_parsed_query ) )
 423          );
 424          $redirect_url  = add_query_arg( $_parsed_query, $redirect_url );
 425      }
 426  
 427      if ( $redirect_url ) {
 428          $redirect = @parse_url( $redirect_url );
 429      }
 430  
 431      // www.example.com vs. example.com
 432      $user_home = @parse_url( home_url() );
 433      if ( ! empty( $user_home['host'] ) ) {
 434          $redirect['host'] = $user_home['host'];
 435      }
 436      if ( empty( $user_home['path'] ) ) {
 437          $user_home['path'] = '/';
 438      }
 439  
 440      // Handle ports.
 441      if ( ! empty( $user_home['port'] ) ) {
 442          $redirect['port'] = $user_home['port'];
 443      } else {
 444          unset( $redirect['port'] );
 445      }
 446  
 447      // Trailing /index.php.
 448      $redirect['path'] = preg_replace( '|/' . preg_quote( $wp_rewrite->index, '|' ) . '/*?$|', '/', $redirect['path'] );
 449  
 450      $punctuation_pattern = implode(
 451          '|',
 452          array_map(
 453              'preg_quote',
 454              array(
 455                  ' ',
 456                  '%20',  // Space.
 457                  '!',
 458                  '%21',  // Exclamation mark.
 459                  '"',
 460                  '%22',  // Double quote.
 461                  "'",
 462                  '%27',  // Single quote.
 463                  '(',
 464                  '%28',  // Opening bracket.
 465                  ')',
 466                  '%29',  // Closing bracket.
 467                  ',',
 468                  '%2C',  // Comma.
 469                  '.',
 470                  '%2E',  // Period.
 471                  ';',
 472                  '%3B',  // Semicolon.
 473                  '{',
 474                  '%7B',  // Opening curly bracket.
 475                  '}',
 476                  '%7D',  // Closing curly bracket.
 477                  '%E2%80%9C', // Opening curly quote.
 478                  '%E2%80%9D', // Closing curly quote.
 479              )
 480          )
 481      );
 482  
 483      // Remove trailing spaces and end punctuation from the path.
 484      $redirect['path'] = preg_replace( "#($punctuation_pattern)+$#", '', $redirect['path'] );
 485  
 486      if ( ! empty( $redirect['query'] ) ) {
 487          // Remove trailing spaces and end punctuation from certain terminating query string args.
 488          $redirect['query'] = preg_replace( "#((^|&)(p|page_id|cat|tag)=[^&]*?)($punctuation_pattern)+$#", '$1', $redirect['query'] );
 489  
 490          // Clean up empty query strings.
 491          $redirect['query'] = trim( preg_replace( '#(^|&)(p|page_id|cat|tag)=?(&|$)#', '&', $redirect['query'] ), '&' );
 492  
 493          // Redirect obsolete feeds.
 494          $redirect['query'] = preg_replace( '#(^|&)feed=rss(&|$)#', '$1feed=rss2$2', $redirect['query'] );
 495  
 496          // Remove redundant leading ampersands.
 497          $redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] );
 498      }
 499  
 500      // Strip /index.php/ when we're not using PATHINFO permalinks.
 501      if ( ! $wp_rewrite->using_index_permalinks() ) {
 502          $redirect['path'] = str_replace( '/' . $wp_rewrite->index . '/', '/', $redirect['path'] );
 503      }
 504  
 505      // Trailing slashes.
 506      if ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() && ! is_404() && ( ! is_front_page() || ( is_front_page() && ( get_query_var( 'paged' ) > 1 ) ) ) ) {
 507          $user_ts_type = '';
 508          if ( get_query_var( 'paged' ) > 0 ) {
 509              $user_ts_type = 'paged';
 510          } else {
 511              foreach ( array( 'single', 'category', 'page', 'day', 'month', 'year', 'home' ) as $type ) {
 512                  $func = 'is_' . $type;
 513                  if ( call_user_func( $func ) ) {
 514                      $user_ts_type = $type;
 515                      break;
 516                  }
 517              }
 518          }
 519          $redirect['path'] = user_trailingslashit( $redirect['path'], $user_ts_type );
 520      } elseif ( is_front_page() ) {
 521          $redirect['path'] = trailingslashit( $redirect['path'] );
 522      }
 523  
 524      // Strip multiple slashes out of the URL.
 525      if ( strpos( $redirect['path'], '//' ) > -1 ) {
 526          $redirect['path'] = preg_replace( '|/+|', '/', $redirect['path'] );
 527      }
 528  
 529      // Always trailing slash the Front Page URL.
 530      if ( trailingslashit( $redirect['path'] ) == trailingslashit( $user_home['path'] ) ) {
 531          $redirect['path'] = trailingslashit( $redirect['path'] );
 532      }
 533  
 534      // Ignore differences in host capitalization, as this can lead to infinite redirects.
 535      // Only redirect no-www <=> yes-www.
 536      if ( strtolower( $original['host'] ) == strtolower( $redirect['host'] ) ||
 537          ( strtolower( $original['host'] ) != 'www.' . strtolower( $redirect['host'] ) && 'www.' . strtolower( $original['host'] ) != strtolower( $redirect['host'] ) ) ) {
 538          $redirect['host'] = $original['host'];
 539      }
 540  
 541      $compare_original = array( $original['host'], $original['path'] );
 542  
 543      if ( ! empty( $original['port'] ) ) {
 544          $compare_original[] = $original['port'];
 545      }
 546  
 547      if ( ! empty( $original['query'] ) ) {
 548          $compare_original[] = $original['query'];
 549      }
 550  
 551      $compare_redirect = array( $redirect['host'], $redirect['path'] );
 552  
 553      if ( ! empty( $redirect['port'] ) ) {
 554          $compare_redirect[] = $redirect['port'];
 555      }
 556  
 557      if ( ! empty( $redirect['query'] ) ) {
 558          $compare_redirect[] = $redirect['query'];
 559      }
 560  
 561      if ( $compare_original !== $compare_redirect ) {
 562          $redirect_url = $redirect['scheme'] . '://' . $redirect['host'];
 563          if ( ! empty( $redirect['port'] ) ) {
 564              $redirect_url .= ':' . $redirect['port'];
 565          }
 566          $redirect_url .= $redirect['path'];
 567          if ( ! empty( $redirect['query'] ) ) {
 568              $redirect_url .= '?' . $redirect['query'];
 569          }
 570      }
 571  
 572      if ( ! $redirect_url || $redirect_url == $requested_url ) {
 573          return;
 574      }
 575  
 576      // Hex encoded octets are case-insensitive.
 577      if ( false !== strpos( $requested_url, '%' ) ) {
 578          if ( ! function_exists( 'lowercase_octets' ) ) {
 579              /**
 580               * Converts the first hex-encoded octet match to lowercase.
 581               *
 582               * @since 3.1.0
 583               * @ignore
 584               *
 585               * @param array $matches Hex-encoded octet matches for the requested URL.
 586               * @return string Lowercased version of the first match.
 587               */
 588  			function lowercase_octets( $matches ) {
 589                  return strtolower( $matches[0] );
 590              }
 591          }
 592          $requested_url = preg_replace_callback( '|%[a-fA-F0-9][a-fA-F0-9]|', 'lowercase_octets', $requested_url );
 593      }
 594  
 595      /**
 596       * Filters the canonical redirect URL.
 597       *
 598       * Returning false to this filter will cancel the redirect.
 599       *
 600       * @since 2.3.0
 601       *
 602       * @param string $redirect_url  The redirect URL.
 603       * @param string $requested_url The requested URL.
 604       */
 605      $redirect_url = apply_filters( 'redirect_canonical', $redirect_url, $requested_url );
 606  
 607      // Yes, again -- in case the filter aborted the request.
 608      if ( ! $redirect_url || strip_fragment_from_url( $redirect_url ) == strip_fragment_from_url( $requested_url ) ) {
 609          return;
 610      }
 611  
 612      if ( $do_redirect ) {
 613          // Protect against chained redirects.
 614          if ( ! redirect_canonical( $redirect_url, false ) ) {
 615              wp_redirect( $redirect_url, 301 );
 616              exit();
 617          } else {
 618              // Debug.
 619              // die("1: $redirect_url<br />2: " . redirect_canonical( $redirect_url, false ) );
 620              return;
 621          }
 622      } else {
 623          return $redirect_url;
 624      }
 625  }
 626  
 627  /**
 628   * Removes arguments from a query string if they are not present in a URL
 629   * DO NOT use this in plugin code.
 630   *
 631   * @since 3.4.0
 632   * @access private
 633   *
 634   * @param string $query_string
 635   * @param array $args_to_check
 636   * @param string $url
 637   * @return string The altered query string
 638   */
 639  function _remove_qs_args_if_not_in_url( $query_string, array $args_to_check, $url ) {
 640      $parsed_url = @parse_url( $url );
 641      if ( ! empty( $parsed_url['query'] ) ) {
 642          parse_str( $parsed_url['query'], $parsed_query );
 643          foreach ( $args_to_check as $qv ) {
 644              if ( ! isset( $parsed_query[ $qv ] ) ) {
 645                  $query_string = remove_query_arg( $qv, $query_string );
 646              }
 647          }
 648      } else {
 649          $query_string = remove_query_arg( $args_to_check, $query_string );
 650      }
 651      return $query_string;
 652  }
 653  
 654  /**
 655   * Strips the #fragment from a URL, if one is present.
 656   *
 657   * @since 4.4.0
 658   *
 659   * @param string $url The URL to strip.
 660   * @return string The altered URL.
 661   */
 662  function strip_fragment_from_url( $url ) {
 663      $parsed_url = @parse_url( $url );
 664      if ( ! empty( $parsed_url['host'] ) ) {
 665          // This mirrors code in redirect_canonical(). It does not handle every case.
 666          $url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
 667          if ( ! empty( $parsed_url['port'] ) ) {
 668              $url .= ':' . $parsed_url['port'];
 669          }
 670  
 671          if ( ! empty( $parsed_url['path'] ) ) {
 672              $url .= $parsed_url['path'];
 673          }
 674  
 675          if ( ! empty( $parsed_url['query'] ) ) {
 676              $url .= '?' . $parsed_url['query'];
 677          }
 678      }
 679  
 680      return $url;
 681  }
 682  
 683  /**
 684   * Attempts to guess the correct URL based on query vars
 685   *
 686   * @since 2.3.0
 687   *
 688   * @global wpdb $wpdb WordPress database abstraction object.
 689   *
 690   * @return string|false The correct URL if one is found. False on failure.
 691   */
 692  function redirect_guess_404_permalink() {
 693      global $wpdb;
 694  
 695      if ( get_query_var( 'name' ) ) {
 696          $where = $wpdb->prepare( 'post_name LIKE %s', $wpdb->esc_like( get_query_var( 'name' ) ) . '%' );
 697  
 698          // If any of post_type, year, monthnum, or day are set, use them to refine the query.
 699          if ( get_query_var( 'post_type' ) ) {
 700              $where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
 701          } else {
 702              $where .= " AND post_type IN ('" . implode( "', '", get_post_types( array( 'public' => true ) ) ) . "')";
 703          }
 704  
 705          if ( get_query_var( 'year' ) ) {
 706              $where .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) );
 707          }
 708          if ( get_query_var( 'monthnum' ) ) {
 709              $where .= $wpdb->prepare( ' AND MONTH(post_date) = %d', get_query_var( 'monthnum' ) );
 710          }
 711          if ( get_query_var( 'day' ) ) {
 712              $where .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) );
 713          }
 714  
 715          $post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE $where AND post_status = 'publish'" );
 716          if ( ! $post_id ) {
 717              return false;
 718          }
 719          if ( get_query_var( 'feed' ) ) {
 720              return get_post_comments_feed_link( $post_id, get_query_var( 'feed' ) );
 721          } elseif ( get_query_var( 'page' ) && 1 < get_query_var( 'page' ) ) {
 722              return trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' );
 723          } else {
 724              return get_permalink( $post_id );
 725          }
 726      }
 727  
 728      return false;
 729  }
 730  
 731  /**
 732   * Redirects a variety of shorthand URLs to the admin.
 733   *
 734   * If a user visits example.com/admin, they'll be redirected to /wp-admin.
 735   * Visiting /login redirects to /wp-login.php, and so on.
 736   *
 737   * @since 3.4.0
 738   *
 739   * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
 740   */
 741  function wp_redirect_admin_locations() {
 742      global $wp_rewrite;
 743      if ( ! ( is_404() && $wp_rewrite->using_permalinks() ) ) {
 744          return;
 745      }
 746  
 747      $admins = array(
 748          home_url( 'wp-admin', 'relative' ),
 749          home_url( 'dashboard', 'relative' ),
 750          home_url( 'admin', 'relative' ),
 751          site_url( 'dashboard', 'relative' ),
 752          site_url( 'admin', 'relative' ),
 753      );
 754      if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $admins, true ) ) {
 755          wp_redirect( admin_url() );
 756          exit;
 757      }
 758  
 759      $logins = array(
 760          home_url( 'wp-login.php', 'relative' ),
 761          home_url( 'login', 'relative' ),
 762          site_url( 'login', 'relative' ),
 763      );
 764      if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $logins, true ) ) {
 765          wp_redirect( wp_login_url() );
 766          exit;
 767      }
 768  }


Generated: Fri Apr 10 01:00:03 2020 Cross-referenced by PHPXref 0.7.1