Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/wp-includes/class-wp-rewrite.php
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,7 @@ public function rewrite_rules() {
$page_rewrite = apply_filters( 'page_rewrite_rules', $page_rewrite );

// Extra permastructs.
$permastruct_rewrite = array();
foreach ( $this->extra_permastructs as $permastructname => $struct ) {
if ( is_array( $struct ) ) {
if ( count( $struct ) === 2 ) {
Expand Down Expand Up @@ -1447,14 +1448,14 @@ public function rewrite_rules() {
$rules = apply_filters_deprecated( 'tag_rewrite_rules', array( $rules ), '3.1.0', 'post_tag_rewrite_rules' );
}

$this->extra_rules_top = array_merge( $this->extra_rules_top, $rules );
$permastruct_rewrite = array_merge( $permastruct_rewrite, $rules );
}

// Put them together.
if ( $this->use_verbose_page_rules ) {
$this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $favicon_rewrite, $sitemap_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules );
$this->rules = array_merge( $this->extra_rules_top + $permastruct_rewrite, $robots_rewrite, $favicon_rewrite, $sitemap_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules );
} else {
$this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $favicon_rewrite, $sitemap_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules );
$this->rules = array_merge( $this->extra_rules_top + $permastruct_rewrite, $robots_rewrite, $favicon_rewrite, $sitemap_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules );
}

/**
Expand Down
76 changes: 76 additions & 0 deletions tests/phpunit/tests/rewrite.php
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,82 @@ public function test_parse_request_with_post_slug_that_clashes_with_a_trashed_pa
$this->assertFalse( is_404() );
}

/**
* @ticket 14991
*/
public function test_extra_rules_top_takes_priority_over_extra_permastructs() {
global $wp_rewrite;

// Register a custom permastruct with a known pattern.
add_permastruct(
'test_permastruct_14991',
'/test_permastruct_14991/%test_permastruct_14991%',
array(
'walk_dirs' => false,
'paged' => false,
'feed' => false,
)
);

$wp_rewrite->flush_rules();
$rewrite_rules = $wp_rewrite->rewrite_rules();

// Find a pattern generated by the permastruct.
$permastruct_pattern = null;
foreach ( array_keys( $rewrite_rules ) as $pattern ) {
if ( str_contains( $pattern, 'test_permastruct_14991' ) ) {
$permastruct_pattern = $pattern;
break;
}
}

$this->assertNotNull( $permastruct_pattern, 'Expected a rewrite rule to be generated for the permastruct.' );

// Add a top-priority rule with the same regex pattern.
$top_query = 'index.php?custom_override=1';
$wp_rewrite->add_rule( $permastruct_pattern, $top_query, 'top' );

$wp_rewrite->flush_rules();
$rewrite_rules = $wp_rewrite->rewrite_rules();

// The top rule's query should win over the permastruct's.
$this->assertSame(
$top_query,
$rewrite_rules[ $permastruct_pattern ],
'extra_rules_top should take priority over extra_permastructs when there is a regex conflict.'
);
}

/**
* @ticket 14991
*/
public function test_extra_rules_top_is_not_polluted_by_permastruct_rules() {
global $wp_rewrite;

// Register a custom permastruct.
add_permastruct(
'test_permastruct_14991_c',
'/test_permastruct_14991_c/%test_permastruct_14991_c%',
array(
'walk_dirs' => false,
'paged' => false,
'feed' => false,
)
);

$wp_rewrite->flush_rules();
$wp_rewrite->rewrite_rules();

// $extra_rules_top should only contain manually-added rules, not permastruct-generated ones.
foreach ( array_keys( $wp_rewrite->extra_rules_top ) as $pattern ) {
$this->assertStringNotContainsString(
'test_permastruct_14991_c',
$pattern,
'Permastruct-generated rules must not be stored in $extra_rules_top.'
);
}
}

/**
* @ticket 29107
*/
Expand Down
Loading