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