Beispiel #1
0
 /**
  * Parse request to find correct WordPress query.
  *
  * Sets up the query variables based on the request. There are also many
  * filters and actions that can be used to further manipulate the result.
  *
  * @since 2.0.0
  *
  * @global WP_Rewrite $wp_rewrite
  *
  * @param array|string $extra_query_vars Set the extra query variables.
  */
 public function parse_request($extra_query_vars = '')
 {
     global $wp_rewrite;
     /**
      * Filter whether to parse the request.
      *
      * @since 3.5.0
      *
      * @param bool         $bool             Whether or not to parse the request. Default true.
      * @param WP           $this             Current WordPress environment instance.
      * @param array|string $extra_query_vars Extra passed query variables.
      */
     if (!apply_filters('do_parse_request', true, $this, $extra_query_vars)) {
         return;
     }
     $this->query_vars = array();
     $post_type_query_vars = array();
     if (is_array($extra_query_vars)) {
         $this->extra_query_vars =& $extra_query_vars;
     } elseif (!empty($extra_query_vars)) {
         parse_str($extra_query_vars, $this->extra_query_vars);
     }
     // Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
     // Fetch the rewrite rules.
     $rewrite = $wp_rewrite->wp_rewrite_rules();
     if (!empty($rewrite)) {
         // If we match a rewrite rule, this will be cleared.
         $error = '404';
         $this->did_permalink = true;
         $pathinfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
         list($pathinfo) = explode('?', $pathinfo);
         $pathinfo = str_replace("%", "%25", $pathinfo);
         list($req_uri) = explode('?', $_SERVER['REQUEST_URI']);
         $self = $_SERVER['PHP_SELF'];
         $home_path = trim(parse_url(home_url(), PHP_URL_PATH), '/');
         $home_path_regex = sprintf('|^%s|i', preg_quote($home_path, '|'));
         // Trim path info from the end and the leading home path from the
         // front. For path info requests, this leaves us with the requesting
         // filename, if any. For 404 requests, this leaves us with the
         // requested permalink.
         $req_uri = str_replace($pathinfo, '', $req_uri);
         $req_uri = trim($req_uri, '/');
         $req_uri = preg_replace($home_path_regex, '', $req_uri);
         $req_uri = trim($req_uri, '/');
         $pathinfo = trim($pathinfo, '/');
         $pathinfo = preg_replace($home_path_regex, '', $pathinfo);
         $pathinfo = trim($pathinfo, '/');
         $self = trim($self, '/');
         $self = preg_replace($home_path_regex, '', $self);
         $self = trim($self, '/');
         // The requested permalink is in $pathinfo for path info requests and
         //  $req_uri for other requests.
         if (!empty($pathinfo) && !preg_match('|^.*' . $wp_rewrite->index . '$|', $pathinfo)) {
             $request = $pathinfo;
         } else {
             // If the request uri is the index, blank it out so that we don't try to match it against a rule.
             if ($req_uri == $wp_rewrite->index) {
                 $req_uri = '';
             }
             $request = $req_uri;
         }
         $this->request = $request;
         // Look for matches.
         $request_match = $request;
         if (empty($request_match)) {
             // An empty request could only match against ^$ regex
             if (isset($rewrite['$'])) {
                 $this->matched_rule = '$';
                 $query = $rewrite['$'];
                 $matches = array('');
             }
         } else {
             foreach ((array) $rewrite as $match => $query) {
                 // If the requesting file is the anchor of the match, prepend it to the path info.
                 if (!empty($req_uri) && strpos($match, $req_uri) === 0 && $req_uri != $request) {
                     $request_match = $req_uri . '/' . $request;
                 }
                 if (preg_match("#^{$match}#", $request_match, $matches) || preg_match("#^{$match}#", urldecode($request_match), $matches)) {
                     if ($wp_rewrite->use_verbose_page_rules && preg_match('/pagename=\\$matches\\[([0-9]+)\\]/', $query, $varmatch)) {
                         // This is a verbose page match, let's check to be sure about it.
                         if (!get_page_by_path($matches[$varmatch[1]])) {
                             continue;
                         }
                     }
                     // Got a match.
                     $this->matched_rule = $match;
                     break;
                 }
             }
         }
         if (isset($this->matched_rule)) {
             // Trim the query of everything up to the '?'.
             $query = preg_replace("!^.+\\?!", '', $query);
             // Substitute the substring matches into the query.
             $query = addslashes(WP_MatchesMapRegex::apply($query, $matches));
             $this->matched_query = $query;
             // Parse the query.
             parse_str($query, $perma_query_vars);
             // If we're processing a 404 request, clear the error var since we found something.
             if ('404' == $error) {
                 unset($error, $_GET['error']);
             }
         }
         // If req_uri is empty or if it is a request for ourself, unset error.
         if (empty($request) || $req_uri == $self || strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false) {
             unset($error, $_GET['error']);
             if (isset($perma_query_vars) && strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false) {
                 unset($perma_query_vars);
             }
             $this->did_permalink = false;
         }
     }
     /**
      * Filter the query variables whitelist before processing.
      *
      * Allows (publicly allowed) query vars to be added, removed, or changed prior
      * to executing the query. Needed to allow custom rewrite rules using your own arguments
      * to work, or any other custom query variables you want to be publicly available.
      *
      * @since 1.5.0
      *
      * @param array $public_query_vars The array of whitelisted query variables.
      */
     $this->public_query_vars = apply_filters('query_vars', $this->public_query_vars);
     foreach (get_post_types(array(), 'objects') as $post_type => $t) {
         if ($t->query_var) {
             $post_type_query_vars[$t->query_var] = $post_type;
         }
     }
     foreach ($this->public_query_vars as $wpvar) {
         if (isset($this->extra_query_vars[$wpvar])) {
             $this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar];
         } elseif (isset($_POST[$wpvar])) {
             $this->query_vars[$wpvar] = $_POST[$wpvar];
         } elseif (isset($_GET[$wpvar])) {
             $this->query_vars[$wpvar] = $_GET[$wpvar];
         } elseif (isset($perma_query_vars[$wpvar])) {
             $this->query_vars[$wpvar] = $perma_query_vars[$wpvar];
         }
         if (!empty($this->query_vars[$wpvar])) {
             if (!is_array($this->query_vars[$wpvar])) {
                 $this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar];
             } else {
                 foreach ($this->query_vars[$wpvar] as $vkey => $v) {
                     if (!is_object($v)) {
                         $this->query_vars[$wpvar][$vkey] = (string) $v;
                     }
                 }
             }
             if (isset($post_type_query_vars[$wpvar])) {
                 $this->query_vars['post_type'] = $post_type_query_vars[$wpvar];
                 $this->query_vars['name'] = $this->query_vars[$wpvar];
             }
         }
     }
     // Convert urldecoded spaces back into +
     foreach (get_taxonomies(array(), 'objects') as $taxonomy => $t) {
         if ($t->query_var && isset($this->query_vars[$t->query_var])) {
             $this->query_vars[$t->query_var] = str_replace(' ', '+', $this->query_vars[$t->query_var]);
         }
     }
     // Limit publicly queried post_types to those that are publicly_queryable
     if (isset($this->query_vars['post_type'])) {
         $queryable_post_types = get_post_types(array('publicly_queryable' => true));
         if (!is_array($this->query_vars['post_type'])) {
             if (!in_array($this->query_vars['post_type'], $queryable_post_types)) {
                 unset($this->query_vars['post_type']);
             }
         } else {
             $this->query_vars['post_type'] = array_intersect($this->query_vars['post_type'], $queryable_post_types);
         }
     }
     // Resolve conflicts between posts with numeric slugs and date archive queries.
     $this->query_vars = wp_resolve_numeric_slug_conflicts($this->query_vars);
     foreach ((array) $this->private_query_vars as $var) {
         if (isset($this->extra_query_vars[$var])) {
             $this->query_vars[$var] = $this->extra_query_vars[$var];
         }
     }
     if (isset($error)) {
         $this->query_vars['error'] = $error;
     }
     /**
      * Filter the array of parsed query variables.
      *
      * @since 2.1.0
      *
      * @param array $query_vars The array of requested query variables.
      */
     $this->query_vars = apply_filters('request', $this->query_vars);
     /**
      * Fires once all query variables for the current request have been parsed.
      *
      * @since 2.1.0
      *
      * @param WP &$this Current WordPress environment instance (passed by reference).
      */
     do_action_ref_array('parse_request', array(&$this));
 }
