Make WordPress Core

Ticket #2433: wp-rewrite-api.7.diff

File wp-rewrite-api.7.diff, 46.0 KB (added by davidhouse, 18 years ago)
  • wp-includes/rewrite.php

     
     1<?php
     2
     3/* WP_Rewrite API
     4*******************************************************************************/
     5
     6//Add a straight rewrite rule
     7function add_rewrite_rule($regex, $redirect) {
     8        global $wp_rewrite;
     9        $wp_rewrite->add_rule($regex, $redirect);
     10}
     11
     12//Add a new tag (like %postname%)
     13//warning: you must call this on init or earlier, otherwise the query var addition stuff won't work
     14function add_rewrite_tag($tagname, $regex) {
     15        //validation
     16        if (strlen($tagname) < 3 || $tagname{0} != '%' || $tagname{strlen($tagname)-1} != '%') {
     17                return;
     18        }
     19       
     20        $qv = trim($tagname, '%');
     21       
     22        global $wp_rewrite, $wp;
     23        $wp->add_query_var($qv);
     24        $wp_rewrite->add_rewrite_tag($tagname, $regex, $qv . '=');
     25}
     26
     27//Add a new feed type like /atom1/
     28function add_feed($feedname, $filename) {
     29        global $wp_rewrite;
     30        if (!in_array($feedname, $wp_rewrite->feeds)) { //override the file if it is
     31                $wp_rewrite->feeds[] = $feedname;
     32        }
     33        $wp_rewrite->feed_files[$feedname] = $filename;
     34}
     35
     36define('EP_PERMALINK',  1   );
     37define('EP_ATTACHMENT', 2   );
     38define('EP_DATE',       4   );
     39define('EP_YEAR',       8   );
     40define('EP_MONTH',      16  );
     41define('EP_DAY',        32  );
     42define('EP_ROOT',       64  );
     43define('EP_COMMENTS',   128 );
     44define('EP_SEARCH',     256 );
     45define('EP_CATEGORIES', 512 );
     46define('EP_AUTHORS',    1024);
     47define('EP_PAGES',      2048);
     48//pseudo-places
     49define('EP_NONE',       0  );
     50define('EP_ALL',        255);
     51
     52//and an endpoint, like /trackback/
     53function add_endpoint($name, $places) {
     54        global $wp_rewrite;
     55        $wp_rewrite->add_endpoint($name, $places);
     56}
     57
     58/* WP_Rewrite class
     59*******************************************************************************/
     60
     61class WP_Rewrite {
     62        var $permalink_structure;
     63        var $category_base;
     64        var $category_structure;
     65        var $author_base = 'author';
     66        var $author_structure;
     67        var $date_structure;
     68        var $page_structure;
     69        var $search_base = 'search';
     70        var $search_structure;
     71        var $comments_base = 'comments';
     72        var $feed_base = 'feed';
     73        var $comments_feed_structure;
     74        var $feed_structure;
     75        var $front;
     76        var $root = '';
     77        var $index = 'index.php';
     78        var $matches = '';
     79        var $rules;
     80        var $extra_rules; //those not generated by the class, see add_rewrite_rule()
     81        var $non_wp_rules; //rules that don't redirect to WP's index.php
     82        var $endpoints;
     83        var $use_verbose_rules = false;
     84        var $rewritecode =
     85                array(
     86                                        '%year%',
     87                                        '%monthnum%',
     88                                        '%day%',
     89                                        '%hour%',
     90                                        '%minute%',
     91                                        '%second%',
     92                                        '%postname%',
     93                                        '%post_id%',
     94                                        '%category%',
     95                                        '%author%',
     96                                        '%pagename%',
     97                                        '%search%'
     98                                        );
     99
     100        var $rewritereplace =
     101                array(
     102                                        '([0-9]{4})',
     103                                        '([0-9]{1,2})',
     104                                        '([0-9]{1,2})',
     105                                        '([0-9]{1,2})',
     106                                        '([0-9]{1,2})',
     107                                        '([0-9]{1,2})',
     108                                        '([^/]+)',
     109                                        '([0-9]+)',
     110                                        '(.+?)',
     111                                        '([^/]+)',
     112                                        '([^/]+)',
     113                                        '(.+)'
     114                                        );
     115
     116        var $queryreplace =
     117                array (
     118                                        'year=',
     119                                        'monthnum=',
     120                                        'day=',
     121                                        'hour=',
     122                                        'minute=',
     123                                        'second=',
     124                                        'name=',
     125                                        'p=',
     126                                        'category_name=',
     127                                        'author_name=',
     128                                        'pagename=',
     129                                        's='
     130                                        );
     131
     132        var $feeds = array ( 'feed', 'rdf', 'rss', 'rss2', 'atom' );
     133       
     134        //the filenames aren't actually used in WP_Rewrite but seems a convenient place as any to store them
     135        var $feed_files = array (
     136                'rdf'  => 'wp-rdf.php',
     137                'rss'  => 'wp-rss.php',
     138                'rss2' => 'wp-rss2.php',
     139                'atom' =>'wp-atom.php'
     140        ); 
     141     
     142        function using_permalinks() {
     143                if (empty($this->permalink_structure))
     144                        return false;
     145                else
     146                        return true;
     147        }
     148
     149        function using_index_permalinks() {
     150                if (empty($this->permalink_structure)) {
     151                        return false;
     152                }
     153
     154                // If the index is not in the permalink, we're using mod_rewrite.
     155                if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {
     156                        return true;
     157                }
     158   
     159                return false;
     160        }
     161
     162        function using_mod_rewrite_permalinks() {
     163                if ( $this->using_permalinks() && ! $this->using_index_permalinks())
     164                        return true;
     165                else
     166                        return false;
     167        }
     168
     169        function preg_index($number) {
     170                $match_prefix = '$';
     171                $match_suffix = '';
     172
     173                if (! empty($this->matches)) {
     174                        $match_prefix = '$' . $this->matches . '[';
     175                        $match_suffix = ']';
     176                }       
     177
     178                return "$match_prefix$number$match_suffix";       
     179        }
     180
     181        function page_rewrite_rules() {
     182                $uris = get_settings('page_uris');
     183                $attachment_uris = get_settings('page_attachment_uris');
     184
     185                $rewrite_rules = array();
     186                $page_structure = $this->get_page_permastruct();
     187                if( is_array( $attachment_uris ) ) {
     188                        foreach ($attachment_uris as $uri => $pagename) {
     189                                $this->add_rewrite_tag('%pagename%', "($uri)", 'attachment=');
     190                                $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
     191                        }
     192                }
     193                if( is_array( $uris ) ) {
     194                        foreach ($uris as $uri => $pagename) {
     195                                $this->add_rewrite_tag('%pagename%', "($uri)", 'pagename=');
     196                                $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
     197                        }
     198                }
     199
     200                return $rewrite_rules;
     201        }
     202
     203        function get_date_permastruct() {
     204                if (isset($this->date_structure)) {
     205                        return $this->date_structure;
     206                }
     207
     208                if (empty($this->permalink_structure)) {
     209                        $this->date_structure = '';
     210                        return false;
     211                }
     212
     213                // The date permalink must have year, month, and day separated by slashes.
     214                $endians = array('%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%');
     215
     216                $this->date_structure = '';
     217                $date_endian = '';
     218
     219                foreach ($endians as $endian) {
     220                        if (false !== strpos($this->permalink_structure, $endian)) {
     221                                $date_endian= $endian;
     222                                break;
     223                        }
     224                }
     225
     226                if ( empty($date_endian) )
     227                        $date_endian = '%year%/%monthnum%/%day%';
     228
     229                // Do not allow the date tags and %post_id% to overlap in the permalink
     230                // structure. If they do, move the date tags to $front/date/. 
     231                $front = $this->front;
     232                preg_match_all('/%.+?%/', $this->permalink_structure, $tokens);
     233                $tok_index = 1;
     234                foreach ($tokens[0] as $token) {
     235                        if ( ($token == '%post_id%') && ($tok_index <= 3) ) {
     236                                $front = $front . 'date/';
     237                                break;
     238                        }
     239                }
     240
     241                $this->date_structure = $front . $date_endian;
     242
     243                return $this->date_structure;
     244        }
     245
     246        function get_year_permastruct() {
     247                $structure = $this->get_date_permastruct($this->permalink_structure);
     248
     249                if (empty($structure)) {
     250                        return false;
     251                }
     252
     253                $structure = str_replace('%monthnum%', '', $structure);
     254                $structure = str_replace('%day%', '', $structure);
     255
     256                $structure = preg_replace('#/+#', '/', $structure);
     257
     258                return $structure;
     259        }
     260
     261        function get_month_permastruct() {
     262                $structure = $this->get_date_permastruct($this->permalink_structure);
     263
     264                if (empty($structure)) {
     265                        return false;
     266                }
     267
     268                $structure = str_replace('%day%', '', $structure);
     269
     270                $structure = preg_replace('#/+#', '/', $structure);
     271
     272                return $structure;
     273        }
     274
     275        function get_day_permastruct() {
     276                return $this->get_date_permastruct($this->permalink_structure);
     277        }
     278
     279        function get_category_permastruct() {
     280                if (isset($this->category_structure)) {
     281                        return $this->category_structure;
     282                }
     283
     284                if (empty($this->permalink_structure)) {
     285                        $this->category_structure = '';
     286                        return false;
     287                }
     288
     289                if (empty($this->category_base))
     290                        $this->category_structure = $this->front . 'category/';
     291                else
     292                        $this->category_structure = $this->category_base . '/';
     293
     294                $this->category_structure .= '%category%';
     295
     296                return $this->category_structure;
     297        }
     298
     299        function get_author_permastruct() {
     300                if (isset($this->author_structure)) {
     301                        return $this->author_structure;
     302                }
     303
     304                if (empty($this->permalink_structure)) {
     305                        $this->author_structure = '';
     306                        return false;
     307                }
     308
     309                $this->author_structure = $this->front . $this->author_base . '/%author%';
     310
     311                return $this->author_structure;
     312        }
     313
     314        function get_search_permastruct() {
     315                if (isset($this->search_structure)) {
     316                        return $this->search_structure;
     317                }
     318
     319                if (empty($this->permalink_structure)) {
     320                        $this->search_structure = '';
     321                        return false;
     322                }
     323
     324                $this->search_structure = $this->root . $this->search_base . '/%search%';
     325
     326                return $this->search_structure;
     327        }
     328
     329        function get_page_permastruct() {
     330                if (isset($this->page_structure)) {
     331                        return $this->page_structure;
     332                }
     333
     334                if (empty($this->permalink_structure)) {
     335                        $this->page_structure = '';
     336                        return false;
     337                }
     338
     339                $this->page_structure = $this->root . '%pagename%';
     340
     341                return $this->page_structure;
     342        }
     343
     344        function get_feed_permastruct() {
     345                if (isset($this->feed_structure)) {
     346                        return $this->feed_structure;
     347                }
     348
     349                if (empty($this->permalink_structure)) {
     350                        $this->feed_structure = '';
     351                        return false;
     352                }
     353
     354                $this->feed_structure = $this->root . $this->feed_base . '/%feed%';
     355
     356                return $this->feed_structure;
     357        }
     358
     359        function get_comment_feed_permastruct() {
     360                if (isset($this->comment_feed_structure)) {
     361                        return $this->comment_feed_structure;
     362                }
     363
     364                if (empty($this->permalink_structure)) {
     365                        $this->comment_feed_structure = '';
     366                        return false;
     367                }
     368
     369                $this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%';
     370
     371                return $this->comment_feed_structure;
     372        }
     373
     374        function add_rewrite_tag($tag, $pattern, $query) {
     375                // If the tag already exists, replace the existing pattern and query for
     376                // that tag, otherwise add the new tag, pattern, and query to the end of
     377                // the arrays.
     378                $position = array_search($tag, $this->rewritecode);
     379                if (FALSE !== $position && NULL !== $position) {
     380                        $this->rewritereplace[$position] = $pattern;
     381                        $this->queryreplace[$position] = $query;
     382                } else {
     383                        $this->rewritecode[] = $tag;
     384                        $this->rewritereplace[] = $pattern;
     385                        $this->queryreplace[] = $query;
     386                }
     387        }
     388
     389        //the main WP_Rewrite function. generate the rules from permalink structure
     390        function generate_rewrite_rules($permalink_structure, $ep_mask = EP_NONE, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true) {
     391                //build a regex to match the feed section of URLs, something like (feed|atom|rss|rss2)/?
     392                $feedregex2 = '';
     393                foreach ($this->feeds as $feed_name) {
     394                        $feedregex2 .= $feed_name . '|';
     395                }
     396                $feedregex2 = '(' . trim($feedregex2, '|') .  ')/?$';
     397                //$feedregex is identical but with /feed/ added on as well, so URLs like <permalink>/feed/atom
     398                //and <permalink>/atom are both possible
     399                $feedregex = $this->feed_base  . '/' . $feedregex2;
     400
     401                //build a regex to match the trackback and page/xx parts of URLs
     402                $trackbackregex = 'trackback/?$';
     403                $pageregex = 'page/?([0-9]{1,})/?$';
     404               
     405                //build up an array of endpoint regexes to append => queries to append
     406                if ($endpoints) {
     407                        $ep_query_append = array ();
     408                        foreach ($this->endpoints as $endpoint) {
     409                                //match everything after the endpoint name, but allow for nothing to appear there
     410                                $epmatch = $endpoint[1] . '(/(.*))?/?$';
     411                                //this will be appended on to the rest of the query for each dir
     412                                $epquery = '&' . $endpoint[1] . '=';
     413                                $ep_query_append[$epmatch] = array ( $endpoint[0], $epquery );
     414                        }
     415                }
     416
     417                //get everything up to the first rewrite tag
     418                $front = substr($permalink_structure, 0, strpos($permalink_structure, '%'));
     419                //build an array of the tags (note that said array ends up being in $tokens[0])
     420                preg_match_all('/%.+?%/', $permalink_structure, $tokens);
     421
     422                $num_tokens = count($tokens[0]);
     423
     424                $index = $this->index; //probably 'index.php'
     425                $feedindex = $index;
     426                $trackbackindex = $index;
     427                //build a list from the rewritecode and queryreplace arrays, that will look something like
     428                //tagname=$matches[i] where i is the current $i
     429                for ($i = 0; $i < $num_tokens; ++$i) {
     430                        if (0 < $i) {
     431                                $queries[$i] = $queries[$i - 1] . '&';
     432                        }
     433             
     434                        $query_token = str_replace($this->rewritecode, $this->queryreplace, $tokens[0][$i]) . $this->preg_index($i+1);
     435                        $queries[$i] .= $query_token;
     436                }
     437
     438                //get the structure, minus any cruft (stuff that isn't tags) at the front
     439                $structure = $permalink_structure;
     440                if ($front != '/') {
     441                        $structure = str_replace($front, '', $structure);
     442                }
     443                //create a list of dirs to walk over, making rewrite rules for each level
     444                //so for example, a $structure of /%year%/%month%/%postname% would create
     445                //rewrite rules for /%year%/, /%year%/%month%/ and /%year%/%month%/%postname%
     446                $structure = trim($structure, '/');
     447                if ($walk_dirs) {
     448                        $dirs = explode('/', $structure);
     449                } else {
     450                        $dirs[] = $structure;
     451                }
     452                $num_dirs = count($dirs);
     453
     454                //strip slashes from the front of $front
     455                $front = preg_replace('|^/+|', '', $front);
     456
     457                //the main workhorse loop
     458                $post_rewrite = array();
     459                $struct = $front;
     460                for ($j = 0; $j < $num_dirs; ++$j) {
     461                        //get the struct for this dir, and trim slashes off the front
     462                        $struct .= $dirs[$j] . '/'; //accumulate. see comment near explode('/', $structure) above
     463                        $struct = ltrim($struct, '/');
     464                        //replace tags with regexes
     465                        $match = str_replace($this->rewritecode, $this->rewritereplace, $struct);
     466                        //make a list of tags, and store how many there are in $num_toks
     467                        $num_toks = preg_match_all('/%.+?%/', $struct, $toks);
     468                        //get the 'tagname=$matches[i]'
     469                        $query = $queries[$num_toks - 1];
     470                       
     471                        //set up $ep_mask_specific which is used to match more specific URL types
     472                        switch ($dirs[$j]) {
     473                                case '%year%': $ep_mask_specific = EP_YEAR; break;
     474                                case '%monthnum%': $ep_mask_specific = EP_MONTH; break;
     475                                case '%day%': $ep_mask_specific = EP_DAY; break;
     476                        }
     477
     478                        //create query for /page/xx
     479                        $pagematch = $match . $pageregex;
     480                        $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1);
     481
     482                        //create query for /feed/(feed|atom|rss|rss2|rdf)
     483                        $feedmatch = $match . $feedregex;
     484                        $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
     485
     486                        //create query for /(feed|atom|rss|rss2|rdf) (see comment near creation of $feedregex)
     487                        $feedmatch2 = $match . $feedregex2;
     488                        $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
     489
     490                        //if asked to, turn the feed queries into comment feed ones
     491                        if ($forcomments) {
     492                                $feedquery .= '&withcomments=1';
     493                                $feedquery2 .= '&withcomments=1';
     494                        }
     495
     496                        //start creating the array of rewrites for this dir
     497                        $rewrite = array();
     498                        if ($feed) //...adding on /feed/ regexes => queries
     499                                $rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2);
     500                        if ($paged) //...and /page/xx ones
     501                                $rewrite = array_merge($rewrite, array($pagematch => $pagequery));
     502                       
     503                        //if we've got some tags in this dir
     504                        if ($num_toks) {
     505                                $post = false;
     506                                $page = false;
     507                               
     508                                //check to see if this dir is permalink-level: i.e. the structure specifies an
     509                                //individual post. Do this by checking it contains at least one of 1) post name,
     510                                //2) post ID, 3) page name, 4) timestamp (year, month, day, hour, second and
     511                                //minute all present). Set these flags now as we need them for the endpoints.
     512                                if (strstr($struct, '%postname%') || strstr($struct, '%post_id%')
     513                                                || strstr($struct, '%pagename%')
     514                                                || (strstr($struct, '%year%') &&  strstr($struct, '%monthnum%') && strstr($struct, '%day%') && strstr($struct, '%hour%') && strstr($struct, '%minute') && strstr($struct, '%second%'))) {
     515                                        $post = true;
     516                                        if  ( strstr($struct, '%pagename%') )
     517                                                $page = true;
     518                                }
     519                               
     520                                //do endpoints
     521                                if ($endpoints) {
     522                                        foreach ($ep_query_append as $regex => $ep) {
     523                                                //add the endpoints on if the mask fits
     524                                                if ($ep[0] & $ep_mask || $ep[0] & $ep_mask_specific) {
     525                                                        $rewrite[$match . $regex] = $index . '?' . $query . $ep[1] . $this->preg_index($num_toks + 2);
     526                                                }
     527                                        }
     528                                }
     529                               
     530                                //if we're creating rules for a permalink, do all the endpoints like attachments etc
     531                                if ($post) {
     532                                        $post = true;
     533                                        //create query and regex for trackback
     534                                        $trackbackmatch = $match . $trackbackregex;
     535                                        $trackbackquery = $trackbackindex . '?' . $query . '&tb=1';
     536                                        //trim slashes from the end of the regex for this dir
     537                                        $match = rtrim($match, '/');
     538                                        //get rid of brackets
     539                                        $submatchbase = str_replace(array('(',')'),'',$match);
     540                                       
     541                                        //add a rule for at attachments, which take the form of <permalink>/some-text
     542                                        $sub1 = $submatchbase . '/([^/]+)/';
     543                                        $sub1tb = $sub1 . $trackbackregex; //add trackback regex <permalink>/trackback/...
     544                                        $sub1feed = $sub1 . $feedregex; //and <permalink>/feed/(atom|...)
     545                                        $sub1feed2 = $sub1 . $feedregex2; //and <permalink>/(feed|atom...)
     546                                        //add an ? as we don't have to match that last slash, and finally a $ so we
     547                                        //match to the end of the URL
     548                                       
     549                                        //add another rule to match attachments in the explicit form:
     550                                        //<permalink>/attachment/some-text
     551                                        $sub2 = $submatchbase . '/attachment/([^/]+)/';
     552                                        $sub2tb = $sub2 . $trackbackregex; //and add trackbacks <permalink>/attachment/trackback
     553                                        $sub2feed = $sub2 . $feedregex;    //feeds, <permalink>/attachment/feed/(atom|...)
     554                                        $sub2feed2 = $sub2 . $feedregex2;  //and feeds again on to this <permalink>/attachment/(feed|atom...)
     555                                       
     556                                        //create queries for these extra tag-ons we've just dealt with
     557                                        $subquery = $index . '?attachment=' . $this->preg_index(1);
     558                                        $subtbquery = $subquery . '&tb=1';
     559                                        $subfeedquery = $subquery . '&feed=' . $this->preg_index(2);
     560                                       
     561                                        //do endpoints for attachments
     562                                        if ($endpoint) { foreach ($ep_query_append as $regex => $ep) {
     563                                                if ($ep[0] & EP_ATTACHMENT) {
     564                                                        $rewrite[$sub1 . $regex] = $subquery . '?' . $ep[1] . $this->preg_index(2);
     565                                                        $rewrite[$sub2 . $regex] = $subquery . '?' . $ep[1] . $this->preg_index(2);
     566                                                }
     567                                        } }
     568                                       
     569                                        //now we've finished with endpoints, finish off the $sub1 and $sub2 matches
     570                                        $sub1 .= '?$';
     571                                        $sub2 .= '?$';
     572                                       
     573                                        //allow URLs like <permalink>/2 for <permalink>/page/2
     574                                        $match = $match . '(/[0-9]+)?/?$';
     575                                        $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1);
     576                                } else { //not matching a permalink so this is a lot simpler
     577                                        //close the match and finalise the query
     578                                        $match .= '?$';
     579                                        $query = $index . '?' . $query;
     580                                }
     581                               
     582                                //create the final array for this dir by joining the $rewrite array (which currently
     583                                //only contains rules/queries for trackback, pages etc) to the main regex/query for
     584                                //this dir
     585                                $rewrite = array_merge($rewrite, array($match => $query));
     586
     587                                //if we're matching a permalink, add those extras (attachments etc) on
     588                                if ($post) {
     589                                        //add trackback
     590                                        $rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite);
     591                                       
     592                                        //add regexes/queries for attachments, attachment trackbacks and so on
     593                                        if ( ! $page ) //require <permalink>/attachment/stuff form for pages because of confusion with subpages
     594                                                $rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery));
     595                                        $rewrite = array_merge($rewrite, array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery));
     596                                }
     597                        } //if($num_toks)
     598                        //add the rules for this dir to the accumulating $post_rewrite
     599                        $post_rewrite = array_merge($rewrite, $post_rewrite);
     600                } //foreach ($dir)
     601                return $post_rewrite; //the finished rules. phew!
     602        }
     603
     604        function generate_rewrite_rule($permalink_structure, $walk_dirs = false) {
     605                return $this->generate_rewrite_rules($permalink_structure, EP_NONE, false, false, false, $walk_dirs);
     606        }
     607
     608        /* rewrite_rules
     609         * Construct rewrite matches and queries from permalink structure.
     610         * Returns an associate array of matches and queries.
     611         */
     612        function rewrite_rules() {
     613                $rewrite = array();
     614
     615                if (empty($this->permalink_structure)) {
     616                        return $rewrite;
     617                }
     618
     619                // Post
     620                $post_rewrite = $this->generate_rewrite_rules($this->permalink_structure, EP_PERMALINK);
     621                $post_rewrite = apply_filters('post_rewrite_rules', $post_rewrite);
     622
     623                // Date
     624                $date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct(), EP_DATE);
     625                $date_rewrite = apply_filters('date_rewrite_rules', $date_rewrite);
     626
     627                // Root
     628                $root_rewrite = $this->generate_rewrite_rules($this->root . '/', EP_ROOT);
     629                $root_rewrite = apply_filters('root_rewrite_rules', $root_rewrite);
     630
     631                // Comments
     632                $comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, EP_COMMENTS, true, true, true, false);
     633                $comments_rewrite = apply_filters('comments_rewrite_rules', $comments_rewrite);
     634
     635                // Search
     636                $search_structure = $this->get_search_permastruct();
     637                $search_rewrite = $this->generate_rewrite_rules($search_structure, EP_SEARCH);
     638                $search_rewrite = apply_filters('search_rewrite_rules', $search_rewrite);
     639
     640                // Categories
     641                $category_rewrite = $this->generate_rewrite_rules($this->get_category_permastruct(), EP_CATEGORIES);
     642                $category_rewrite = apply_filters('category_rewrite_rules', $category_rewrite);
     643
     644                // Authors
     645                $author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct(), EP_AUTHORS);
     646                $author_rewrite = apply_filters('author_rewrite_rules', $author_rewrite);
     647
     648                // Pages
     649                $page_rewrite = $this->page_rewrite_rules();
     650                $page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite);
     651
     652                // Put them together.
     653                $this->rules = array_merge($page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules);
     654
     655                do_action('generate_rewrite_rules', array(&$this));
     656                $this->rules = apply_filters('rewrite_rules_array', $this->rules);
     657
     658                return $this->rules;
     659        }
     660
     661        function wp_rewrite_rules() {
     662                $this->rules = get_option('rewrite_rules');
     663                if ( empty($this->rules) ) {
     664                        $this->matches = 'matches';
     665                        $this->rewrite_rules();
     666                        update_option('rewrite_rules', $this->rules);
     667                }
     668
     669                return $this->rules;
     670        }
     671
     672        function mod_rewrite_rules() {
     673                if ( ! $this->using_permalinks()) {
     674                        return '';
     675                }
     676
     677                $site_root = parse_url(get_settings('siteurl'));
     678                $site_root = trailingslashit($site_root['path']);
     679
     680                $home_root = parse_url(get_settings('home'));
     681                $home_root = trailingslashit($home_root['path']);
     682   
     683                $rules = "<IfModule mod_rewrite.c>\n";
     684                $rules .= "RewriteEngine On\n";
     685                $rules .= "RewriteBase $home_root\n";
     686               
     687                //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all)
     688                foreach ($this->non_wp_rules as $match => $query) {
     689                        // Apache 1.3 does not support the reluctant (non-greedy) modifier.
     690                        $match = str_replace('.+?', '.+', $match);
     691
     692                        // If the match is unanchored and greedy, prepend rewrite conditions
     693                        // to avoid infinite redirects and eclipsing of real files.
     694                        if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) {
     695                                //nada.
     696                        }
     697
     698                        $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";
     699                }
     700
     701                if ($this->use_verbose_rules) {
     702                        $this->matches = '';
     703                        $rewrite = $this->rewrite_rules();
     704                        $num_rules = count($rewrite);
     705                        $rules .= "RewriteCond %{REQUEST_FILENAME} -f [OR]\n" .
     706                                "RewriteCond %{REQUEST_FILENAME} -d\n" .
     707                                "RewriteRule ^.*$ - [S=$num_rules]\n";
     708
     709                        foreach ($rewrite as $match => $query) {
     710                                // Apache 1.3 does not support the reluctant (non-greedy) modifier.
     711                                $match = str_replace('.+?', '.+', $match);
     712
     713                                // If the match is unanchored and greedy, prepend rewrite conditions
     714                                // to avoid infinite redirects and eclipsing of real files.
     715                                if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) {
     716                                        //nada.
     717                                }
     718
     719                                if (strstr($query, $this->index)) {
     720                                        $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";
     721                                } else {
     722                                        $rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n";
     723                                }
     724                        }
     725                } else {
     726                        $rules .= "RewriteCond %{REQUEST_FILENAME} !-f\n" .
     727                                "RewriteCond %{REQUEST_FILENAME} !-d\n" .
     728                                "RewriteRule . {$home_root}{$this->index} [L]\n";
     729                }
     730
     731                $rules .= "</IfModule>\n";
     732
     733                $rules = apply_filters('mod_rewrite_rules', $rules);
     734                $rules = apply_filters('rewrite_rules', $rules);  // Deprecated
     735
     736                return $rules;
     737        }
     738       
     739        //Add a straight rewrite rule
     740        function add_rule($regex, $redirect) {
     741                //get everything up to the first ?
     742                $index = (strpos($redirect, '?') == false ? strlen($redirect) : strpos($redirect, '?'));
     743                $front = substr($redirect, 0, $index);
     744                if ($front != $this->index) { //it doesn't redirect to WP's index.php
     745                        $this->add_external_rule($regex, $redirect);
     746                } else {
     747                        $this->extra_rules[$regex] = $redirect;
     748                }
     749        }
     750       
     751        //add a rule that doesn't redirect to index.php
     752        function add_external_rule($regex, $redirect) {
     753                $this->non_wp_rules[$regex] = $redirect;
     754        }
     755       
     756        //add an endpoint, like /trackback/, to be inserted after certain URL types (specified in $places)
     757        function add_endpoint($name, $places) {
     758                global $wp;
     759                $this->endpoints[] = array ( $places, $name );
     760                $wp->add_query_var($name);
     761        }
     762
     763        function flush_rules() {
     764                generate_page_uri_index();
     765                delete_option('rewrite_rules');
     766                $this->wp_rewrite_rules();
     767                if ( function_exists('save_mod_rewrite_rules') )
     768                        save_mod_rewrite_rules();
     769        }
     770
     771        function init() {
     772                $this->extra_rules = $this->non_wp_rules = $this->endpoints = array();
     773                $this->permalink_structure = get_settings('permalink_structure');
     774                $this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%'));
     775                $this->root = '';
     776                if ($this->using_index_permalinks()) {
     777                        $this->root = $this->index . '/';
     778                }
     779                $this->category_base = get_settings('category_base');
     780                unset($this->category_structure);
     781                unset($this->author_structure);
     782                unset($this->date_structure);
     783                unset($this->page_structure);
     784                unset($this->search_structure);
     785                unset($this->feed_structure);
     786                unset($this->comment_feed_structure);
     787        }
     788
     789        function set_permalink_structure($permalink_structure) {
     790                if ($permalink_structure != $this->permalink_structure) {
     791                        update_option('permalink_structure', $permalink_structure);
     792                        $this->init();
     793                }
     794        }
     795
     796        function set_category_base($category_base) {
     797                if ($category_base != $this->category_base) {
     798                        update_option('category_base', $category_base);
     799                        $this->init();
     800                }
     801        }
     802
     803        function WP_Rewrite() {
     804                $this->init();
     805        }
     806}
     807
     808?>
     809 No newline at end of file
  • wp-includes/classes.php

     
    855855
    856856}
    857857
    858 class WP_Rewrite {
    859         var $permalink_structure;
    860         var $category_base;
    861         var $category_structure;
    862         var $author_base = 'author';
    863         var $author_structure;
    864         var $date_structure;
    865         var $page_structure;
    866         var $search_base = 'search';
    867         var $search_structure;
    868         var $comments_base = 'comments';
    869         var $feed_base = 'feed';
    870         var $comments_feed_structure;
    871         var $feed_structure;
    872         var $front;
    873         var $root = '';
    874         var $index = 'index.php';
    875         var $matches = '';
    876         var $rules;
    877         var $use_verbose_rules = false;
    878         var $rewritecode =
    879                 array(
    880                                         '%year%',
    881                                         '%monthnum%',
    882                                         '%day%',
    883                                         '%hour%',
    884                                         '%minute%',
    885                                         '%second%',
    886                                         '%postname%',
    887                                         '%post_id%',
    888                                         '%category%',
    889                                         '%author%',
    890                                         '%pagename%',
    891                                         '%search%'
    892                                         );
    893 
    894         var $rewritereplace =
    895                 array(
    896                                         '([0-9]{4})',
    897                                         '([0-9]{1,2})',
    898                                         '([0-9]{1,2})',
    899                                         '([0-9]{1,2})',
    900                                         '([0-9]{1,2})',
    901                                         '([0-9]{1,2})',
    902                                         '([^/]+)',
    903                                         '([0-9]+)',
    904                                         '(.+?)',
    905                                         '([^/]+)',
    906                                         '([^/]+)',
    907                                         '(.+)'
    908                                         );
    909 
    910         var $queryreplace =
    911                 array (
    912                                         'year=',
    913                                         'monthnum=',
    914                                         'day=',
    915                                         'hour=',
    916                                         'minute=',
    917                                         'second=',
    918                                         'name=',
    919                                         'p=',
    920                                         'category_name=',
    921                                         'author_name=',
    922                                         'pagename=',
    923                                         's='
    924                                         );
    925 
    926         var $feeds = array ('feed', 'rdf', 'rss', 'rss2', 'atom');
    927 
    928         function using_permalinks() {
    929                 if (empty($this->permalink_structure))
    930                         return false;
    931                 else
    932                         return true;
    933         }
    934 
    935         function using_index_permalinks() {
    936                 if (empty($this->permalink_structure)) {
    937                         return false;
    938                 }
    939 
    940                 // If the index is not in the permalink, we're using mod_rewrite.
    941                 if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {
    942                         return true;
    943                 }
    944    
    945                 return false;
    946         }
    947 
    948         function using_mod_rewrite_permalinks() {
    949                 if ( $this->using_permalinks() && ! $this->using_index_permalinks())
    950                         return true;
    951                 else
    952                         return false;
    953         }
    954 
    955         function preg_index($number) {
    956                 $match_prefix = '$';
    957                 $match_suffix = '';
    958 
    959                 if (! empty($this->matches)) {
    960                         $match_prefix = '$' . $this->matches . '[';
    961                         $match_suffix = ']';
    962                 }       
    963 
    964                 return "$match_prefix$number$match_suffix";       
    965         }
    966 
    967         function page_rewrite_rules() {
    968                 $uris = get_settings('page_uris');
    969                 $attachment_uris = get_settings('page_attachment_uris');
    970 
    971                 $rewrite_rules = array();
    972                 $page_structure = $this->get_page_permastruct();
    973                 if( is_array( $attachment_uris ) ) {
    974                         foreach ($attachment_uris as $uri => $pagename) {
    975                                 $this->add_rewrite_tag('%pagename%', "($uri)", 'attachment=');
    976                                 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure));
    977                         }
    978                 }
    979                 if( is_array( $uris ) ) {
    980                         foreach ($uris as $uri => $pagename) {
    981                                 $this->add_rewrite_tag('%pagename%', "($uri)", 'pagename=');
    982                                 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure));
    983                         }
    984                 }
    985 
    986                 return $rewrite_rules;
    987         }
    988 
    989         function get_date_permastruct() {
    990                 if (isset($this->date_structure)) {
    991                         return $this->date_structure;
    992                 }
    993 
    994                 if (empty($this->permalink_structure)) {
    995                         $this->date_structure = '';
    996                         return false;
    997                 }
    998 
    999                 // The date permalink must have year, month, and day separated by slashes.
    1000                 $endians = array('%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%');
    1001 
    1002                 $this->date_structure = '';
    1003                 $date_endian = '';
    1004 
    1005                 foreach ($endians as $endian) {
    1006                         if (false !== strpos($this->permalink_structure, $endian)) {
    1007                                 $date_endian= $endian;
    1008                                 break;
    1009                         }
    1010                 }
    1011 
    1012                 if ( empty($date_endian) )
    1013                         $date_endian = '%year%/%monthnum%/%day%';
    1014 
    1015                 // Do not allow the date tags and %post_id% to overlap in the permalink
    1016                 // structure. If they do, move the date tags to $front/date/. 
    1017                 $front = $this->front;
    1018                 preg_match_all('/%.+?%/', $this->permalink_structure, $tokens);
    1019                 $tok_index = 1;
    1020                 foreach ($tokens[0] as $token) {
    1021                         if ( ($token == '%post_id%') && ($tok_index <= 3) ) {
    1022                                 $front = $front . 'date/';
    1023                                 break;
    1024                         }
    1025                 }
    1026 
    1027                 $this->date_structure = $front . $date_endian;
    1028 
    1029                 return $this->date_structure;
    1030         }
    1031 
    1032         function get_year_permastruct() {
    1033                 $structure = $this->get_date_permastruct($this->permalink_structure);
    1034 
    1035                 if (empty($structure)) {
    1036                         return false;
    1037                 }
    1038 
    1039                 $structure = str_replace('%monthnum%', '', $structure);
    1040                 $structure = str_replace('%day%', '', $structure);
    1041 
    1042                 $structure = preg_replace('#/+#', '/', $structure);
    1043 
    1044                 return $structure;
    1045         }
    1046 
    1047         function get_month_permastruct() {
    1048                 $structure = $this->get_date_permastruct($this->permalink_structure);
    1049 
    1050                 if (empty($structure)) {
    1051                         return false;
    1052                 }
    1053 
    1054                 $structure = str_replace('%day%', '', $structure);
    1055 
    1056                 $structure = preg_replace('#/+#', '/', $structure);
    1057 
    1058                 return $structure;
    1059         }
    1060 
    1061         function get_day_permastruct() {
    1062                 return $this->get_date_permastruct($this->permalink_structure);
    1063         }
    1064 
    1065         function get_category_permastruct() {
    1066                 if (isset($this->category_structure)) {
    1067                         return $this->category_structure;
    1068                 }
    1069 
    1070                 if (empty($this->permalink_structure)) {
    1071                         $this->category_structure = '';
    1072                         return false;
    1073                 }
    1074 
    1075                 if (empty($this->category_base))
    1076                         $this->category_structure = $this->front . 'category/';
    1077                 else
    1078                         $this->category_structure = $this->category_base . '/';
    1079 
    1080                 $this->category_structure .= '%category%';
    1081 
    1082                 return $this->category_structure;
    1083         }
    1084 
    1085         function get_author_permastruct() {
    1086                 if (isset($this->author_structure)) {
    1087                         return $this->author_structure;
    1088                 }
    1089 
    1090                 if (empty($this->permalink_structure)) {
    1091                         $this->author_structure = '';
    1092                         return false;
    1093                 }
    1094 
    1095                 $this->author_structure = $this->front . $this->author_base . '/%author%';
    1096 
    1097                 return $this->author_structure;
    1098         }
    1099 
    1100         function get_search_permastruct() {
    1101                 if (isset($this->search_structure)) {
    1102                         return $this->search_structure;
    1103                 }
    1104 
    1105                 if (empty($this->permalink_structure)) {
    1106                         $this->search_structure = '';
    1107                         return false;
    1108                 }
    1109 
    1110                 $this->search_structure = $this->root . $this->search_base . '/%search%';
    1111 
    1112                 return $this->search_structure;
    1113         }
    1114 
    1115         function get_page_permastruct() {
    1116                 if (isset($this->page_structure)) {
    1117                         return $this->page_structure;
    1118                 }
    1119 
    1120                 if (empty($this->permalink_structure)) {
    1121                         $this->page_structure = '';
    1122                         return false;
    1123                 }
    1124 
    1125                 $this->page_structure = $this->root . '%pagename%';
    1126 
    1127                 return $this->page_structure;
    1128         }
    1129 
    1130         function get_feed_permastruct() {
    1131                 if (isset($this->feed_structure)) {
    1132                         return $this->feed_structure;
    1133                 }
    1134 
    1135                 if (empty($this->permalink_structure)) {
    1136                         $this->feed_structure = '';
    1137                         return false;
    1138                 }
    1139 
    1140                 $this->feed_structure = $this->root . $this->feed_base . '/%feed%';
    1141 
    1142                 return $this->feed_structure;
    1143         }
    1144 
    1145         function get_comment_feed_permastruct() {
    1146                 if (isset($this->comment_feed_structure)) {
    1147                         return $this->comment_feed_structure;
    1148                 }
    1149 
    1150                 if (empty($this->permalink_structure)) {
    1151                         $this->comment_feed_structure = '';
    1152                         return false;
    1153                 }
    1154 
    1155                 $this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%';
    1156 
    1157                 return $this->comment_feed_structure;
    1158         }
    1159 
    1160         function add_rewrite_tag($tag, $pattern, $query) {
    1161                 // If the tag already exists, replace the existing pattern and query for
    1162                 // that tag, otherwise add the new tag, pattern, and query to the end of
    1163                 // the arrays.
    1164                 $position = array_search($tag, $this->rewritecode);
    1165                 if (FALSE !== $position && NULL !== $position) {
    1166                         $this->rewritereplace[$position] = $pattern;
    1167                         $this->queryreplace[$position] = $query;
    1168                 } else {
    1169                         $this->rewritecode[] = $tag;
    1170                         $this->rewritereplace[] = $pattern;
    1171                         $this->queryreplace[] = $query;
    1172                 }
    1173         }
    1174 
    1175         function generate_rewrite_rules($permalink_structure, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true) {
    1176                 $feedregex2 = '';
    1177                 foreach ($this->feeds as $feed_name) {
    1178                         $feedregex2 .= $feed_name . '|';
    1179                 }
    1180                 $feedregex2 = '(' . trim($feedregex2, '|') .  ')/?$';
    1181                 $feedregex = $this->feed_base  . '/' . $feedregex2;
    1182 
    1183                 $trackbackregex = 'trackback/?$';
    1184                 $pageregex = 'page/?([0-9]{1,})/?$';
    1185 
    1186                 $front = substr($permalink_structure, 0, strpos($permalink_structure, '%'));
    1187                 preg_match_all('/%.+?%/', $permalink_structure, $tokens);
    1188 
    1189                 $num_tokens = count($tokens[0]);
    1190 
    1191                 $index = $this->index;
    1192                 $feedindex = $index;
    1193                 $trackbackindex = $index;
    1194                 for ($i = 0; $i < $num_tokens; ++$i) {
    1195                         if (0 < $i) {
    1196                                 $queries[$i] = $queries[$i - 1] . '&';
    1197                         }
    1198              
    1199                         $query_token = str_replace($this->rewritecode, $this->queryreplace, $tokens[0][$i]) . $this->preg_index($i+1);
    1200                         $queries[$i] .= $query_token;
    1201                 }
    1202 
    1203                 $structure = $permalink_structure;
    1204                 if ($front != '/') {
    1205                         $structure = str_replace($front, '', $structure);
    1206                 }
    1207                 $structure = trim($structure, '/');
    1208                 if ($walk_dirs) {
    1209                         $dirs = explode('/', $structure);
    1210                 } else {
    1211                         $dirs[] = $structure;
    1212                 }
    1213                 $num_dirs = count($dirs);
    1214 
    1215                 $front = preg_replace('|^/+|', '', $front);
    1216 
    1217                 $post_rewrite = array();
    1218                 $struct = $front;
    1219                 for ($j = 0; $j < $num_dirs; ++$j) {
    1220                         $struct .= $dirs[$j] . '/';
    1221                         $struct = ltrim($struct, '/');
    1222                         $match = str_replace($this->rewritecode, $this->rewritereplace, $struct);
    1223                         $num_toks = preg_match_all('/%.+?%/', $struct, $toks);
    1224                         $query = $queries[$num_toks - 1];
    1225 
    1226                         $pagematch = $match . $pageregex;
    1227                         $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1);
    1228 
    1229                         $feedmatch = $match . $feedregex;
    1230                         $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
    1231 
    1232                         $feedmatch2 = $match . $feedregex2;
    1233                         $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
    1234 
    1235                         if ($forcomments) {
    1236                                 $feedquery .= '&withcomments=1';
    1237                                 $feedquery2 .= '&withcomments=1';
    1238                         }
    1239 
    1240                         $rewrite = array();
    1241                         if ($feed)
    1242                                 $rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2);
    1243                         if ($paged)
    1244                                 $rewrite = array_merge($rewrite, array($pagematch => $pagequery));
    1245 
    1246                         if ($num_toks) {
    1247                                 $post = false;
    1248                                 $page = false;
    1249                                 if (strstr($struct, '%postname%') || strstr($struct, '%post_id%')
    1250                                                 || strstr($struct, '%pagename%')
    1251                                                 || (strstr($struct, '%year%') &&  strstr($struct, '%monthnum%') && strstr($struct, '%day%') && strstr($struct, '%hour%') && strstr($struct, '%minute') && strstr($struct, '%second%'))) {
    1252                                         $post = true;
    1253                                         if  ( strstr($struct, '%pagename%') )
    1254                                                 $page = true;
    1255                                         $trackbackmatch = $match . $trackbackregex;
    1256                                         $trackbackquery = $trackbackindex . '?' . $query . '&tb=1';
    1257                                         $match = rtrim($match, '/');
    1258                                         $submatchbase = str_replace(array('(',')'),'',$match);
    1259                                         $sub1 = $submatchbase . '/([^/]+)/';
    1260                                         $sub1tb = $sub1 . $trackbackregex;
    1261                                         $sub1feed = $sub1 . $feedregex;
    1262                                         $sub1feed2 = $sub1 . $feedregex2;
    1263                                         $sub1 .= '?$';
    1264                                         $sub2 = $submatchbase . '/attachment/([^/]+)/';
    1265                                         $sub2tb = $sub2 . $trackbackregex;
    1266                                         $sub2feed = $sub2 . $feedregex;
    1267                                         $sub2feed2 = $sub2 . $feedregex2;
    1268                                         $sub2 .= '?$';
    1269                                         $subquery = $index . '?attachment=' . $this->preg_index(1);
    1270                                         $subtbquery = $subquery . '&tb=1';
    1271                                         $subfeedquery = $subquery . '&feed=' . $this->preg_index(2);
    1272                                         $match = $match . '(/[0-9]+)?/?$';
    1273                                         $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1);
    1274                                 } else {
    1275                                         $match .= '?$';
    1276                                         $query = $index . '?' . $query;
    1277                                 }
    1278                                        
    1279                                 $rewrite = array_merge($rewrite, array($match => $query));
    1280 
    1281                                 if ($post) {
    1282                                         $rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite);
    1283                                         if ( ! $page )
    1284                                                 $rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery));
    1285                                         $rewrite = array_merge($rewrite, array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery));
    1286                                 }
    1287                         }
    1288                         $post_rewrite = array_merge($rewrite, $post_rewrite);
    1289                 }
    1290                 return $post_rewrite;
    1291         }
    1292 
    1293         function generate_rewrite_rule($permalink_structure, $walk_dirs = false) {
    1294                 return $this->generate_rewrite_rules($permalink_structure, false, false, false, $walk_dirs);
    1295         }
    1296 
    1297         /* rewrite_rules
    1298          * Construct rewrite matches and queries from permalink structure.
    1299          * Returns an associate array of matches and queries.
    1300          */
    1301         function rewrite_rules() {
    1302                 $rewrite = array();
    1303 
    1304                 if (empty($this->permalink_structure)) {
    1305                         return $rewrite;
    1306                 }
    1307 
    1308                 // Post
    1309                 $post_rewrite = $this->generate_rewrite_rules($this->permalink_structure);
    1310                 $post_rewrite = apply_filters('post_rewrite_rules', $post_rewrite);
    1311 
    1312                 // Date
    1313                 $date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct());
    1314                 $date_rewrite = apply_filters('date_rewrite_rules', $date_rewrite);
    1315 
    1316                 // Root
    1317                 $root_rewrite = $this->generate_rewrite_rules($this->root . '/');
    1318                 $root_rewrite = apply_filters('root_rewrite_rules', $root_rewrite);
    1319 
    1320                 // Comments
    1321                 $comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, true, true, true, false);
    1322                 $comments_rewrite = apply_filters('comments_rewrite_rules', $comments_rewrite);
    1323 
    1324                 // Search
    1325                 $search_structure = $this->get_search_permastruct();
    1326                 $search_rewrite = $this->generate_rewrite_rules($search_structure);
    1327                 $search_rewrite = apply_filters('search_rewrite_rules', $search_rewrite);
    1328 
    1329                 // Categories
    1330                 $category_rewrite = $this->generate_rewrite_rules($this->get_category_permastruct());
    1331                 $category_rewrite = apply_filters('category_rewrite_rules', $category_rewrite);
    1332 
    1333                 // Authors
    1334                 $author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct());
    1335                 $author_rewrite = apply_filters('author_rewrite_rules', $author_rewrite);
    1336 
    1337                 // Pages
    1338                 $page_rewrite = $this->page_rewrite_rules();
    1339                 $page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite);
    1340 
    1341                 // Put them together.
    1342                 $this->rules = array_merge($page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite);
    1343 
    1344                 do_action('generate_rewrite_rules', array(&$this));
    1345                 $this->rules = apply_filters('rewrite_rules_array', $this->rules);
    1346 
    1347                 return $this->rules;
    1348         }
    1349 
    1350         function wp_rewrite_rules() {
    1351                 $this->rules = get_option('rewrite_rules');
    1352                 if ( empty($this->rules) ) {
    1353                         $this->matches = 'matches';
    1354                         $this->rewrite_rules();
    1355                         update_option('rewrite_rules', $this->rules);
    1356                 }
    1357 
    1358                 return $this->rules;
    1359         }
    1360 
    1361         function mod_rewrite_rules() {
    1362                 if ( ! $this->using_permalinks()) {
    1363                         return '';
    1364                 }
    1365 
    1366                 $site_root = parse_url(get_settings('siteurl'));
    1367                 $site_root = trailingslashit($site_root['path']);
    1368 
    1369                 $home_root = parse_url(get_settings('home'));
    1370                 $home_root = trailingslashit($home_root['path']);
    1371    
    1372                 $rules = "<IfModule mod_rewrite.c>\n";
    1373                 $rules .= "RewriteEngine On\n";
    1374                 $rules .= "RewriteBase $home_root\n";
    1375 
    1376                 if ($this->use_verbose_rules) {
    1377                         $this->matches = '';
    1378                         $rewrite = $this->rewrite_rules();
    1379                         $num_rules = count($rewrite);
    1380                         $rules .= "RewriteCond %{REQUEST_FILENAME} -f [OR]\n" .
    1381                                 "RewriteCond %{REQUEST_FILENAME} -d\n" .
    1382                                 "RewriteRule ^.*$ - [S=$num_rules]\n";
    1383 
    1384                         foreach ($rewrite as $match => $query) {
    1385                                 // Apache 1.3 does not support the reluctant (non-greedy) modifier.
    1386                                 $match = str_replace('.+?', '.+', $match);
    1387 
    1388                                 // If the match is unanchored and greedy, prepend rewrite conditions
    1389                                 // to avoid infinite redirects and eclipsing of real files.
    1390                                 if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) {
    1391                                         //nada.
    1392                                 }
    1393 
    1394                                 if (strstr($query, $this->index)) {
    1395                                         $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";
    1396                                 } else {
    1397                                         $rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n";
    1398                                 }
    1399                         }
    1400                 } else {
    1401                         $rules .= "RewriteCond %{REQUEST_FILENAME} !-f\n" .
    1402                                 "RewriteCond %{REQUEST_FILENAME} !-d\n" .
    1403                                 "RewriteRule . {$home_root}{$this->index} [L]\n";
    1404                 }
    1405 
    1406                 $rules .= "</IfModule>\n";
    1407 
    1408                 $rules = apply_filters('mod_rewrite_rules', $rules);
    1409                 $rules = apply_filters('rewrite_rules', $rules);  // Deprecated
    1410 
    1411                 return $rules;
    1412         }
    1413 
    1414         function flush_rules() {
    1415                 generate_page_uri_index();
    1416                 delete_option('rewrite_rules');
    1417                 $this->wp_rewrite_rules();
    1418                 if ( function_exists('save_mod_rewrite_rules') )
    1419                         save_mod_rewrite_rules();
    1420         }
    1421 
    1422         function init() {
    1423                 $this->permalink_structure = get_settings('permalink_structure');
    1424                 $this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%'));
    1425                 $this->root = '';
    1426                 if ($this->using_index_permalinks()) {
    1427                         $this->root = $this->index . '/';
    1428                 }
    1429                 $this->category_base = get_settings('category_base');
    1430                 unset($this->category_structure);
    1431                 unset($this->author_structure);
    1432                 unset($this->date_structure);
    1433                 unset($this->page_structure);
    1434                 unset($this->search_structure);
    1435                 unset($this->feed_structure);
    1436                 unset($this->comment_feed_structure);
    1437         }
    1438 
    1439         function set_permalink_structure($permalink_structure) {
    1440                 if ($permalink_structure != $this->permalink_structure) {
    1441                         update_option('permalink_structure', $permalink_structure);
    1442                         $this->init();
    1443                 }
    1444         }
    1445 
    1446         function set_category_base($category_base) {
    1447                 if ($category_base != $this->category_base) {
    1448                         update_option('category_base', $category_base);
    1449                         $this->init();
    1450                 }
    1451         }
    1452 
    1453         function WP_Rewrite() {
    1454                 $this->init();
    1455         }
    1456 }
    1457 
    1458858class WP {
    1459859        var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview');
    1460860
     
    1467867        var $matched_rule;
    1468868        var $matched_query;
    1469869        var $did_permalink = false;
     870       
     871        function add_query_var($qv) {
     872                $this->public_query_vars[] = $qv;
     873        }
    1470874
    1471875        function parse_request($extra_query_vars = '') {
    1472876                global $wp_rewrite;
     
    1539943                                        preg_match("!^$match!", urldecode($request_match), $matches)) {
    1540944                                        // Got a match.
    1541945                                        $this->matched_rule = $match;
    1542 
     946                                       
    1543947                                        // Trim the query of everything up to the '?'.
    1544948                                        $query = preg_replace("!^.+\?!", '', $query);
    1545949
  • wp-settings.php

     
    140140require (ABSPATH . WPINC . '/template-functions-post.php');
    141141require (ABSPATH . WPINC . '/template-functions-category.php');
    142142require (ABSPATH . WPINC . '/comment-functions.php');
     143require (ABSPATH . WPINC . '/rewrite.php');
    143144require (ABSPATH . WPINC . '/feed-functions.php');
    144145require (ABSPATH . WPINC . '/template-functions-bookmarks.php');
    145146require (ABSPATH . WPINC . '/kses.php');
  • wp-feed.php

     
    1212    $feed = 'rss2';
    1313}
    1414
     15$file = $wp_rewrite->feed_files[$feed];
     16
    1517if ( is_single() || ($withcomments == 1) ) {
    1618    require(ABSPATH . 'wp-commentsrss2.php');
    17 } else {
    18     switch ($feed) {
    19     case 'atom':
    20         require(ABSPATH . 'wp-atom.php');
    21         break;
    22     case 'rdf':
    23         require(ABSPATH . 'wp-rdf.php');
    24         break;
    25     case 'rss':
    26         require(ABSPATH . 'wp-rss.php');
    27         break;
    28     case 'rss2':
    29         require(ABSPATH . 'wp-rss2.php');
    30         break;
    31     case 'comments-rss2':
    32         require(ABSPATH . 'wp-commentsrss2.php');
    33         break;
    34     }
     19} elseif (in_array($feed, $wp_rewrite->feeds) && !empty($file) && file_exists(ABSPATH . $file)) {
     20        require ABSPATH . $file;
    3521}
    3622
    3723?>