示例#1
0
/**
 * Examine a url and try to determine the post ID it represents.
 *
 * Checks are supposedly from the hosted site blog.
 *
 * @since 0.0.1
 *
 * @global HQ_Rewrite $hq_rewrite
 * @global HQ         $hq
 *
 * @param string $url Permalink to check.
 * @return int Post ID, or 0 on failure.
 */
function url_to_postid($url)
{
    global $hq_rewrite;
    /**
     * Filter the URL to derive the post ID from.
     *
     * @since 0.0.1
     *
     * @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 = $hq_rewrite->hq_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 (!$hq_rewrite->using_index_permalinks()) {
        $url = str_replace($hq_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 ($hq_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(HQ_MatchesMapRegex::apply($query, $matches));
            // Filter out non-public query vars
            global $hq;
            parse_str($query, $query_vars);
            $query = array();
            foreach ((array) $query_vars as $key => $value) {
                if (in_array($key, $hq->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 = hq_resolve_numeric_slug_conflicts($query);
            // Do the query
            $query = new HQ_Query($query);
            if (!empty($query->posts) && $query->is_singular) {
                return $query->post->ID;
            } else {
                return 0;
            }
        }
    }
    return 0;
}
示例#2
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 0.0.1
  *
  * @global HQ_Rewrite $hq_rewrite
  *
  * @param array|string $extra_query_vars Set the extra query variables.
  */
 public function parse_request($extra_query_vars = '')
 {
     global $hq_rewrite;
     /**
      * Filter whether to parse the request.
      *
      * @since 0.0.1
      *
      * @param bool         $bool             Whether or not to parse the request. Default true.
      * @param HQ           $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 = $hq_rewrite->hq_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('|^.*' . $hq_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 == $hq_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 ($hq_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(HQ_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'], 'hq-admin/') !== false) {
             unset($error, $_GET['error']);
             if (isset($perma_query_vars) && strpos($_SERVER['PHP_SELF'], 'hq-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 0.0.1
      *
      * @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 $hqvar) {
         if (isset($this->extra_query_vars[$hqvar])) {
             $this->query_vars[$hqvar] = $this->extra_query_vars[$hqvar];
         } elseif (isset($_POST[$hqvar])) {
             $this->query_vars[$hqvar] = $_POST[$hqvar];
         } elseif (isset($_GET[$hqvar])) {
             $this->query_vars[$hqvar] = $_GET[$hqvar];
         } elseif (isset($perma_query_vars[$hqvar])) {
             $this->query_vars[$hqvar] = $perma_query_vars[$hqvar];
         }
         if (!empty($this->query_vars[$hqvar])) {
             if (!is_array($this->query_vars[$hqvar])) {
                 $this->query_vars[$hqvar] = (string) $this->query_vars[$hqvar];
             } else {
                 foreach ($this->query_vars[$hqvar] as $vkey => $v) {
                     if (!is_object($v)) {
                         $this->query_vars[$hqvar][$vkey] = (string) $v;
                     }
                 }
             }
             if (isset($post_type_query_vars[$hqvar])) {
                 $this->query_vars['post_type'] = $post_type_query_vars[$hqvar];
                 $this->query_vars['name'] = $this->query_vars[$hqvar];
             }
         }
     }
     // Convert urldecoded spaces back into +
     //TODO: Goyo no taxonomies
     //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 = hq_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 0.0.1
      *
      * @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 0.0.1
      *
      * @param HQ &$this Current WordPress environment instance (passed by reference).
      */
     do_action_ref_array('parse_request', array(&$this));
 }