Beispiel #2
0
/**
 * Examine a url and try to determine the post ID it represents.
 *
 * Checks are supposedly from the hosted site blog.
 *
 * @since 1.0.0
 *
 * @global WP_Rewrite $wp_rewrite
 * @global WP         $wp
 *
 * @param string $url Permalink to check.
 * @return int Post ID, or 0 on failure.
 */
function url_to_postid( $url ) {
	global $wp_rewrite;

	/**
	 * Filter the URL to derive the post ID from.
	 *
	 * @since 2.2.0
	 *
	 * @param string $url The URL to derive the post ID from.
	 */
	$url = apply_filters( 'url_to_postid', $url );

	// First, check to see if there is a 'p=N' or 'page_id=N' to match against
	if ( preg_match('#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values) )	{
		$id = absint($values[2]);
		if ( $id )
			return $id;
	}

	// Check to see if we are using rewrite rules
	$rewrite = $wp_rewrite->wp_rewrite_rules();

	// Not using rewrite rules, and 'p=N' and 'page_id=N' methods failed, so we're out of options
	if ( empty($rewrite) )
		return 0;

	// Get rid of the #anchor
	$url_split = explode('#', $url);
	$url = $url_split[0];

	// Get rid of URL ?query=string
	$url_split = explode('?', $url);
	$url = $url_split[0];

	// Add 'www.' if it is absent and should be there
	if ( false !== strpos(home_url(), '://www.') && false === strpos($url, '://www.') )
		$url = str_replace('://', '://www.', $url);

	// Strip 'www.' if it is present and shouldn't be
	if ( false === strpos(home_url(), '://www.') )
		$url = str_replace('://www.', '://', $url);

	// Strip 'index.php/' if we're not using path info permalinks
	if ( !$wp_rewrite->using_index_permalinks() )
		$url = str_replace( $wp_rewrite->index . '/', '', $url );

	if ( false !== strpos( trailingslashit( $url ), home_url( '/' ) ) ) {
		// Chop off http://domain.com/[path]
		$url = str_replace(home_url(), '', $url);
	} else {
		// Chop off /path/to/blog
		$home_path = parse_url( home_url( '/' ) );
		$home_path = isset( $home_path['path'] ) ? $home_path['path'] : '' ;
		$url = preg_replace( sprintf( '#^%s#', preg_quote( $home_path ) ), '', trailingslashit( $url ) );
	}

	// Trim leading and lagging slashes
	$url = trim($url, '/');

	$request = $url;
	$post_type_query_vars = array();

	foreach ( get_post_types( array() , 'objects' ) as $post_type => $t ) {
		if ( ! empty( $t->query_var ) )
			$post_type_query_vars[ $t->query_var ] = $post_type;
	}

	// Look for matches.
	$request_match = $request;
	foreach ( (array)$rewrite as $match => $query) {

		// If the requesting file is the anchor of the match, prepend it
		// to the path info.
		if ( !empty($url) && ($url != $request) && (strpos($match, $url) === 0) )
			$request_match = $url . '/' . $request;

		if ( preg_match("#^$match#", $request_match, $matches) ) {

			if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) {
				// This is a verbose page match, let's check to be sure about it.
				if ( ! get_page_by_path( $matches[ $varmatch[1] ] ) )
					continue;
			}

			// Got a match.
			// Trim the query of everything up to the '?'.
			$query = preg_replace("!^.+\?!", '', $query);

			// Substitute the substring matches into the query.
			$query = addslashes(WP_MatchesMapRegex::apply($query, $matches));

			// Filter out non-public query vars
			global $wp;
			parse_str( $query, $query_vars );
			$query = array();
			foreach ( (array) $query_vars as $key => $value ) {
				if ( in_array( $key, $wp->public_query_vars ) ){
					$query[$key] = $value;
					if ( isset( $post_type_query_vars[$key] ) ) {
						$query['post_type'] = $post_type_query_vars[$key];
						$query['name'] = $value;
					}
				}
			}

			// Resolve conflicts between posts with numeric slugs and date archive queries.
			$query = wp_resolve_numeric_slug_conflicts( $query );

			// Do the query
			$query = new WP_Query( $query );
			if ( ! empty( $query->posts ) && $query->is_singular )
				return $query->post->ID;
			else
				return 0;
		}
	}
	return 0;
}