Make WordPress Core

Ticket #1324: url_to_postid.diff

File url_to_postid.diff, 4.6 KB (added by macmanx, 21 years ago)
  • functions.php

     
    173173// examine a url (supposedly from this blog) and try to
    174174// determine the post ID it represents.
    175175function url_to_postid($url = '') {
    176         global $wpdb;
     176        global $wp_rewrite;
    177177
    178         $siteurl = get_settings('home');
    179         // Take a link like 'http://example.com/blog/something'
    180         // and extract just the '/something':
    181         $uri = preg_replace("#$siteurl#i", '', $url);
    182 
    183         // on failure, preg_replace just returns the subject string
    184         // so if $uri and $siteurl are the same, they didn't match:
    185         if ($uri == $siteurl)
    186                 return 0;
    187                
    188178        // First, check to see if there is a 'p=N' or 'page_id=N' to match against:
    189         preg_match('#[?&](p|page_id)=(\d+)#', $uri, $values);
    190         $p = intval($values[2]);
    191         if ($p) return $p;
    192        
    193         // Match $uri against our permalink structure
    194         $permalink_structure = get_settings('permalink_structure');
    195        
    196         // Matt's tokenizer code
    197         $rewritecode = array(
    198                 '%year%',
    199                 '%monthnum%',
    200                 '%day%',
    201                 '%hour%',
    202                 '%minute%',
    203                 '%second%',
    204                 '%postname%',
    205                 '%post_id%'
    206         );
    207         $rewritereplace = array(
    208                 '([0-9]{4})?',
    209                 '([0-9]{1,2})?',
    210                 '([0-9]{1,2})?',
    211                 '([0-9]{1,2})?',
    212                 '([0-9]{1,2})?',
    213                 '([0-9]{1,2})?',
    214                 '([_0-9a-z-]+)?',
    215                 '([0-9]+)?'
    216         );
     179        preg_match('#[?&](p|page_id)=(\d+)#', $url, $values);
     180        $id = intval($values[2]);
     181        if ($id) return $id;
    217182
    218         // Turn the structure into a regular expression
    219         $matchre = str_replace('/', '/?', $permalink_structure);
    220         $matchre = str_replace($rewritecode, $rewritereplace, $matchre);
     183        // URI is probably a permalink.
     184        $rewrite = $wp_rewrite->wp_rewrite_rules();
    221185
    222         // Extract the key values from the uri:
    223         preg_match("#$matchre#",$uri,$values);
     186        if ( empty($rewrite) )
     187                return 0;
    224188
    225         // Extract the token names from the structure:
    226         preg_match_all("#%(.+?)%#", $permalink_structure, $tokens);
    227 
    228         for($i = 0; $i < count($tokens[1]); $i++) {
    229                 $name = $tokens[1][$i];
    230                 $value = $values[$i+1];
    231 
    232                 // Create a variable named $year, $monthnum, $day, $postname, or $post_id:
    233                 $$name = $value;
    234         }
     189        $req_uri = $url;
     190        $home_path = parse_url(get_settings('home'));
     191        $home_path = $home_path['path'];
    235192       
    236         // If using %post_id%, we're done:
    237         if (intval($post_id)) return intval($post_id);
     193        // Trim path info from the end and the leading home path from the
     194        // front.  For path info requests, this leaves us with the requesting
     195        // filename, if any.  For 404 requests, this leaves us with the
     196        // requested permalink.
     197        $req_uri = str_replace($pathinfo, '', $req_uri);
     198        $req_uri = str_replace($home_path, '', $req_uri);
     199        $req_uri = trim($req_uri, '/');
     200        $request = $req_uri;
    238201       
    239         // Otherwise, build a WHERE clause, making the values safe along the way:
    240         if ($year) $where .= " AND YEAR(post_date) = '" . intval($year) . "'";
    241         if ($monthnum) $where .= " AND MONTH(post_date) = '" . intval($monthnum) . "'";
    242         if ($day) $where .= " AND DAYOFMONTH(post_date) = '" . intval($day) . "'";
    243         if ($hour) $where .= " AND HOUR(post_date) = '" . intval($hour) . "'";
    244         if ($minute) $where .= " AND MINUTE(post_date) = '" . intval($minute) . "'";
    245         if ($second) $where .= " AND SECOND(post_date) = '" . intval($second) . "'";
    246         if ($postname) $where .= " AND post_name = '" . $wpdb->escape($postname) . "' ";
     202        // Look for matches.
     203        $request_match = $request;
     204        foreach ($rewrite as $match => $query) {
     205                // If the requesting file is the anchor of the match, prepend it
     206                // to the path info.
     207                if ((! empty($req_uri)) && (strpos($match, $req_uri) === 0)) {
     208                        $request_match = $req_uri . '/' . $request;
     209                }
    247210
    248         // We got no indication, so we return false:
    249         if (!strlen($where)) {
    250                 return false;
     211                if (preg_match("!^$match!", $request_match, $matches)) {
     212                        // Got a match.
     213                        // Trim the query of everything up to the '?'.
     214                        $query = preg_replace("!^.+\?!", '', $query);
     215                       
     216                        // Substitute the substring matches into the query.
     217                        eval("\$query = \"$query\";");
     218                        $query = new WP_Query($query);
     219                        if ( !empty($query->post) )
     220                                return $query->post->ID;
     221                        else
     222                                return 0;
     223                }
    251224        }
    252225
    253         // if all we got was a postname, it's probably a page, so we'll want to check for a possible subpage
    254         if ($postname && !$year && !$monthnum && !$day && !$hour && !$minute && !$second) {
    255         $postname = rtrim(strstr($uri, $postname), '/');
    256         $uri_array = explode('/', $postname);
    257         $postname = $uri_array[count($uri_array) - 1];
    258         $where = " AND post_name = '" . $wpdb->escape($postname) . "' ";
    259         }
    260        
    261         // Run the query to get the post ID:
    262         $id = intval($wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE 1 = 1 " . $where));
    263 
    264         return $id;
     226        return 0;
    265227}
    266228
    267229