WordPressを読む 47-3 /blog/wp-includes/rewrite.php 3
2015/01/15
目次
- 1 /blog/wp-includes/rewrite.php 3
- 2 クラス WP_Rewrite::page_rewrite_rules()
- 3 クラス WP_Rewrite::get_date_permastruct()
- 4 クラス WP_Rewrite::get_year_permastruct()
- 5 クラス WP_Rewrite::get_month_permastruct()
- 6 クラス WP_Rewrite::get_day_permastruct()
- 7 クラス WP_Rewrite::get_category_permastruct()
- 8 クラス WP_Rewrite::get_tag_permastruct()
- 9 クラス WP_Rewrite::get_extra_permastruct()
- 10 クラス WP_Rewrite::get_author_permastruct()
- 11 クラス WP_Rewrite::get_search_permastruct()
- 12 クラス WP_Rewrite::get_page_permastruct()
- 13 クラス WP_Rewrite::get_feed_permastruct()
- 14 クラス WP_Rewrite::get_comment_feed_permastruct()
- 15 クラス WP_Rewrite::add_rewrite_tag()
- 16 クラス WP_Rewrite::generate_rewrite_rules()
/blog/wp-includes/rewrite.php 3
クラス WP_Rewrite::page_rewrite_rules()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** * WordPress Rewrite Component. * * The WordPress Rewrite /** * Retrieve all of the rewrite rules for pages. * * @since 1.5.0 * @access public * * @return array */ public function page_rewrite_rules() { // the extra .? at the beginning prevents clashes with other regular expressions in the rules array $this->add_rewrite_tag( '%pagename%', '(.?.+?)', 'pagename=' ); return $this->generate_rewrite_rules( $this->get_page_permastruct(), EP_PAGES, true, true, false, false ); } |
クラス WP_Rewrite::get_date_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** * Retrieve date permalink structure, with year, month, and day. * * The permalink structure for the date, if not set already depends on the * permalink structure. It can be one of three formats. The first is year, * month, day; the second is day, month, year; and the last format is month, * day, year. These are matched against the permalink structure for which * one is used. If none matches, then the default will be used, which is * year, month, day. * * Prevents post ID and date permalinks from overlapping. In the case of * post_id, the date permalink will be prepended with front permalink with * 'date/' before the actual permalink to form the complete date permalink * structure. * * @since 1.5.0 * @access public * * @return bool|string False on no permalink structure. Date permalink structure. */ public function get_date_permastruct() { if ( isset($this->date_structure) ) return $this->date_structure; if ( empty($this->permalink_structure) ) { $this->date_structure = ''; return false; } // The date permalink must have year, month, and day separated by slashes. $endians = array('%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%'); $this->date_structure = ''; $date_endian = ''; foreach ( $endians as $endian ) { if ( false !== strpos($this->permalink_structure, $endian) ) { $date_endian= $endian; break; } } if ( empty($date_endian) ) $date_endian = '%year%/%monthnum%/%day%'; // Do not allow the date tags and %post_id% to overlap in the permalink // structure. If they do, move the date tags to $front/date/. $front = $this->front; preg_match_all('/%.+?%/', $this->permalink_structure, $tokens); $tok_index = 1; foreach ( (array) $tokens[0] as $token) { if ( '%post_id%' == $token && ($tok_index <= 3) ) { $front = $front . 'date/'; break; } $tok_index++; } $this->date_structure = $front . $date_endian; return $this->date_structure; } |
クラス WP_Rewrite::get_year_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /** * Retrieve the year permalink structure without month and day. * * Gets the date permalink structure and strips out the month and day * permalink structures. * * @since 1.5.0 * @access public * * @return bool|string False on failure. Year structure on success. */ public function get_year_permastruct() { $structure = $this->get_date_permastruct(); if ( empty($structure) ) return false; $structure = str_replace('%monthnum%', '', $structure); $structure = str_replace('%day%', '', $structure); $structure = preg_replace('#/+#', '/', $structure); return $structure; } |
クラス WP_Rewrite::get_month_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * Retrieve the month permalink structure without day and with year. * * Gets the date permalink structure and strips out the day permalink * structures. Keeps the year permalink structure. * * @since 1.5.0 * @access public * * @return bool|string False on failure. Year/Month structure on success. */ public function get_month_permastruct() { $structure = $this->get_date_permastruct(); if ( empty($structure) ) return false; $structure = str_replace('%day%', '', $structure); $structure = preg_replace('#/+#', '/', $structure); return $structure; } |
クラス WP_Rewrite::get_day_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 | /** * Retrieve the day permalink structure with month and year. * * Keeps date permalink structure with all year, month, and day. * * @since 1.5.0 * @access public * * @return bool|string False on failure. Year/Month/Day structure on success. */ public function get_day_permastruct() { return $this->get_date_permastruct(); } |
クラス WP_Rewrite::get_category_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * Retrieve the permalink structure for categories. * * If the category_base property has no value, then the category structure * will have the front property value, followed by 'category', and finally * '%category%'. If it does, then the root property will be used, along with * the category_base property value. * * @since 1.5.0 * @access public * * @return bool|string False on failure. Category permalink structure. */ public function get_category_permastruct() { return $this->get_extra_permastruct('category'); } |
クラス WP_Rewrite::get_tag_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * Retrieve the permalink structure for tags. * * If the tag_base property has no value, then the tag structure will have * the front property value, followed by 'tag', and finally '%tag%'. If it * does, then the root property will be used, along with the tag_base * property value. * * @since 2.3.0 * @access public * * @return bool|string False on failure. Tag permalink structure. */ public function get_tag_permastruct() { return $this->get_extra_permastruct('post_tag'); } |
クラス WP_Rewrite::get_extra_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** * Retrieve extra permalink structure by name. * * @since 2.5.0 * @access public * * @param string $name Permalink structure name. * @return string|bool False if not found. Permalink structure string. */ public function get_extra_permastruct($name) { if ( empty($this->permalink_structure) ) return false; if ( isset($this->extra_permastructs[$name]) ) return $this->extra_permastructs[$name]['struct']; return false; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * Retrieve the author permalink structure. * * The permalink structure is front property, author base, and finally * '/%author%'. Will set the author_structure property and then return it * without attempting to set the value again. * * @since 1.5.0 * @access public * * @return string|bool False if not found. Permalink structure string. */ public function get_author_permastruct() { if ( isset($this->author_structure) ) return $this->author_structure; if ( empty($this->permalink_structure) ) { $this->author_structure = ''; return false; } $this->author_structure = $this->front . $this->author_base . '/%author%'; return $this->author_structure; } |
クラス WP_Rewrite::get_search_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * Retrieve the search permalink structure. * * The permalink structure is root property, search base, and finally * '/%search%'. Will set the search_structure property and then return it * without attempting to set the value again. * * @since 1.5.0 * @access public * * @return string|bool False if not found. Permalink structure string. */ public function get_search_permastruct() { if ( isset($this->search_structure) ) return $this->search_structure; if ( empty($this->permalink_structure) ) { $this->search_structure = ''; return false; } $this->search_structure = $this->root . $this->search_base . '/%search%'; return $this->search_structure; } |
クラス WP_Rewrite::get_page_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * Retrieve the page permalink structure. * * The permalink structure is root property, and '%pagename%'. Will set the * page_structure property and then return it without attempting to set the * value again. * * @since 1.5.0 * @access public * * @return string|bool False if not found. Permalink structure string. */ public function get_page_permastruct() { if ( isset($this->page_structure) ) return $this->page_structure; if (empty($this->permalink_structure)) { $this->page_structure = ''; return false; } $this->page_structure = $this->root . '%pagename%'; return $this->page_structure; } |
クラス WP_Rewrite::get_feed_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * Retrieve the feed permalink structure. * * The permalink structure is root property, feed base, and finally * '/%feed%'. Will set the feed_structure property and then return it * without attempting to set the value again. * * @since 1.5.0 * @access public * * @return string|bool False if not found. Permalink structure string. */ public function get_feed_permastruct() { if ( isset($this->feed_structure) ) return $this->feed_structure; if ( empty($this->permalink_structure) ) { $this->feed_structure = ''; return false; } $this->feed_structure = $this->root . $this->feed_base . '/%feed%'; return $this->feed_structure; } |
クラス WP_Rewrite::get_comment_feed_permastruct()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * Retrieve the comment feed permalink structure. * * The permalink structure is root property, comment base property, feed * base and finally '/%feed%'. Will set the comment_feed_structure property * and then return it without attempting to set the value again. * * @since 1.5.0 * @access public * * @return string|bool False if not found. Permalink structure string. */ public function get_comment_feed_permastruct() { if ( isset($this->comment_feed_structure) ) return $this->comment_feed_structure; if (empty($this->permalink_structure)) { $this->comment_feed_structure = ''; return false; } $this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%'; return $this->comment_feed_structure; } |
クラス WP_Rewrite::add_rewrite_tag()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** * Add or update existing rewrite tags (e.g. %postname%). * * If the tag already exists, replace the existing pattern and query for * that tag, otherwise add the new tag. * * @see WP_Rewrite::$rewritecode * @see WP_Rewrite::$rewritereplace * @see WP_Rewrite::$queryreplace * @since 1.5.0 * @access public * * @param string $tag Name of the rewrite tag to add or update. * @param string $regex Regular expression to substitute the tag for in rewrite rules. * @param string $query String to append to the rewritten query. Must end in '='. */ public function add_rewrite_tag( $tag, $regex, $query ) { $position = array_search( $tag, $this->rewritecode ); if ( false !== $position && null !== $position ) { $this->rewritereplace[ $position ] = $regex; $this->queryreplace[ $position ] = $query; } else { $this->rewritecode[] = $tag; $this->rewritereplace[] = $regex; $this->queryreplace[] = $query; } } |
クラス WP_Rewrite::generate_rewrite_rules()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | /** * Generate rewrite rules from a permalink structure. * * The main WP_Rewrite function for building the rewrite rule list. The * contents of the function is a mix of black magic and regular expressions, * so best just ignore the contents and move to the parameters. * * @since 1.5.0 * @access public * * @param string $permalink_structure The permalink structure. * @param int $ep_mask Endpoint mask defining what endpoints are added to the structure. Default is EP_NONE. * @param bool $paged Should archive pagination rules be added for the structure? Default is true. * @param bool $feed Should feed rewrite rules be added for the structure? Default is true. * @param bool $forcomments Should the feed rules be a query for a comments feed? Default is false. * @param bool $walk_dirs Should the 'directories' making up the structure be walked over and rewrite rules * built for each in turn? Default is true. * @param bool $endpoints Should endpoints be applied to the generated rewrite rules? Default is true. * @return array Rewrite rule list. */ public function generate_rewrite_rules($permalink_structure, $ep_mask = EP_NONE, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true) { //build a regex to match the feed section of URLs, something like (feed|atom|rss|rss2)/? $feedregex2 = ''; foreach ( (array) $this->feeds as $feed_name) $feedregex2 .= $feed_name . '|'; $feedregex2 = '(' . trim($feedregex2, '|') . ')/?$'; //$feedregex is identical but with /feed/ added on as well, so URLs like <permalink>/feed/atom //and <permalink>/atom are both possible $feedregex = $this->feed_base . '/' . $feedregex2; //build a regex to match the trackback and page/xx parts of URLs $trackbackregex = 'trackback/?$'; $pageregex = $this->pagination_base . '/?([0-9]{1,})/?$'; $commentregex = 'comment-page-([0-9]{1,})/?$'; //build up an array of endpoint regexes to append => queries to append if ( $endpoints ) { $ep_query_append = array (); foreach ( (array) $this->endpoints as $endpoint) { //match everything after the endpoint name, but allow for nothing to appear there $epmatch = $endpoint[1] . '(/(.*))?/?$'; //this will be appended on to the rest of the query for each dir $epquery = '&' . $endpoint[2] . '='; $ep_query_append[$epmatch] = array ( $endpoint[0], $epquery ); } } //get everything up to the first rewrite tag $front = substr($permalink_structure, 0, strpos($permalink_structure, '%')); //build an array of the tags (note that said array ends up being in $tokens[0]) preg_match_all('/%.+?%/', $permalink_structure, $tokens); $num_tokens = count($tokens[0]); $index = $this->index; //probably 'index.php' $feedindex = $index; $trackbackindex = $index; //build a list from the rewritecode and queryreplace arrays, that will look something like //tagname=$matches[i] where i is the current $i for ( $i = 0; $i < $num_tokens; ++$i ) { if ( 0 < $i ) $queries[$i] = $queries[$i - 1] . '&'; else $queries[$i] = ''; $query_token = str_replace($this->rewritecode, $this->queryreplace, $tokens[0][$i]) . $this->preg_index($i+1); $queries[$i] .= $query_token; } //get the structure, minus any cruft (stuff that isn't tags) at the front $structure = $permalink_structure; if ( $front != '/' ) $structure = str_replace($front, '', $structure); //create a list of dirs to walk over, making rewrite rules for each level //so for example, a $structure of /%year%/%monthnum%/%postname% would create //rewrite rules for /%year%/, /%year%/%monthnum%/ and /%year%/%monthnum%/%postname% $structure = trim($structure, '/'); $dirs = $walk_dirs ? explode('/', $structure) : array( $structure ); $num_dirs = count($dirs); //strip slashes from the front of $front $front = preg_replace('|^/+|', '', $front); //the main workhorse loop $post_rewrite = array(); $struct = $front; for ( $j = 0; $j < $num_dirs; ++$j ) { //get the struct for this dir, and trim slashes off the front $struct .= $dirs[$j] . '/'; //accumulate. see comment near explode('/', $structure) above $struct = ltrim($struct, '/'); //replace tags with regexes $match = str_replace($this->rewritecode, $this->rewritereplace, $struct); //make a list of tags, and store how many there are in $num_toks $num_toks = preg_match_all('/%.+?%/', $struct, $toks); //get the 'tagname=$matches[i]' $query = ( isset($queries) && is_array($queries) && !empty($num_toks) ) ? $queries[$num_toks - 1] : ''; //set up $ep_mask_specific which is used to match more specific URL types switch ( $dirs[$j] ) { case '%year%': $ep_mask_specific = EP_YEAR; break; case '%monthnum%': $ep_mask_specific = EP_MONTH; break; case '%day%': $ep_mask_specific = EP_DAY; break; default: $ep_mask_specific = EP_NONE; } //create query for /page/xx $pagematch = $match . $pageregex; $pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1); //create query for /comment-page-xx $commentmatch = $match . $commentregex; $commentquery = $index . '?' . $query . '&cpage=' . $this->preg_index($num_toks + 1); if ( get_option('page_on_front') ) { //create query for Root /comment-page-xx $rootcommentmatch = $match . $commentregex; $rootcommentquery = $index . '?' . $query . '&page_id=' . get_option('page_on_front') . '&cpage=' . $this->preg_index($num_toks + 1); } //create query for /feed/(feed|atom|rss|rss2|rdf) $feedmatch = $match . $feedregex; $feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); //create query for /(feed|atom|rss|rss2|rdf) (see comment near creation of $feedregex) $feedmatch2 = $match . $feedregex2; $feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1); //if asked to, turn the feed queries into comment feed ones if ( $forcomments ) { $feedquery .= '&withcomments=1'; $feedquery2 .= '&withcomments=1'; } //start creating the array of rewrites for this dir $rewrite = array(); if ( $feed ) //...adding on /feed/ regexes => queries $rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2); if ( $paged ) //...and /page/xx ones $rewrite = array_merge($rewrite, array($pagematch => $pagequery)); //only on pages with comments add ../comment-page-xx/ if ( EP_PAGES & $ep_mask || EP_PERMALINK & $ep_mask ) $rewrite = array_merge($rewrite, array($commentmatch => $commentquery)); else if ( EP_ROOT & $ep_mask && get_option('page_on_front') ) $rewrite = array_merge($rewrite, array($rootcommentmatch => $rootcommentquery)); //do endpoints if ( $endpoints ) { foreach ( (array) $ep_query_append as $regex => $ep) { //add the endpoints on if the mask fits if ( $ep[0] & $ep_mask || $ep[0] & $ep_mask_specific ) $rewrite[$match . $regex] = $index . '?' . $query . $ep[1] . $this->preg_index($num_toks + 2); } } //if we've got some tags in this dir if ( $num_toks ) { $post = false; $page = false; //check to see if this dir is permalink-level: i.e. the structure specifies an //individual post. Do this by checking it contains at least one of 1) post name, //2) post ID, 3) page name, 4) timestamp (year, month, day, hour, second and //minute all present). Set these flags now as we need them for the endpoints. if ( strpos($struct, '%postname%') !== false || strpos($struct, '%post_id%') !== false || strpos($struct, '%pagename%') !== false || (strpos($struct, '%year%') !== false && strpos($struct, '%monthnum%') !== false && strpos($struct, '%day%') !== false && strpos($struct, '%hour%') !== false && strpos($struct, '%minute%') !== false && strpos($struct, '%second%') !== false) ) { $post = true; if ( strpos($struct, '%pagename%') !== false ) $page = true; } if ( ! $post ) { // For custom post types, we need to add on endpoints as well. foreach ( get_post_types( array('_builtin' => false ) ) as $ptype ) { if ( strpos($struct, "%$ptype%") !== false ) { $post = true; $page = is_post_type_hierarchical( $ptype ); // This is for page style attachment url's break; } } } //if we're creating rules for a permalink, do all the endpoints like attachments etc if ( $post ) { //create query and regex for trackback $trackbackmatch = $match . $trackbackregex; $trackbackquery = $trackbackindex . '?' . $query . '&tb=1'; //trim slashes from the end of the regex for this dir $match = rtrim($match, '/'); //get rid of brackets $submatchbase = str_replace( array('(', ')'), '', $match); //add a rule for at attachments, which take the form of <permalink>/some-text $sub1 = $submatchbase . '/([^/]+)/'; $sub1tb = $sub1 . $trackbackregex; //add trackback regex <permalink>/trackback/... $sub1feed = $sub1 . $feedregex; //and <permalink>/feed/(atom|...) $sub1feed2 = $sub1 . $feedregex2; //and <permalink>/(feed|atom...) $sub1comment = $sub1 . $commentregex; //and <permalink>/comment-page-xx //add another rule to match attachments in the explicit form: //<permalink>/attachment/some-text $sub2 = $submatchbase . '/attachment/([^/]+)/'; $sub2tb = $sub2 . $trackbackregex; //and add trackbacks <permalink>/attachment/trackback $sub2feed = $sub2 . $feedregex; //feeds, <permalink>/attachment/feed/(atom|...) $sub2feed2 = $sub2 . $feedregex2; //and feeds again on to this <permalink>/attachment/(feed|atom...) $sub2comment = $sub2 . $commentregex; //and <permalink>/comment-page-xx //create queries for these extra tag-ons we've just dealt with $subquery = $index . '?attachment=' . $this->preg_index(1); $subtbquery = $subquery . '&tb=1'; $subfeedquery = $subquery . '&feed=' . $this->preg_index(2); $subcommentquery = $subquery . '&cpage=' . $this->preg_index(2); //do endpoints for attachments if ( !empty($endpoints) ) { foreach ( (array) $ep_query_append as $regex => $ep ) { if ( $ep[0] & EP_ATTACHMENT ) { $rewrite[$sub1 . $regex] = $subquery . $ep[1] . $this->preg_index(3); $rewrite[$sub2 . $regex] = $subquery . $ep[1] . $this->preg_index(3); } } } //now we've finished with endpoints, finish off the $sub1 and $sub2 matches //add a ? as we don't have to match that last slash, and finally a $ so we //match to the end of the URL $sub1 .= '?$'; $sub2 .= '?$'; //post pagination, e.g. <permalink>/2/ $match = $match . '(/[0-9]+)?/?$'; $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1); } else { //not matching a permalink so this is a lot simpler //close the match and finalise the query $match .= '?$'; $query = $index . '?' . $query; } //create the final array for this dir by joining the $rewrite array (which currently //only contains rules/queries for trackback, pages etc) to the main regex/query for //this dir $rewrite = array_merge($rewrite, array($match => $query)); //if we're matching a permalink, add those extras (attachments etc) on if ( $post ) { //add trackback $rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite); //add regexes/queries for attachments, attachment trackbacks and so on if ( ! $page ) //require <permalink>/attachment/stuff form for pages because of confusion with subpages $rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery, $sub1comment => $subcommentquery)); $rewrite = array_merge(array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery, $sub2comment => $subcommentquery), $rewrite); } } //if($num_toks) //add the rules for this dir to the accumulating $post_rewrite $post_rewrite = array_merge($rewrite, $post_rewrite); } //foreach ($dir) return $post_rewrite; //the finished rules. phew! } |