Changeset 65441
- Timestamp:
- 11/12/2026 10:23:49 PM (less than one hour ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
src/wp-includes/class-wp-rewrite.php (modified) (3 diffs)
-
tests/phpunit/tests/query/randomContentRedirect.php (modified) (4 diffs)
-
tests/phpunit/tests/rewrite/randomRewriteRules.php (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-rewrite.php
r64690 r65441 1424 1424 $page_rewrite = apply_filters( 'page_rewrite_rules', $page_rewrite ); 1425 1425 1426 // Random content rewrite rules.1427 $random_rewrite = $this->random_rewrite_rules();1428 1429 /**1430 * Filters rewrite rules used for random content redirects.1431 *1432 * Likely random content rules would include `/random/`, as well as1433 * term, author and post type archives prefixed with the random base,1434 * for example `/random/category/news/`.1435 *1436 * @since 7.2.01437 *1438 * @param array<string, string> $random_rewrite Array of rewrite rules for random content redirects, keyed by their regex pattern.1439 */1440 $random_rewrite = apply_filters( 'random_rewrite_rules', $random_rewrite );1441 1442 1426 // Extra permastructs. 1443 1427 foreach ( $this->extra_permastructs as $permastructname => $struct ) { … … 1486 1470 } 1487 1471 1488 // Put them together. 1472 // Random content rewrite rules. 1473 $random_rewrite = $this->random_rewrite_rules(); 1474 1475 /* 1476 * Rules added to the top, including those for post types and taxonomies, take 1477 * precedence over random content rules using the same regex, for example a post 1478 * type archive at `/random/`. 1479 * 1480 * Rules added to the top are merged ahead of the random content rules, so without 1481 * this, the random content rule's query would replace the query of a rule using the 1482 * same regex. Rules added to the top using a different regex for the same path, 1483 * such as `^random/?$`, already take precedence as they are matched first. 1484 */ 1485 $random_rewrite = array_diff_key( $random_rewrite, $this->extra_rules_top ); 1486 1487 /** 1488 * Filters rewrite rules used for random content redirects. 1489 * 1490 * Likely random content rules would include `/random/`, as well as 1491 * term, author and post type archives prefixed with the random base, 1492 * for example `/random/category/news/`. 1493 * 1494 * @since 7.2.0 1495 * 1496 * @param array<string, string> $random_rewrite Array of rewrite rules for random content redirects, keyed by their regex pattern. 1497 */ 1498 $random_rewrite = apply_filters( 'random_rewrite_rules', $random_rewrite ); 1499 1500 /* 1501 * Put them together, with the random content rules ahead of the generic rules 1502 * such as the page and post rules which would otherwise match them first. 1503 */ 1489 1504 if ( $this->use_verbose_page_rules ) { 1490 1505 $this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $favicon_rewrite, $sitemap_rewrite, $deprecated_files, $registration_pages, $random_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules ); … … 1532 1547 * the URL, see {@see WP_Rewrite::post_permalinks_share_random_base()}. The rules are flushed 1533 1548 * when such a page or post changes, see {@see wp_random_content_flush_rewrite_rules_for_post()}. 1549 * 1550 * Rules added to the top of the rewrite rules, including those for post types and taxonomies, 1551 * take precedence over the random content rules. When the rewrite rules are generated, random 1552 * content rules using the same regex as a rule added to the top are omitted, see 1553 * {@see WP_Rewrite::rewrite_rules()}. For example, a post type archive at `/random/` replaces 1554 * the `/random/` rule. 1555 * 1556 * If a post type or taxonomy uses the random base as its rewrite slug, its rules may match 1557 * random archive URLs before the random content rules do. For example, the attachment rules 1558 * of a post type with the rewrite slug `random` match `/random/category/news/`, and the rules 1559 * of a hierarchical post type or taxonomy match every URL beginning with `/random/`. Such 1560 * random archive URLs display the post type or taxonomy content instead. To use random 1561 * archives on these sites, change the random base on the Permalinks screen. 1534 1562 * 1535 1563 * The `random` query variable can be added to any other archive or search URL, for example -
trunk/tests/phpunit/tests/query/randomContentRedirect.php
r65440 r65441 105 105 106 106 /** 107 * Rewrite rules added to the top of the rules before each test. 108 * 109 * WP_Rewrite::init() does not reset these, so they are restored after each test. 110 * 111 * @var string[] 112 */ 113 protected $original_extra_rules_top = array(); 114 115 /** 116 * Extra permalink structures registered before each test. 117 * 118 * Unregistering post types between tests does not remove their permalink structures, 119 * so they are restored after each test. 120 * 121 * @var array<array<mixed>> 122 */ 123 protected $original_extra_permastructs = array(); 124 125 /** 107 126 * Creates shared user, category and post fixtures. 108 127 * … … 146 165 /** 147 166 * Sets up pretty permalinks and redirect capturing before each test. 167 * 168 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 148 169 */ 149 170 public function set_up(): void { 171 global $wp_rewrite; 172 150 173 parent::set_up(); 174 175 $this->original_extra_rules_top = $wp_rewrite->extra_rules_top; 176 $this->original_extra_permastructs = $wp_rewrite->extra_permastructs; 151 177 152 178 $this->set_permalink_structure( '/%postname%/' ); … … 166 192 /** 167 193 * Unregisters the test post types and taxonomy after each test. 194 * 195 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 168 196 */ 169 197 public function tear_down(): void { 198 global $wp_rewrite; 199 200 $wp_rewrite->extra_rules_top = $this->original_extra_rules_top; 201 $wp_rewrite->extra_permastructs = $this->original_extra_permastructs; 202 170 203 unregister_post_type( 'wptests_book' ); 171 204 unregister_post_type( 'wptests_hidden' ); … … 2698 2731 $this->assertRedirectedToOneOf( array( self::$arts_post, self::$sport_post ), 'Random content redirects should resume when the post named random is unpublished.' ); 2699 2732 } 2733 2734 /** 2735 * Ensure a post type archive at the random base is not redirected to random content. 2736 * 2737 * @dataProvider data_post_types_at_the_random_base 2738 * 2739 * @param string $post_type Post type name. 2740 * @param array<string, mixed> $args Post type registration arguments. 2741 * 2742 * @phpstan-param lowercase-string&non-falsy-string $post_type 2743 * @phpstan-param array{public: bool, has_archive: bool|string, rewrite?: array{slug: string}} $args 2744 */ 2745 public function test_post_type_archive_at_the_random_base_is_not_redirected( string $post_type, array $args ): void { 2746 register_post_type( $post_type, $args ); 2747 flush_rewrite_rules(); 2748 2749 $this->create_post( array( 'post_type' => $post_type ) ); 2750 2751 $this->go_to( home_url( '/random/' ) ); 2752 2753 $this->assertNotRedirected( 'The post type archive at the random base should not redirect to random content.' ); 2754 $this->assertQueryTrue( 'is_archive', 'is_post_type_archive' ); 2755 $this->assertSame( $post_type, get_query_var( 'post_type' ), 'The post type archive at the random base should be queried.' ); 2756 } 2757 2758 /** 2759 * Ensure a single post of a post type at the random base is not redirected to random content. 2760 * 2761 * Registering a post type named `random` also registers `random` as its query variable, 2762 * which is the query variable used by random content requests. 2763 * 2764 * @dataProvider data_post_types_at_the_random_base 2765 * 2766 * @param string $post_type Post type name. 2767 * @param array<string, mixed> $args Post type registration arguments. 2768 * 2769 * @phpstan-param lowercase-string&non-falsy-string $post_type 2770 * @phpstan-param array{public: bool, has_archive: bool|string, rewrite?: array{slug: string}} $args 2771 */ 2772 public function test_single_post_of_a_post_type_at_the_random_base_is_not_redirected( string $post_type, array $args ): void { 2773 register_post_type( $post_type, $args ); 2774 flush_rewrite_rules(); 2775 2776 $post_id = self::factory()->post->create( array( 'post_type' => $post_type ) ); 2777 self::factory()->post->create(); 2778 2779 $permalink = get_permalink( $post_id ); 2780 $this->assertIsString( $permalink, 'The post permalink could not be retrieved.' ); 2781 $this->assertStringStartsWith( home_url( '/' . ( $args['rewrite']['slug'] ?? $post_type ) . '/' ), $permalink, 'The post permalink should use the post type rewrite slug.' ); 2782 2783 $redirect = new MockAction(); 2784 add_filter( 'wp_redirect', array( $redirect, 'filter' ), 5 ); 2785 2786 $this->go_to( $permalink ); 2787 2788 $this->assertSame( 0, $redirect->get_call_count(), 'The single post should not redirect to random content.' ); 2789 $this->assertQueryTrue( 'is_single', 'is_singular' ); 2790 $this->assertSame( $post_id, get_queried_object_id(), 'The single post should be queried.' ); 2791 } 2792 2793 /** 2794 * Data provider for post types registered with an archive or single posts at the random base. 2795 * 2796 * @return array<string, array{0: string, 1: array<string, mixed>}> 2797 */ 2798 public static function data_post_types_at_the_random_base(): array { 2799 return array( 2800 'post type named random' => array( 2801 'random', 2802 array( 2803 'public' => true, 2804 'has_archive' => true, 2805 ), 2806 ), 2807 'archive slug random' => array( 2808 'wptests_random', 2809 array( 2810 'public' => true, 2811 'has_archive' => 'random', 2812 ), 2813 ), 2814 'archive and rewrite slug random' => array( 2815 'wptests_random', 2816 array( 2817 'public' => true, 2818 'has_archive' => 'random', 2819 'rewrite' => array( 'slug' => 'random' ), 2820 ), 2821 ), 2822 'rewrite slug random' => array( 2823 'wptests_random', 2824 array( 2825 'public' => true, 2826 'has_archive' => true, 2827 'rewrite' => array( 'slug' => 'random' ), 2828 ), 2829 ), 2830 ); 2831 } 2832 2833 /** 2834 * Ensure random archives redirect when a post type archive is at the random base. 2835 */ 2836 public function test_random_archives_redirect_when_a_post_type_archive_is_at_the_random_base(): void { 2837 register_post_type( 2838 'wptests_random', 2839 array( 2840 'public' => true, 2841 'has_archive' => 'random', 2842 ) 2843 ); 2844 flush_rewrite_rules(); 2845 2846 $this->go_to( home_url( '/random/category/arts/' ) ); 2847 2848 $this->assertSame( get_permalink( self::$arts_post ), $this->redirect_location, 'Random archives should redirect when a post type archive is at the random base.' ); 2849 } 2850 2851 /** 2852 * Ensure the random base is not redirected to random content when an existing rule takes it. 2853 * 2854 * The dataProvider supplies a top-priority rewrite rule, each one a different regex spelling that 2855 * matches the path `/random` and points to a specific `page`. This ensures that rewrite rule 2856 * takes priority over the random ones. 2857 * 2858 * @dataProvider data_random_base_is_not_redirected_when_an_existing_rule_takes_it 2859 * 2860 * @param string $regex Rewrite rule regex. 2861 */ 2862 public function test_random_base_is_not_redirected_when_an_existing_rule_takes_it( string $regex ): void { 2863 $page = $this->create_post( 2864 array( 2865 'post_type' => 'page', 2866 'post_name' => 'wptests-taken', 2867 ) 2868 ); 2869 2870 add_rewrite_rule( $regex, 'index.php?pagename=wptests-taken', 'top' ); 2871 flush_rewrite_rules(); 2872 2873 $this->go_to( home_url( '/random/' ) ); 2874 2875 $this->assertNotRedirected( "The random base should not redirect to random content when the rule {$regex} takes it." ); 2876 $this->assertSame( $page, get_queried_object_id(), "The page served by the rule {$regex} should be queried." ); 2877 } 2878 2879 /** 2880 * Data provider. 2881 * 2882 * @return array<string, string[]> 2883 */ 2884 public static function data_random_base_is_not_redirected_when_an_existing_rule_takes_it(): array { 2885 return array( 2886 'exact match' => array( 'random/?$' ), 2887 'anchored exact match' => array( '^random/?$' ), 2888 'alternation' => array( '(random|pens|pencils)/?$' ), 2889 'partial group' => array( '(rand)om/?$' ), 2890 'character class' => array( '[r]andom/?$' ), 2891 'optional suffix' => array( 'random(?:-ful)?/?$' ), 2892 ); 2893 } 2894 2895 /** 2896 * Ensure random archives redirect when an existing rule takes the random base. 2897 */ 2898 public function test_random_archives_redirect_when_an_existing_rule_takes_the_random_base(): void { 2899 add_rewrite_rule( '^random/?$', 'index.php?pagename=wptests-taken', 'top' ); 2900 flush_rewrite_rules(); 2901 2902 $this->go_to( home_url( '/random/category/arts/' ) ); 2903 2904 $this->assertSame( get_permalink( self::$arts_post ), $this->redirect_location, 'Random archives should redirect when an existing rule takes the random base.' ); 2905 } 2906 2907 /** 2908 * Ensure the random base redirects to random content when existing rules do not take it. 2909 * 2910 * @dataProvider data_random_base_redirects_when_existing_rules_do_not_take_it 2911 * 2912 * @param string $regex Rewrite rule regex. 2913 * @param string $position Position of the rewrite rule, either 'top' or 'bottom'. 2914 */ 2915 public function test_random_base_redirects_when_existing_rules_do_not_take_it( string $regex, string $position ): void { 2916 add_rewrite_rule( $regex, 'index.php?pagename=wptests-not-taken', $position ); 2917 flush_rewrite_rules(); 2918 2919 $this->go_to( home_url( '/random/' ) ); 2920 2921 $this->assertRedirectedToOneOf( array( self::$arts_post, self::$sport_post ), "The random base should redirect to random content when the rule {$regex} does not take it." ); 2922 } 2923 2924 /** 2925 * Data provider. 2926 * 2927 * @return array<string, string[]> 2928 */ 2929 public static function data_random_base_redirects_when_existing_rules_do_not_take_it(): array { 2930 return array( 2931 'suffixed slug' => array( 'randomful/?$', 'top' ), 2932 'hyphenated suffixed slug' => array( '^random-ful/?$', 'top' ), 2933 'similar alternation' => array( '(randomful|random-ful)/?$', 'top' ), 2934 'sub path' => array( '^random/wptests/?$', 'top' ), 2935 'requires a sub path' => array( '^random/(.*)?', 'top' ), 2936 'catch-all' => array( '(.+?)/?$', 'bottom' ), 2937 'single segment catch-all' => array( '([^/]+)/?$', 'bottom' ), 2938 'bottom anchored match' => array( '^random/?$', 'bottom' ), 2939 'bottom alternation' => array( '(random|pens|pencils)/?$', 'bottom' ), 2940 'bottom unterminated' => array( 'random', 'bottom' ), 2941 ); 2942 } 2943 2944 /** 2945 * Ensure a bottom rule using the random root rule's regex takes the random base. 2946 * 2947 * Rules added to the bottom are preceded by the generic page and post rules, so are 2948 * never matched for the random base. A bottom rule using the same regex as the random 2949 * root rule replaces the root rule's query while keeping its position ahead of the 2950 * page and post rules, so takes the random base. 2951 */ 2952 public function test_bottom_rule_using_the_random_root_rule_regex_takes_the_random_base(): void { 2953 $page = $this->create_post( 2954 array( 2955 'post_type' => 'page', 2956 'post_name' => 'wptests-taken', 2957 ) 2958 ); 2959 2960 add_rewrite_rule( 'random/?$', 'index.php?pagename=wptests-taken', 'bottom' ); 2961 flush_rewrite_rules(); 2962 2963 $this->go_to( home_url( '/random/' ) ); 2964 2965 $this->assertNotRedirected( 'A bottom rule using the root rule regex should not redirect to random content.' ); 2966 $this->assertQueryTrue( 'is_page', 'is_singular' ); 2967 $this->assertSame( $page, get_queried_object_id(), 'The page served by the bottom rule using the root rule regex should be queried.' ); 2968 } 2969 2970 /** 2971 * Ensure a category at the random base with the category base removed is not redirected to random content. 2972 * 2973 * This replicates plugins that remove the category base from category archive URLs. 2974 */ 2975 public function test_category_at_the_random_base_without_a_category_base_is_not_redirected(): void { 2976 $category = self::factory()->category->create( array( 'slug' => 'random' ) ); 2977 2978 add_rewrite_rule( '(random)/?$', 'index.php?category_name=$matches[1]', 'top' ); 2979 flush_rewrite_rules(); 2980 2981 $this->go_to( home_url( '/random/' ) ); 2982 2983 $this->assertNotRedirected( 'A category at the random base should not redirect to random content.' ); 2984 $this->assertQueryTrue( 'is_archive', 'is_category' ); 2985 $this->assertSame( $category, get_queried_object_id(), 'The category at the random base should be queried.' ); 2986 } 2700 2987 } -
trunk/tests/phpunit/tests/rewrite/randomRewriteRules.php
r65440 r65441 20 20 21 21 /** 22 * Rewrite rules added to the top of the rules before each test. 23 * 24 * WP_Rewrite::init() does not reset these, so they are restored after each test. 25 * 26 * @var string[] 27 */ 28 private $original_extra_rules_top = array(); 29 30 /** 31 * Extra permalink structures registered before each test. 32 * 33 * Unregistering post types between tests does not remove their permalink structures, 34 * so they are restored after each test. 35 * 36 * @var array<array<mixed>> 37 */ 38 private $original_extra_permastructs = array(); 39 40 /** 22 41 * Requests a URL, stopping where a random content redirect ends the request. 23 42 * … … 34 53 } 35 54 55 /** 56 * Sets up pretty permalinks before each test. 57 * 58 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 59 */ 36 60 public function set_up(): void { 61 global $wp_rewrite; 62 37 63 parent::set_up(); 64 65 $this->original_extra_rules_top = $wp_rewrite->extra_rules_top; 66 $this->original_extra_permastructs = $wp_rewrite->extra_permastructs; 38 67 39 68 // End the request before random content redirects exit, only the rewrite rules are under test. … … 50 79 } 51 80 81 /** 82 * Restores the rewrite rules and random base after each test. 83 * 84 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 85 */ 52 86 public function tear_down(): void { 87 global $wp_rewrite; 88 89 $wp_rewrite->extra_rules_top = $this->original_extra_rules_top; 90 $wp_rewrite->extra_permastructs = $this->original_extra_permastructs; 91 53 92 /* 54 93 * The parent class re-initializes the rewrite base from this option before the … … 667 706 * such as the greedy page and post rules. 668 707 * 669 * @dataProvider data_ permalink_structures708 * @dataProvider data_random_rewrite_rules_precede_other_matching_rules 670 709 * 671 710 * @param string $structure Permalink structure. … … 705 744 * @return array<string, string[]> 706 745 */ 707 public static function data_ permalink_structures(): array {746 public static function data_random_rewrite_rules_precede_other_matching_rules(): array { 708 747 return array( 709 748 'post name' => array( '/%postname%/' ), … … 720 759 * @param string $path Request path. 721 760 * @param array<string, string> $expected_query Expected query variables. 722 */ 723 public function test_random_urls_resolve_to_random_query_vars( $path, $expected_query ): void { 761 * @param string $structure Optional. Permalink structure. Default empty, the 762 * structure set up for each test. 763 */ 764 public function test_random_urls_resolve_to_random_query_vars( $path, $expected_query, string $structure = '' ): void { 724 765 global $wp; 766 767 if ( '' !== $structure ) { 768 $this->set_permalink_structure( $structure ); 769 create_initial_taxonomies(); 770 } 725 771 726 772 register_taxonomy( 'wptests_genre', 'post', array( 'rewrite' => array( 'slug' => 'genre' ) ) ); … … 745 791 * Data provider. 746 792 * 747 * @return array<string, array{0: string, 1: array<string, string> }>793 * @return array<string, array{0: string, 1: array<string, string>, 2?: string}> 748 794 */ 749 795 public static function data_random_urls(): array { 750 796 return array( 751 'random' => array( '/random/', array( 'random' => '1' ) ), 752 'random without slash' => array( '/random', array( 'random' => '1' ) ), 753 'random category' => array( 797 'random' => array( '/random/', array( 'random' => '1' ) ), 798 'random without slash' => array( '/random', array( 'random' => '1' ) ), 799 'random, verbose page rules' => array( '/random/', array( 'random' => '1' ), '/%category%/%postname%/' ), 800 'random, date and name' => array( '/random/', array( 'random' => '1' ), '/%year%/%monthnum%/%postname%/' ), 801 'random category' => array( 754 802 '/random/category/news/', 755 803 array( … … 758 806 ), 759 807 ), 760 'random child category' => array(808 'random child category' => array( 761 809 '/random/category/news/local/', 762 810 array( … … 765 813 ), 766 814 ), 767 'random tag' => array(815 'random tag' => array( 768 816 '/random/tag/featured/', 769 817 array( … … 772 820 ), 773 821 ), 774 'random author' => array(822 'random author' => array( 775 823 '/random/author/admin/', 776 824 array( … … 779 827 ), 780 828 ), 781 'random custom taxonomy' => array(829 'random custom taxonomy' => array( 782 830 '/random/genre/sci-fi/', 783 831 array( … … 786 834 ), 787 835 ), 788 'random post type archive' => array(836 'random post type archive' => array( 789 837 '/random/books/', 790 838 array( … … 793 841 ), 794 842 ), 795 'query string random' => array( '/?random', array( 'random' => '' ) ),796 'query string random value' => array( '/?random=1', array( 'random' => '1' ) ),843 'query string random' => array( '/?random', array( 'random' => '' ) ), 844 'query string random value' => array( '/?random=1', array( 'random' => '1' ) ), 797 845 ); 798 846 } … … 1055 1103 ); 1056 1104 } 1105 1106 /** 1107 * Ensure random rules using the same regex as a rule added to the top are omitted. 1108 * 1109 * Rules added to the top are merged ahead of the random rules, so a random rule using 1110 * the same regex would otherwise replace the top rule's query. 1111 * 1112 * @dataProvider data_random_rules_using_the_regex_of_a_top_rule_are_omitted 1113 * 1114 * @param string $regex Rewrite rule regex. 1115 * @param string $random_rule A random rule using a different regex, expected to be kept. 1116 */ 1117 public function test_random_rules_using_the_regex_of_a_top_rule_are_omitted( string $regex, string $random_rule ): void { 1118 add_rewrite_rule( $regex, 'index.php?pagename=wptests-taken', 'top' ); 1119 1120 $this->get_random_rewrite_rules(); 1121 $rules = $this->get_stored_rewrite_rules(); 1122 1123 $this->assertSame( 'index.php?pagename=wptests-taken', $rules[ $regex ] ?? null, "The top rule {$regex} should take precedence over the random rule using the same regex." ); 1124 $random_query = $rules[ $random_rule ] ?? ''; 1125 $this->assertIsString( $random_query, "The random rule {$random_rule} should be kept when the top rule {$regex} uses a different regex." ); 1126 $this->assertStringContainsString( 'random=1', $random_query, "The random rule {$random_rule} should be kept when the top rule {$regex} uses a different regex." ); 1127 } 1128 1129 /** 1130 * Data provider. 1131 * 1132 * @return array<string, string[]> 1133 */ 1134 public static function data_random_rules_using_the_regex_of_a_top_rule_are_omitted(): array { 1135 return array( 1136 'root rule' => array( 'random/?$', 'random/category/(.+?)/?$' ), 1137 'category archive rule' => array( 'random/category/(.+?)/?$', 'random/?$' ), 1138 ); 1139 } 1140 1141 /** 1142 * Ensure random rules are kept when a rule added to the top uses a different regex for the random base. 1143 * 1144 * Such rules are matched before the random rules, so take precedence without the random rules being omitted. 1145 * 1146 * @global WP $wp Current WordPress environment instance. 1147 */ 1148 public function test_random_root_rule_is_kept_when_a_top_rule_uses_a_different_regex_for_the_random_base(): void { 1149 global $wp; 1150 1151 $page = self::factory()->post->create( 1152 array( 1153 'post_type' => 'page', 1154 'post_name' => 'wptests-taken', 1155 ) 1156 ); 1157 1158 add_rewrite_rule( '^random/?$', 'index.php?pagename=wptests-taken', 'top' ); 1159 1160 $this->get_random_rewrite_rules(); 1161 1162 $this->assertSame( 'index.php?random=1', $this->get_stored_rewrite_rules()['random/?$'] ?? null, 'The root rule should be kept when a top rule uses a different regex.' ); 1163 1164 $this->go_to( home_url( '/random/' ) ); 1165 1166 $this->assertSame( '^random/?$', $wp->matched_rule, 'The top rule should be matched before the root rule.' ); 1167 $this->assertSame( $page, get_queried_object_id(), 'The page served by the top rule should be queried.' ); 1168 } 1169 1170 /** 1171 * Ensure a post type archive at the random base takes precedence over the root rule. 1172 * 1173 * @dataProvider data_random_root_rule_is_omitted_for_a_post_type_archive_at_the_random_base 1174 * 1175 * @param string $post_type Post type name. 1176 * @param array<string, mixed> $args Post type registration arguments. 1177 * 1178 * @phpstan-param lowercase-string&non-falsy-string $post_type 1179 * @phpstan-param array{public: bool, has_archive: bool|string, rewrite?: array{slug: string}} $args 1180 */ 1181 public function test_random_root_rule_is_omitted_for_a_post_type_archive_at_the_random_base( string $post_type, array $args ): void { 1182 register_post_type( $post_type, $args ); 1183 1184 $this->get_random_rewrite_rules(); 1185 1186 $this->assertSame( "index.php?post_type={$post_type}", $this->get_stored_rewrite_rules()['random/?$'] ?? null, 'The post type archive should be reachable at the random base.' ); 1187 } 1188 1189 /** 1190 * Data provider. 1191 * 1192 * @return array<string, array{0: string, 1: array<string, mixed>}> 1193 */ 1194 public static function data_random_root_rule_is_omitted_for_a_post_type_archive_at_the_random_base(): array { 1195 return array( 1196 'post type named random' => array( 1197 'random', 1198 array( 1199 'public' => true, 1200 'has_archive' => true, 1201 ), 1202 ), 1203 'archive slug random' => array( 1204 'wptests_random', 1205 array( 1206 'public' => true, 1207 'has_archive' => 'random', 1208 ), 1209 ), 1210 'rewrite slug random' => array( 1211 'wptests_random', 1212 array( 1213 'public' => true, 1214 'has_archive' => true, 1215 'rewrite' => array( 'slug' => 'random' ), 1216 ), 1217 ), 1218 ); 1219 } 1220 1221 /** 1222 * Ensure a post type archive with a slug similar to the random base does not take it. 1223 * 1224 * @dataProvider data_random_root_rule_is_kept_for_a_post_type_archive_with_a_similar_slug 1225 * 1226 * @param string $slug Post type archive slug. 1227 */ 1228 public function test_random_root_rule_is_kept_for_a_post_type_archive_with_a_similar_slug( string $slug ): void { 1229 register_post_type( 1230 'wptests_similar', 1231 array( 1232 'public' => true, 1233 'has_archive' => $slug, 1234 ) 1235 ); 1236 1237 $this->get_random_rewrite_rules(); 1238 1239 $this->assertSame( 'index.php?random=1', $this->get_stored_rewrite_rules()['random/?$'] ?? null, "The root rule should be kept for a post type archive at {$slug}." ); 1240 } 1241 1242 /** 1243 * Data provider. 1244 * 1245 * @return array<string, string[]> 1246 */ 1247 public static function data_random_root_rule_is_kept_for_a_post_type_archive_with_a_similar_slug(): array { 1248 return array( 1249 'suffixed' => array( 'randomful' ), 1250 'hyphenated' => array( 'random-ful' ), 1251 'prefixed' => array( 'not-random' ), 1252 ); 1253 } 1254 1255 /** 1256 * Ensure the root rule is omitted when a top rule uses its regex with a custom random base. 1257 * 1258 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 1259 */ 1260 public function test_random_root_rule_is_omitted_when_a_top_rule_uses_its_regex_with_a_custom_random_base(): void { 1261 global $wp_rewrite; 1262 1263 $wp_rewrite->random_base = 'surprise-me'; 1264 add_rewrite_rule( 'surprise-me/?$', 'index.php?pagename=wptests-taken', 'top' ); 1265 1266 $this->get_random_rewrite_rules(); 1267 1268 $this->assertSame( 'index.php?pagename=wptests-taken', $this->get_stored_rewrite_rules()['surprise-me/?$'] ?? null, 'The top rule should take precedence over the root rule for the custom random base.' ); 1269 } 1270 1271 /** 1272 * Ensure a top rule at the default random base does not replace the root rule for a custom random base. 1273 * 1274 * @global WP_Rewrite $wp_rewrite WordPress rewrite component. 1275 */ 1276 public function test_random_root_rule_is_kept_when_a_top_rule_uses_the_default_base_with_a_custom_random_base(): void { 1277 global $wp_rewrite; 1278 1279 $wp_rewrite->random_base = 'surprise-me'; 1280 add_rewrite_rule( 'random/?$', 'index.php?pagename=wptests-taken', 'top' ); 1281 1282 $this->get_random_rewrite_rules(); 1283 1284 $this->assertSame( 'index.php?random=1', $this->get_stored_rewrite_rules()['surprise-me/?$'] ?? null, 'The root rule for the custom random base should be kept when a top rule only uses the default random base.' ); 1285 } 1286 1287 /** 1288 * Ensure the root rule is omitted when a top rule uses its regex with PATHINFO permalinks. 1289 */ 1290 public function test_random_root_rule_is_omitted_when_a_top_rule_uses_its_regex_with_pathinfo_permalinks(): void { 1291 $this->set_permalink_structure( '/index.php/%postname%/' ); 1292 create_initial_taxonomies(); 1293 1294 add_rewrite_rule( 'index.php/random/?$', 'index.php?pagename=wptests-taken', 'top' ); 1295 1296 $this->get_random_rewrite_rules(); 1297 1298 $this->assertSame( 'index.php?pagename=wptests-taken', $this->get_stored_rewrite_rules()['index.php/random/?$'] ?? null, 'The top rule should take precedence over the root rule with PATHINFO permalinks.' ); 1299 } 1057 1300 }
Note:
See TracChangeset
for help on using the changeset viewer.