Ticket #2433: wp-rewrite-api.2.diff
File wp-rewrite-api.2.diff, 14.4 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 ?> 34 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 867 869 var $use_verbose_rules = false; 868 870 var $rewritecode = 869 871 array( … … 913 915 's=' 914 916 ); 915 917 916 var $feeds = array ('feed', 'rdf', 'rss', 'rss2', 'atom'); 917 918 var $feeds = array ( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); 919 920 //the filenames aren't actually used in WP_Rewrite but seems a convenient place as any to store them 921 var $feed_files = array ( 922 'rdf' => 'wp-rdf.php', 923 'rss' => 'wp-rss.php', 924 'rss2' => 'wp-rss2.php', 925 'atom' =>'wp-atom.php' 926 ); 927 918 928 function using_permalinks() { 919 929 if (empty($this->permalink_structure)) 920 930 return false; … … 1162 1172 } 1163 1173 } 1164 1174 1175 //the main WP_Rewrite function. generate the rules from permalink structure 1165 1176 function generate_rewrite_rules($permalink_structure, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true) { 1177 //build a regex to match the feed section of URLs, something like (feed|atom|rss|rss2)/? 1166 1178 $feedregex2 = ''; 1167 1179 foreach ($this->feeds as $feed_name) { 1168 1180 $feedregex2 .= $feed_name . '|'; 1169 1181 } 1170 1182 $feedregex2 = '(' . trim($feedregex2, '|') . ')/?$'; 1183 //$feedregex is identical but with /feed/ added on as well, so URLs like <permalink>/feed/atom 1184 //and <permalink>/atom are both possible 1171 1185 $feedregex = $this->feed_base . '/' . $feedregex2; 1172 1186 1187 //build a regex to match the trackback and page/xx parts of URLs 1173 1188 $trackbackregex = 'trackback/?$'; 1174 1189 $pageregex = 'page/?([0-9]{1,})/?$'; 1175 1190 1191 //get everything up to the first rewrite tag 1176 1192 $front = substr($permalink_structure, 0, strpos($permalink_structure, '%')); 1193 //build an array of the tags (note that said array ends up being in $tokens[0]) 1177 1194 preg_match_all('/%.+?%/', $permalink_structure, $tokens); 1178 1195 1179 1196 $num_tokens = count($tokens[0]); 1180 1197 1181 $index = $this->index; 1198 $index = $this->index; //probably 'index.php' 1182 1199 $feedindex = $index; 1183 1200 $trackbackindex = $index; 1201 //build a list from the rewritecode and queryreplace arrays, that will look something like 1202 //tagname=$matches[i] where i is the current $i 1184 1203 for ($i = 0; $i < $num_tokens; ++$i) { 1185 1204 if (0 < $i) { 1186 1205 $queries[$i] = $queries[$i - 1] . '&'; … … 1190 1209 $queries[$i] .= $query_token; 1191 1210 } 1192 1211 1212 //get the structure, minus any cruft (stuff that isn't tags) at the front 1193 1213 $structure = $permalink_structure; 1194 1214 if ($front != '/') { 1195 1215 $structure = str_replace($front, '', $structure); 1196 1216 } 1217 //create a list of dirs to walk over, making rewrite rules for each level 1218 //so for example, a $structure of /%year%/%month%/%postname% would create 1219 //rewrite rules for /%year%/, /%year%/%month%/ and /%year%/%month%/%postname% 1197 1220 $structure = trim($structure, '/'); 1198 1221 if ($walk_dirs) { 1199 1222 $dirs = explode('/', $structure); … … 1202 1225 } 1203 1226 $num_dirs = count($dirs); 1204 1227 1228 //strip slashes from the front of $front 1205 1229 $front = preg_replace('|^/+|', '', $front); 1206 1230 1231 //the main workhorse loop 1207 1232 $post_rewrite = array(); 1208 1233 $struct = $front; 1209 1234 for ($j = 0; $j < $num_dirs; ++$j) { 1210 $struct .= $dirs[$j] . '/'; 1235 //get the struct for this dir, and trim slashes off the front 1236 $struct .= $dirs[$j] . '/'; //accumulate. see comment near explode('/', $structure) above 1211 1237 $struct = ltrim($struct, '/'); 1238 //replace tags with regexes 1212 1239 $match = str_replace($this->rewritecode, $this->rewritereplace, $struct); 1240 //make a list of tags, and store how many there are in $num_toks 1213 1241 $num_toks = preg_match_all('/%.+?%/', $struct, $toks); 1242 //get the 'tagname=$matches[i]' 1214 1243 $query = $queries[$num_toks - 1]; 1215 1244 1245 //create query for /page/xx 1216 1246 $pagematch = $match . $pageregex; 1217 1247 $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1); 1218 1248 1249 //create query for /feed/(feed|atom|rss|rss2|rdf) 1219 1250 $feedmatch = $match . $feedregex; 1220 1251 $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); 1221 1252 1253 //create query for /(feed|atom|rss|rss2|rdf) (see comment near creation of $feedregex) 1222 1254 $feedmatch2 = $match . $feedregex2; 1223 1255 $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); 1224 1256 1257 //if asked to, turn the feed queries into comment feed ones 1225 1258 if ($forcomments) { 1226 1259 $feedquery .= '&withcomments=1'; 1227 1260 $feedquery2 .= '&withcomments=1'; 1228 1261 } 1229 1262 1263 //start creating the array of rewrites for this dir 1230 1264 $rewrite = array(); 1231 if ($feed) 1265 if ($feed) //...adding on /feed/ regexes => queries 1232 1266 $rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2); 1233 if ($paged) 1267 if ($paged) //...and /page/xx ones 1234 1268 $rewrite = array_merge($rewrite, array($pagematch => $pagequery)); 1235 1269 1270 //if we've got some tags in this dir 1236 1271 if ($num_toks) { 1237 1272 $post = false; 1238 1273 $page = false; 1274 1275 //check to see if this dir is permalink-level: i.e. the structure specifies an 1276 //individual post. Do this by checking it contains at least one of 1) post name, 1277 //2) post ID, 3) page name, 4) timestamp (year, month, day, hour, second and 1278 //minute all present) 1239 1279 if (strstr($struct, '%postname%') || strstr($struct, '%post_id%') 1240 1280 || strstr($struct, '%pagename%') 1241 1281 || (strstr($struct, '%year%') && strstr($struct, '%monthnum%') && strstr($struct, '%day%') && strstr($struct, '%hour%') && strstr($struct, '%minute') && strstr($struct, '%second%'))) { 1242 1282 $post = true; 1243 1283 if ( strstr($struct, '%pagename%') ) 1244 1284 $page = true; 1285 //create query and regex for trackback 1245 1286 $trackbackmatch = $match . $trackbackregex; 1246 1287 $trackbackquery = $trackbackindex . '?' . $query . '&tb=1'; 1288 //trim slashes from the end of the regex for this dir 1247 1289 $match = rtrim($match, '/'); 1290 //get rid of brackets 1248 1291 $submatchbase = str_replace(array('(',')'),'',$match); 1292 1293 //add a rule for at attachements, which take the form of <permalink>/some-text 1249 1294 $sub1 = $submatchbase . '/([^/]+)/'; 1250 $sub1tb = $sub1 . $trackbackregex; 1251 $sub1feed = $sub1 . $feedregex; 1252 $sub1feed2 = $sub1 . $feedregex2; 1295 $sub1tb = $sub1 . $trackbackregex; //add trackback regex 1296 $sub1feed = $sub1 . $feedregex; //and /feed/(atom|...) 1297 $sub1feed2 = $sub1 . $feedregex2; //and (feed|atom...) 1298 //add an ? as we don't have to match that last slash, and finally a $ so we 1299 //match to the end of the URL 1253 1300 $sub1 .= '?$'; 1301 1302 //add another rule to match attachments in the explicit form: 1303 //<permalink>/attachment/some-text 1254 1304 $sub2 = $submatchbase . '/attachment/([^/]+)/'; 1255 $sub2tb = $sub2 . $trackbackregex; 1256 $sub2feed = $sub2 . $feedregex; 1257 $sub2feed2 = $sub2 . $feedregex2; 1258 $sub2 .= '?$'; 1305 $sub2tb = $sub2 . $trackbackregex; //and add trackbacks, 1306 $sub2feed = $sub2 . $feedregex; //feeds, 1307 $sub2feed2 = $sub2 . $feedregex2; //and feeds again on to this 1308 $sub2 .= '?$'; //add a ?$ as above 1309 1310 //create queries for these extra tag-ons we've just dealt with 1259 1311 $subquery = $index . '?attachment=' . $this->preg_index(1); 1260 1312 $subtbquery = $subquery . '&tb=1'; 1261 1313 $subfeedquery = $subquery . '&feed=' . $this->preg_index(2); 1314 1315 //allow URLs like <permalink>/2 for <permalink>/page/2 1262 1316 $match = $match . '(/[0-9]+)?/?$'; 1263 1317 $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1); 1264 1318 } else { 1319 //not matching a permalink so this is a lot simpler 1265 1320 $match .= '?$'; 1266 1321 $query = $index . '?' . $query; 1267 1322 } 1268 1323 1324 //create the final array for this dir by joining the $rewrite array (which currently 1325 //only contains rules/queries for trackback, pages etc) to the main regex/query for 1326 //this dir 1269 1327 $rewrite = array_merge($rewrite, array($match => $query)); 1270 1328 1329 //if we're matching a permalink, add those extras (attachments etc) on 1271 1330 if ($post) { 1331 //add trackback 1272 1332 $rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite); 1273 if ( ! $page ) 1333 1334 //add regexes/queries for attachments, attachment trackbacks and so on 1335 if ( ! $page ) //require <permalink>/attachment/stuff form for pages because of confusion with subpages 1274 1336 $rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery)); 1275 1337 $rewrite = array_merge($rewrite, array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery)); 1276 1338 } 1277 1339 } 1340 //add the rules for this dir to the accumulating $post_rewrite 1278 1341 $post_rewrite = array_merge($rewrite, $post_rewrite); 1279 1342 } 1280 return $post_rewrite; 1343 return $post_rewrite; //the finished rules. phew! 1281 1344 } 1282 1345 1283 1346 function generate_rewrite_rule($permalink_structure, $walk_dirs = false) { … … 1329 1392 $page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite); 1330 1393 1331 1394 // Put them together. 1332 $this->rules = array_merge($page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite );1395 $this->rules = array_merge($page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules); 1333 1396 1334 1397 do_action('generate_rewrite_rules', array(&$this)); 1335 1398 $this->rules = apply_filters('rewrite_rules_array', $this->rules); … … 1362 1425 $rules = "<IfModule mod_rewrite.c>\n"; 1363 1426 $rules .= "RewriteEngine On\n"; 1364 1427 $rules .= "RewriteBase $home_root\n"; 1428 1429 //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all) 1430 foreach ($this->non_wp_rules as $match => $query) { 1431 // Apache 1.3 does not support the reluctant (non-greedy) modifier. 1432 $match = str_replace('.+?', '.+', $match); 1365 1433 1434 // If the match is unanchored and greedy, prepend rewrite conditions 1435 // to avoid infinite redirects and eclipsing of real files. 1436 if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) { 1437 //nada. 1438 } 1439 1440 $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; 1441 } 1442 1366 1443 if ($this->use_verbose_rules) { 1367 1444 $this->matches = ''; 1368 1445 $rewrite = $this->rewrite_rules(); … … 1400 1477 1401 1478 return $rules; 1402 1479 } 1480 1481 //Add a straight rewrite rule 1482 function add_extra_rule($regex, $redirect) { 1483 //get everything up to the first ? 1484 $index = (strpos($redirect, '?') == false ? strlen($redirect) : strpos($redirect, '?')); 1485 $front = substr($redirect, 0, $index); 1486 if ($front != $this->index) { //it doesn't redirect to WP's index.php 1487 $this->add_non_wp_rule($regex, $redirect); 1488 } else { 1489 $this->extra_rules[$regex] = $redirect; 1490 } 1491 } 1492 1493 //add a rule that doesn't redirect to index.php 1494 function add_non_wp_rule($regex, $redirect) { 1495 $this->non_wp_rules[$regex] = $redirect; 1496 } 1403 1497 1404 1498 function flush_rules() { 1405 1499 generate_page_uri_index(); … … 1410 1504 } 1411 1505 1412 1506 function init() { 1507 $this->extra_rules = $this->non_wp_rules = array(); 1413 1508 $this->permalink_structure = get_settings('permalink_structure'); 1414 1509 $this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%')); 1415 1510 $this->root = ''; … … 1456 1551 var $matched_rule; 1457 1552 var $matched_query; 1458 1553 var $did_permalink = false; 1554 1555 function add_extra_qv($qv) { 1556 $this->public_query_vars[] = $qv; 1557 } 1459 1558 1460 1559 function parse_request($extra_query_vars = '') { 1461 1560 global $wp_rewrite; … … 1530 1629 preg_match("!^$match!", urldecode($request_match), $matches)) { 1531 1630 // Got a match. 1532 1631 $this->matched_rule = $match; 1533 1632 1534 1633 // Trim the query of everything up to the '?'. 1535 1634 $query = preg_replace("!^.+\?!", '', $query); 1536 1635 -
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 ?>