diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-includes/class-wp-rewrite.php --- a/wp/wp-includes/class-wp-rewrite.php Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-includes/class-wp-rewrite.php Fri Sep 05 18:40:08 2025 +0200 @@ -22,6 +22,7 @@ * * @since 1.5.0 */ +#[AllowDynamicProperties] class WP_Rewrite { /** * Permalink structure for posts. @@ -184,7 +185,7 @@ * Rewrite rules to match against the request to find the redirect or query. * * @since 1.5.0 - * @var array + * @var string[] */ public $rules; @@ -194,7 +195,7 @@ * Those not generated by the class, see add_rewrite_rule(). * * @since 2.1.0 - * @var array + * @var string[] */ public $extra_rules = array(); @@ -204,7 +205,7 @@ * Those not generated by the class, see add_rewrite_rule(). * * @since 2.3.0 - * @var array + * @var string[] */ public $extra_rules_top = array(); @@ -215,7 +216,7 @@ * and are added by add_external_rule(). * * @since 2.1.0 - * @var array + * @var string[] */ public $non_wp_rules = array(); @@ -223,7 +224,7 @@ * Extra permalink structures, e.g. categories, added by add_permastruct(). * * @since 2.1.0 - * @var array + * @var array[] */ public $extra_permastructs = array(); @@ -231,7 +232,7 @@ * Endpoints (like /trackback/) added by add_rewrite_endpoint(). * * @since 2.1.0 - * @var array + * @var array[] */ public $endpoints; @@ -412,7 +413,7 @@ } /** - * Retrieves all page and attachments for pages URIs. + * Retrieves all pages and attachments for pages URIs. * * The attachments are for those that have pages as parents and will be * retrieved. @@ -508,7 +509,7 @@ $date_endian = ''; foreach ( $endians as $endian ) { - if ( false !== strpos( $this->permalink_structure, $endian ) ) { + if ( str_contains( $this->permalink_structure, $endian ) ) { $date_endian = $endian; break; } @@ -530,7 +531,7 @@ $front = $front . 'date/'; break; } - $tok_index++; + ++$tok_index; } $this->date_structure = $front . $date_endian; @@ -615,7 +616,7 @@ } /** - * Retrieve the permalink structure for tags. + * Retrieves 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 @@ -860,7 +861,7 @@ * Default `EP_NONE`. * @param bool $paged Optional. Whether archive pagination rules should be added for the structure. * Default true. - * @param bool $feed Optional Whether feed rewrite rules should be added for the structure. + * @param bool $feed Optional. Whether feed rewrite rules should be added for the structure. * Default true. * @param bool $forcomments Optional. Whether the feed rules should be a query for a comments feed. * Default false. @@ -1059,13 +1060,18 @@ * 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 ) - ) { + if ( str_contains( $struct, '%postname%' ) + || str_contains( $struct, '%post_id%' ) + || str_contains( $struct, '%pagename%' ) + || ( str_contains( $struct, '%year%' ) + && str_contains( $struct, '%monthnum%' ) + && str_contains( $struct, '%day%' ) + && str_contains( $struct, '%hour%' ) + && str_contains( $struct, '%minute%' ) + && str_contains( $struct, '%second%' ) ) + ) { $post = true; - if ( strpos( $struct, '%pagename%' ) !== false ) { + if ( str_contains( $struct, '%pagename%' ) ) { $page = true; } } @@ -1073,7 +1079,7 @@ 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 ) { + if ( str_contains( $struct, "%$ptype%" ) ) { $post = true; // This is for page style attachment URLs. @@ -1244,7 +1250,7 @@ * @param string $permalink_structure The permalink structure to generate rules. * @param bool $walk_dirs Optional. Whether to create list of directories to walk over. * Default false. - * @return array + * @return array An array of rewrite rules keyed by their regex pattern. */ public function generate_rewrite_rule( $permalink_structure, $walk_dirs = false ) { return $this->generate_rewrite_rules( $permalink_structure, EP_NONE, false, false, false, $walk_dirs ); @@ -1398,7 +1404,7 @@ // Extra permastructs. foreach ( $this->extra_permastructs as $permastructname => $struct ) { if ( is_array( $struct ) ) { - if ( count( $struct ) == 2 ) { + if ( count( $struct ) === 2 ) { $rules = $this->generate_rewrite_rules( $struct[0], $struct[1] ); } else { $rules = $this->generate_rewrite_rules( $struct['struct'], $struct['ep_mask'], $struct['paged'], $struct['feed'], $struct['forcomments'], $struct['walk_dirs'], $struct['endpoints'] ); @@ -1484,19 +1490,36 @@ public function wp_rewrite_rules() { $this->rules = get_option( 'rewrite_rules' ); if ( empty( $this->rules ) ) { - $this->matches = 'matches'; - $this->rewrite_rules(); - if ( ! did_action( 'wp_loaded' ) ) { - add_action( 'wp_loaded', array( $this, 'flush_rules' ) ); - return $this->rules; - } - update_option( 'rewrite_rules', $this->rules ); + $this->refresh_rewrite_rules(); } return $this->rules; } /** + * Refreshes the rewrite rules, saving the fresh value to the database. + * If the `wp_loaded` action has not occurred yet, will postpone saving to the database. + * + * @since 6.4.0 + */ + private function refresh_rewrite_rules() { + $this->rules = ''; + $this->matches = 'matches'; + + $this->rewrite_rules(); + + if ( ! did_action( 'wp_loaded' ) ) { + /* + * Is not safe to save the results right now, as the rules may be partial. + * Need to give all rules the chance to register. + */ + add_action( 'wp_loaded', array( $this, 'flush_rules' ) ); + } else { + update_option( 'rewrite_rules', $this->rules ); + } + } + + /** * Retrieves mod_rewrite-formatted rewrite rules to write to .htaccess. * * Does not actually write to the .htaccess file, but creates the rules for @@ -1554,7 +1577,7 @@ // Apache 1.3 does not support the reluctant (non-greedy) modifier. $match = str_replace( '.+?', '.+', $match ); - if ( strpos( $query, $this->index ) !== false ) { + if ( str_contains( $query, $this->index ) ) { $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n"; } else { $rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n"; @@ -1659,10 +1682,10 @@ $external = false; $query = add_query_arg( $query, 'index.php' ); } else { - $index = false === strpos( $query, '?' ) ? strlen( $query ) : strpos( $query, '?' ); + $index = ! str_contains( $query, '?' ) ? strlen( $query ) : strpos( $query, '?' ); $front = substr( $query, 0, $index ); - $external = $front != $this->index; + $external = $front !== $this->index; } // "external" = it doesn't correspond to index.php. @@ -1793,7 +1816,8 @@ if ( ! is_array( $args ) ) { $args = array( 'with_front' => $args ); } - if ( func_num_args() == 4 ) { + + if ( func_num_args() === 4 ) { $args['ep_mask'] = func_get_arg( 3 ); } @@ -1806,14 +1830,16 @@ 'walk_dirs' => true, 'endpoints' => true, ); - $args = array_intersect_key( $args, $defaults ); - $args = wp_parse_args( $args, $defaults ); + + $args = array_intersect_key( $args, $defaults ); + $args = wp_parse_args( $args, $defaults ); if ( $args['with_front'] ) { $struct = $this->front . $struct; } else { $struct = $this->root . $struct; } + $args['struct'] = $struct; $this->extra_permastructs[ $name ] = $args; @@ -1855,8 +1881,7 @@ unset( $do_hard_later ); } - update_option( 'rewrite_rules', '' ); - $this->wp_rewrite_rules(); + $this->refresh_rewrite_rules(); /** * Filters whether a "hard" rewrite rule flush should be performed when requested. @@ -1906,7 +1931,7 @@ unset( $this->feed_structure ); unset( $this->comment_feed_structure ); - $this->use_trailing_slashes = ( '/' === substr( $this->permalink_structure, -1, 1 ) ); + $this->use_trailing_slashes = str_ends_with( $this->permalink_structure, '/' ); // Enable generic rules for pages if permalink structure doesn't begin with a wildcard. if ( preg_match( '/^[^%]*%(?:postname|category|tag|author)%/', $this->permalink_structure ) ) { @@ -1931,7 +1956,7 @@ * @param string $permalink_structure Permalink structure. */ public function set_permalink_structure( $permalink_structure ) { - if ( $permalink_structure != $this->permalink_structure ) { + if ( $this->permalink_structure !== $permalink_structure ) { $old_permalink_structure = $this->permalink_structure; update_option( 'permalink_structure', $permalink_structure );