Ticket #2433: wp-rewrite-api.3.diff
File wp-rewrite-api.3.diff, 19.5 KB (added by , 19 years ago) |
---|
-
wp-includes/rewrite-functions.php
1 <?php 2 3 //Add a straight rewrite rule 4 function add_rewrite_rule($regex, $redirect) { 5 global $wp_rewrite; 6 $wp_rewrite->add_extra_rule($regex, $redirect); 7 } 8 9 //Add a new tag (like %postname%) 10 //warning: you must call this on init or earlier, otherwise the query var addition stuff won't work 11 function add_rewrite_tag($tagname, $regex) { 12 //validation 13 if (strlen($tagname) < 3 || $tagname{0} != '%' || $tagname{strlen($tagname)-1} != '%') { 14 return; 15 } 16 17 $qv = trim($tagname, '%'); 18 19 global $wp_rewrite, $wp; 20 $wp->add_extra_qv($qv); 21 $wp_rewrite->add_rewrite_tag($tagname, $regex, $qv . '='); 22 } 23 24 //Add a new feed type like /atom1/ 25 function add_feed($feedname, $filename) { 26 global $wp_rewrite; 27 if (!in_array($feedname, $wp_rewrite->feeds)) { //override the file if it is 28 $wp_rewrite->feeds[] = $feedname; 29 } 30 $wp_rewrite->feed_files[$feedname] = $filename; 31 } 32 33 define('EP_PERMALINK', 1 ); 34 define('EP_DATE', 2 ); 35 define('EP_ROOT', 4 ); 36 define('EP_COMMENTS', 8 ); 37 define('EP_SEARCH', 16 ); 38 define('EP_CATEGORIES', 32 ); 39 define('EP_AUTHORS', 64 ); 40 define('EP_PAGES', 128); 41 //pseudo-places 42 define('EP_NONE', 0 ); 43 define('EP_ALL', 255); 44 45 //and an endpoint, like /trackback/ 46 function add_endpoint($name, $places) { 47 global $wp_rewrite; 48 $wp_rewrite->add_endpoint($name, $func, $places); 49 } 50 51 ?> 52 No newline at end of file -
wp-includes/classes.php
864 864 var $index = 'index.php'; 865 865 var $matches = ''; 866 866 var $rules; 867 var $extra_rules; //those not generated by the class, see add_rewrite_rule() 868 var $non_wp_rules; //rules that don't redirect to WP's index.php 869 var $endpoints; 867 870 var $use_verbose_rules = false; 868 871 var $rewritecode = 869 872 array( … … 913 916 's=' 914 917 ); 915 918 916 var $feeds = array ('feed', 'rdf', 'rss', 'rss2', 'atom'); 917 919 var $feeds = array ( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); 920 921 //the filenames aren't actually used in WP_Rewrite but seems a convenient place as any to store them 922 var $feed_files = array ( 923 'rdf' => 'wp-rdf.php', 924 'rss' => 'wp-rss.php', 925 'rss2' => 'wp-rss2.php', 926 'atom' =>'wp-atom.php' 927 ); 928 918 929 function using_permalinks() { 919 930 if (empty($this->permalink_structure)) 920 931 return false; … … 963 974 if( is_array( $attachment_uris ) ) { 964 975 foreach ($attachment_uris as $uri => $pagename) { 965 976 $this->add_rewrite_tag('%pagename%', "($uri)", 'attachment='); 966 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure ));977 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); 967 978 } 968 979 } 969 980 if( is_array( $uris ) ) { 970 981 foreach ($uris as $uri => $pagename) { 971 982 $this->add_rewrite_tag('%pagename%', "($uri)", 'pagename='); 972 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure ));983 $rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES)); 973 984 } 974 985 } 975 986 … … 1162 1173 } 1163 1174 } 1164 1175 1165 function generate_rewrite_rules($permalink_structure, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true) { 1176 //the main WP_Rewrite function. generate the rules from permalink structure 1177 function generate_rewrite_rules($permalink_structure, $ep_mask = EP_NONE, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true) { 1178 //build a regex to match the feed section of URLs, something like (feed|atom|rss|rss2)/? 1166 1179 $feedregex2 = ''; 1167 1180 foreach ($this->feeds as $feed_name) { 1168 1181 $feedregex2 .= $feed_name . '|'; 1169 1182 } 1170 1183 $feedregex2 = '(' . trim($feedregex2, '|') . ')/?$'; 1184 //$feedregex is identical but with /feed/ added on as well, so URLs like <permalink>/feed/atom 1185 //and <permalink>/atom are both possible 1171 1186 $feedregex = $this->feed_base . '/' . $feedregex2; 1172 1187 1188 //build a regex to match the trackback and page/xx parts of URLs 1173 1189 $trackbackregex = 'trackback/?$'; 1174 1190 $pageregex = 'page/?([0-9]{1,})/?$'; 1191 1192 //build up an array of endpoint regexes to append => queries to append 1193 if ($endpoints) { 1194 $ep_query_append = array (); 1195 foreach ($this->endpoints as $endpoint) { 1196 //match everything after the endpoint name, but allow for nothing to appear there 1197 $epmatch = $endpoint[1] . '(/(.*))?/?$'; 1198 //this will be appended on to the rest of the query for each dir 1199 $epquery = '&' . $endpoint[1] . '=' . $this->preg_index(2); 1200 $ep_query_append[$epmatch] = array ( $endpoint[0], $epquery ); 1201 } 1202 } 1175 1203 1204 //get everything up to the first rewrite tag 1176 1205 $front = substr($permalink_structure, 0, strpos($permalink_structure, '%')); 1206 //build an array of the tags (note that said array ends up being in $tokens[0]) 1177 1207 preg_match_all('/%.+?%/', $permalink_structure, $tokens); 1178 1208 1179 1209 $num_tokens = count($tokens[0]); 1180 1210 1181 $index = $this->index; 1211 $index = $this->index; //probably 'index.php' 1182 1212 $feedindex = $index; 1183 1213 $trackbackindex = $index; 1214 //build a list from the rewritecode and queryreplace arrays, that will look something like 1215 //tagname=$matches[i] where i is the current $i 1184 1216 for ($i = 0; $i < $num_tokens; ++$i) { 1185 1217 if (0 < $i) { 1186 1218 $queries[$i] = $queries[$i - 1] . '&'; … … 1190 1222 $queries[$i] .= $query_token; 1191 1223 } 1192 1224 1225 //get the structure, minus any cruft (stuff that isn't tags) at the front 1193 1226 $structure = $permalink_structure; 1194 1227 if ($front != '/') { 1195 1228 $structure = str_replace($front, '', $structure); 1196 1229 } 1230 //create a list of dirs to walk over, making rewrite rules for each level 1231 //so for example, a $structure of /%year%/%month%/%postname% would create 1232 //rewrite rules for /%year%/, /%year%/%month%/ and /%year%/%month%/%postname% 1197 1233 $structure = trim($structure, '/'); 1198 1234 if ($walk_dirs) { 1199 1235 $dirs = explode('/', $structure); … … 1202 1238 } 1203 1239 $num_dirs = count($dirs); 1204 1240 1241 //strip slashes from the front of $front 1205 1242 $front = preg_replace('|^/+|', '', $front); 1206 1243 1244 //the main workhorse loop 1207 1245 $post_rewrite = array(); 1208 1246 $struct = $front; 1209 1247 for ($j = 0; $j < $num_dirs; ++$j) { 1210 $struct .= $dirs[$j] . '/'; 1248 //get the struct for this dir, and trim slashes off the front 1249 $struct .= $dirs[$j] . '/'; //accumulate. see comment near explode('/', $structure) above 1211 1250 $struct = ltrim($struct, '/'); 1251 //replace tags with regexes 1212 1252 $match = str_replace($this->rewritecode, $this->rewritereplace, $struct); 1253 //make a list of tags, and store how many there are in $num_toks 1213 1254 $num_toks = preg_match_all('/%.+?%/', $struct, $toks); 1255 //get the 'tagname=$matches[i]' 1214 1256 $query = $queries[$num_toks - 1]; 1215 1257 1258 //create query for /page/xx 1216 1259 $pagematch = $match . $pageregex; 1217 1260 $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1); 1218 1261 1262 //create query for /feed/(feed|atom|rss|rss2|rdf) 1219 1263 $feedmatch = $match . $feedregex; 1220 1264 $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); 1221 1265 1266 //create query for /(feed|atom|rss|rss2|rdf) (see comment near creation of $feedregex) 1222 1267 $feedmatch2 = $match . $feedregex2; 1223 1268 $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); 1224 1269 1270 //if asked to, turn the feed queries into comment feed ones 1225 1271 if ($forcomments) { 1226 1272 $feedquery .= '&withcomments=1'; 1227 1273 $feedquery2 .= '&withcomments=1'; 1228 1274 } 1229 1275 1276 //start creating the array of rewrites for this dir 1230 1277 $rewrite = array(); 1231 if ($feed) 1278 if ($feed) //...adding on /feed/ regexes => queries 1232 1279 $rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2); 1233 if ($paged) 1280 if ($paged) //...and /page/xx ones 1234 1281 $rewrite = array_merge($rewrite, array($pagematch => $pagequery)); 1235 1282 1283 //if we've got some tags in this dir 1236 1284 if ($num_toks) { 1237 1285 $post = false; 1238 1286 $page = false; 1287 1288 //check to see if this dir is permalink-level: i.e. the structure specifies an 1289 //individual post. Do this by checking it contains at least one of 1) post name, 1290 //2) post ID, 3) page name, 4) timestamp (year, month, day, hour, second and 1291 //minute all present). Set these flags now as we need them for the endpoints. 1239 1292 if (strstr($struct, '%postname%') || strstr($struct, '%post_id%') 1240 1293 || strstr($struct, '%pagename%') 1241 1294 || (strstr($struct, '%year%') && strstr($struct, '%monthnum%') && strstr($struct, '%day%') && strstr($struct, '%hour%') && strstr($struct, '%minute') && strstr($struct, '%second%'))) { 1242 1295 $post = true; 1243 1296 if ( strstr($struct, '%pagename%') ) 1244 1297 $page = true; 1298 } 1299 1300 //do endpoints 1301 if ($endpoints) { 1302 foreach ($ep_query_append as $regex => $ep) { 1303 //add the endpoints on if 1) it's a permalink and there's flags for a permalink or 2) 1304 //it's not a permalink (then we don't do any flag checking as it should have happened in 1305 //rewrite_rules()) 1306 if ($ep[0] & $ep_mask) { 1307 $rewrite[$match . $regex] = $index . '?' . $query . $ep[1]; 1308 } 1309 } 1310 } 1311 1312 //if we're creating rules for a permalink 1313 if ($post) { 1314 $post = true; 1315 //create query and regex for trackback 1245 1316 $trackbackmatch = $match . $trackbackregex; 1246 1317 $trackbackquery = $trackbackindex . '?' . $query . '&tb=1'; 1318 //trim slashes from the end of the regex for this dir 1247 1319 $match = rtrim($match, '/'); 1320 //get rid of brackets 1248 1321 $submatchbase = str_replace(array('(',')'),'',$match); 1322 1323 //add a rule for at attachements, which take the form of <permalink>/some-text 1249 1324 $sub1 = $submatchbase . '/([^/]+)/'; 1250 $sub1tb = $sub1 . $trackbackregex; 1251 $sub1feed = $sub1 . $feedregex; 1252 $sub1feed2 = $sub1 . $feedregex2; 1325 $sub1tb = $sub1 . $trackbackregex; //add trackback regex 1326 $sub1feed = $sub1 . $feedregex; //and /feed/(atom|...) 1327 $sub1feed2 = $sub1 . $feedregex2; //and (feed|atom...) 1328 //add an ? as we don't have to match that last slash, and finally a $ so we 1329 //match to the end of the URL 1253 1330 $sub1 .= '?$'; 1331 1332 //add another rule to match attachments in the explicit form: 1333 //<permalink>/attachment/some-text 1254 1334 $sub2 = $submatchbase . '/attachment/([^/]+)/'; 1255 $sub2tb = $sub2 . $trackbackregex; 1256 $sub2feed = $sub2 . $feedregex; 1257 $sub2feed2 = $sub2 . $feedregex2; 1258 $sub2 .= '?$'; 1335 $sub2tb = $sub2 . $trackbackregex; //and add trackbacks, 1336 $sub2feed = $sub2 . $feedregex; //feeds, 1337 $sub2feed2 = $sub2 . $feedregex2; //and feeds again on to this 1338 $sub2 .= '?$'; //add a ?$ as above 1339 1340 //create queries for these extra tag-ons we've just dealt with 1259 1341 $subquery = $index . '?attachment=' . $this->preg_index(1); 1260 1342 $subtbquery = $subquery . '&tb=1'; 1261 1343 $subfeedquery = $subquery . '&feed=' . $this->preg_index(2); 1344 1345 //allow URLs like <permalink>/2 for <permalink>/page/2 1262 1346 $match = $match . '(/[0-9]+)?/?$'; 1263 1347 $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1); 1264 } else { 1348 } else { //not matching a permalink so this is a lot simpler 1349 //close the match and finalise the query 1265 1350 $match .= '?$'; 1266 1351 $query = $index . '?' . $query; 1267 1352 } 1268 1353 1354 //create the final array for this dir by joining the $rewrite array (which currently 1355 //only contains rules/queries for trackback, pages etc) to the main regex/query for 1356 //this dir 1269 1357 $rewrite = array_merge($rewrite, array($match => $query)); 1270 1358 1359 //if we're matching a permalink, add those extras (attachments etc) on 1271 1360 if ($post) { 1361 //add trackback 1272 1362 $rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite); 1273 if ( ! $page ) 1363 1364 //add regexes/queries for attachments, attachment trackbacks and so on 1365 if ( ! $page ) //require <permalink>/attachment/stuff form for pages because of confusion with subpages 1274 1366 $rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery)); 1275 1367 $rewrite = array_merge($rewrite, array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery)); 1276 1368 } 1277 1369 } 1370 //add the rules for this dir to the accumulating $post_rewrite 1278 1371 $post_rewrite = array_merge($rewrite, $post_rewrite); 1279 1372 } 1280 return $post_rewrite; 1373 return $post_rewrite; //the finished rules. phew! 1281 1374 } 1282 1375 1283 1376 function generate_rewrite_rule($permalink_structure, $walk_dirs = false) { 1284 return $this->generate_rewrite_rules($permalink_structure, false, false, false, $walk_dirs);1377 return $this->generate_rewrite_rules($permalink_structure, EP_NONE, false, false, false, $walk_dirs); 1285 1378 } 1286 1379 1287 1380 /* rewrite_rules … … 1296 1389 } 1297 1390 1298 1391 // Post 1299 $post_rewrite = $this->generate_rewrite_rules($this->permalink_structure );1392 $post_rewrite = $this->generate_rewrite_rules($this->permalink_structure, EP_PERMALINK); 1300 1393 $post_rewrite = apply_filters('post_rewrite_rules', $post_rewrite); 1301 1394 1302 1395 // Date 1303 $date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct() );1396 $date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct(), EP_DATE); 1304 1397 $date_rewrite = apply_filters('date_rewrite_rules', $date_rewrite); 1305 1398 1306 1399 // Root 1307 $root_rewrite = $this->generate_rewrite_rules($this->root . '/' );1400 $root_rewrite = $this->generate_rewrite_rules($this->root . '/', EP_ROOT); 1308 1401 $root_rewrite = apply_filters('root_rewrite_rules', $root_rewrite); 1309 1402 1310 1403 // Comments 1311 $comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, true, true, true);1404 $comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, EP_COMMENTS, true, true, true); 1312 1405 $comments_rewrite = apply_filters('comments_rewrite_rules', $comments_rewrite); 1313 1406 1314 1407 // Search 1315 1408 $search_structure = $this->get_search_permastruct(); 1316 $search_rewrite = $this->generate_rewrite_rules($search_structure );1409 $search_rewrite = $this->generate_rewrite_rules($search_structure, EP_SEARCH); 1317 1410 $search_rewrite = apply_filters('search_rewrite_rules', $search_rewrite); 1318 1411 1319 1412 // Categories 1320 $category_rewrite = $this->generate_rewrite_rules($this->get_category_permastruct() );1413 $category_rewrite = $this->generate_rewrite_rules($this->get_category_permastruct(), EP_CATEGORIES); 1321 1414 $category_rewrite = apply_filters('category_rewrite_rules', $category_rewrite); 1322 1415 1323 1416 // Authors 1324 $author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct() );1417 $author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct(), EP_AUTHORS); 1325 1418 $author_rewrite = apply_filters('author_rewrite_rules', $author_rewrite); 1326 1419 1327 1420 // Pages … … 1329 1422 $page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite); 1330 1423 1331 1424 // Put them together. 1332 $this->rules = array_merge($page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite );1425 $this->rules = array_merge($page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules); 1333 1426 1334 1427 do_action('generate_rewrite_rules', array(&$this)); 1335 1428 $this->rules = apply_filters('rewrite_rules_array', $this->rules); … … 1362 1455 $rules = "<IfModule mod_rewrite.c>\n"; 1363 1456 $rules .= "RewriteEngine On\n"; 1364 1457 $rules .= "RewriteBase $home_root\n"; 1458 1459 //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all) 1460 foreach ($this->non_wp_rules as $match => $query) { 1461 // Apache 1.3 does not support the reluctant (non-greedy) modifier. 1462 $match = str_replace('.+?', '.+', $match); 1365 1463 1464 // If the match is unanchored and greedy, prepend rewrite conditions 1465 // to avoid infinite redirects and eclipsing of real files. 1466 if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) { 1467 //nada. 1468 } 1469 1470 $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; 1471 } 1472 1366 1473 if ($this->use_verbose_rules) { 1367 1474 $this->matches = ''; 1368 1475 $rewrite = $this->rewrite_rules(); … … 1400 1507 1401 1508 return $rules; 1402 1509 } 1510 1511 //Add a straight rewrite rule 1512 function add_extra_rule($regex, $redirect) { 1513 //get everything up to the first ? 1514 $index = (strpos($redirect, '?') == false ? strlen($redirect) : strpos($redirect, '?')); 1515 $front = substr($redirect, 0, $index); 1516 if ($front != $this->index) { //it doesn't redirect to WP's index.php 1517 $this->add_non_wp_rule($regex, $redirect); 1518 } else { 1519 $this->extra_rules[$regex] = $redirect; 1520 } 1521 } 1522 1523 //add a rule that doesn't redirect to index.php 1524 function add_non_wp_rule($regex, $redirect) { 1525 $this->non_wp_rules[$regex] = $redirect; 1526 } 1527 1528 //add an endpoint, like /trackback/, to be inserted after certain URL types (specified in $places) 1529 function add_endpoint($name, $places) { 1530 global $wp; 1531 $this->endpoints[] = array ( $places, $name ); 1532 $wp->add_extra_qv($name); 1533 } 1403 1534 1404 1535 function flush_rules() { 1405 1536 generate_page_uri_index(); … … 1410 1541 } 1411 1542 1412 1543 function init() { 1544 $this->extra_rules = $this->non_wp_rules = $this->endpoints = array(); 1413 1545 $this->permalink_structure = get_settings('permalink_structure'); 1414 1546 $this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%')); 1415 1547 $this->root = ''; … … 1456 1588 var $matched_rule; 1457 1589 var $matched_query; 1458 1590 var $did_permalink = false; 1591 1592 function add_extra_qv($qv) { 1593 $this->public_query_vars[] = $qv; 1594 } 1459 1595 1460 1596 function parse_request($extra_query_vars = '') { 1461 1597 global $wp_rewrite; … … 1471 1607 1472 1608 // Fetch the rewrite rules. 1473 1609 $rewrite = $wp_rewrite->wp_rewrite_rules(); 1610 print_r($rewrite); 1474 1611 1475 1612 if (! empty($rewrite)) { 1476 1613 // If we match a rewrite rule, this will be cleared. … … 1530 1667 preg_match("!^$match!", urldecode($request_match), $matches)) { 1531 1668 // Got a match. 1532 1669 $this->matched_rule = $match; 1533 1670 1534 1671 // Trim the query of everything up to the '?'. 1535 1672 $query = preg_replace("!^.+\?!", '', $query); 1536 1673 -
wp-settings.php
138 138 require (ABSPATH . WPINC . '/template-functions-post.php'); 139 139 require (ABSPATH . WPINC . '/template-functions-category.php'); 140 140 require (ABSPATH . WPINC . '/comment-functions.php'); 141 require (ABSPATH . WPINC . '/rewrite-functions.php'); 141 142 require (ABSPATH . WPINC . '/feed-functions.php'); 142 143 require (ABSPATH . WPINC . '/links.php'); 143 144 require (ABSPATH . WPINC . '/kses.php'); -
wp-feed.php
12 12 $feed = 'rss2'; 13 13 } 14 14 15 $file = $wp_rewrite->feed_files[$feed]; 16 15 17 if ( is_single() || ($withcomments == 1) ) { 16 18 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; 21 } 35 22 } 36 23 37 24 ?>