WordPress.org

Make WordPress Core

Ticket #5305: 5305.17.diff

File 5305.17.diff, 33.1 KB (added by boonebgorges, 5 years ago)
  • src/wp-includes/class-wp.php

    diff --git src/wp-includes/class-wp.php src/wp-includes/class-wp.php
    index efe77ad..8a2f177 100644
    class WP { 
    308308                        }
    309309                }
    310310
     311                // Resolve conflicts between posts with numeric slugs and date archive queries.
     312                $this->query_vars = wp_resolve_numeric_slug_conflicts( $this->query_vars );
     313
    311314                foreach ( (array) $this->private_query_vars as $var) {
    312315                        if ( isset($this->extra_query_vars[$var]) )
    313316                                $this->query_vars[$var] = $this->extra_query_vars[$var];
  • src/wp-includes/post.php

    diff --git src/wp-includes/post.php src/wp-includes/post.php
    index 564d4ee..b0b1391 100644
    function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p 
    37703770                $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
    37713771                $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );
    37723772
     3773                // Prevent post slugs that could result in URLs that conflict with date archives.
     3774                $conflicts_with_date_archive = false;
     3775                if ( 'post' === $post_type && preg_match( '/^[0-9]+$/', $slug ) && $slug_num = intval( $slug ) ) {
     3776                        $permastructs   = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
     3777                        $postname_index = array_search( '%postname%', $permastructs );
     3778
     3779                        /*
     3780                         * Potential date clashes are as follows:
     3781                         *
     3782                         * - Any integer in the first permastruct position could be a year.
     3783                         * - An integer between 1 and 12 that follows 'year' conflicts with 'monthnum'.
     3784                         * - An integer between 1 and 31 that follows 'monthnum' conflicts with 'day'.
     3785                         */
     3786                        if ( 0 === $postname_index ||
     3787                                ( $postname_index && '%year%' === $permastructs[ $postname_index - 1 ] && 13 > $slug_num ) ||
     3788                                ( $postname_index && '%monthnum%' === $permastructs[ $postname_index - 1 ] && 32 > $slug_num )
     3789                        ) {
     3790                                $conflicts_with_date_archive = true;
     3791                        }
     3792                }
     3793
    37733794                /**
    37743795                 * Filter whether the post slug would be bad as a flat slug.
    37753796                 *
    function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p 
    37793800                 * @param string $slug      The post slug.
    37803801                 * @param string $post_type Post type.
    37813802                 */
    3782                 if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
     3803                if ( $post_name_check || in_array( $slug, $feeds ) || $conflicts_with_date_archive || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
    37833804                        $suffix = 2;
    37843805                        do {
    37853806                                $alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  • src/wp-includes/rewrite.php

    diff --git src/wp-includes/rewrite.php src/wp-includes/rewrite.php
    index 51e3a6b..9a1fad8 100644
    function _wp_filter_taxonomy_base( $base ) { 
    277277        return $base;
    278278}
    279279
     280
     281/**
     282 * Resolve numeric slugs that collide with date permalinks.
     283 *
     284 * Permalinks of posts with numeric slugs can sometimes look to `WP_Query::parse_query()` like a date archive,
     285 * as when your permalink structure is `/%year%/%postname%/` and a post with post_name '05' has the URL
     286 * `/2015/05/`. This function detects these conflicts and resolves conflicts in favor of the post permalink.
     287 *
     288 * @since 4.3.0
     289 *
     290 * @param array $query_vars Query variables for setting up the loop, as determined in `WP::parse_request()`.
     291 * @return array Returns the original array of query vars, with date/post conflicts resolved.
     292 */
     293function wp_resolve_numeric_slug_conflicts( $query_vars = array() ) {
     294        if ( ! isset( $query_vars['year'] ) && ! isset( $query_vars['monthnum'] ) && ! isset( $query_vars['day'] ) ) {
     295                return $query_vars;
     296        }
     297
     298        // Identify the 'postname' position in the permastruct array.
     299        $permastructs   = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
     300        $postname_index = array_search( '%postname%', $permastructs );
     301
     302        if ( false === $postname_index ) {
     303                return $query_vars;
     304        }
     305
     306        /*
     307         * A numeric slug could be confused with a year, month, or day, depending on position. To account for
     308         * the possibility of post pagination (eg 2015/2 for the second page of a post called '2015'), our
     309         * `is_*` checks are generous: check for year-slug clashes when `is_year` *or* `is_month`, and check
     310         * for month-slug clashes when `is_month` *or* `is_day`.
     311         */
     312        $compare = '';
     313        if ( 0 === $postname_index && ( isset( $query_vars['year'] ) || isset( $query_vars['monthnum'] ) ) ) {
     314                $compare = 'year';
     315        } else if ( '%year%' === $permastructs[ $postname_index - 1 ] && ( isset( $query_vars['monthnum'] ) || isset( $query_vars['day'] ) ) ) {
     316                $compare = 'monthnum';
     317        } else if ( '%monthnum%' === $permastructs[ $postname_index - 1 ] && isset( $query_vars['day'] ) ) {
     318                $compare = 'day';
     319        }
     320
     321        if ( ! $compare ) {
     322                return $query_vars;
     323        }
     324
     325        // This is the potentially clashing slug.
     326        $value = $query_vars[ $compare ];
     327
     328        $post = get_page_by_path( $value, OBJECT, 'post' );
     329        if ( ! ( $post instanceof WP_Post ) ) {
     330                return $query_vars;
     331        }
     332
     333        // If the date of the post doesn't match the date specified in the URL, resolve to the date archive.
     334        if ( preg_match( '/^([0-9]{4})\-([0-9]{2})/', $post->post_date, $matches ) && isset( $query_vars['year'] ) && ( 'monthnum' === $compare || 'day' === $compare ) ) {
     335                // $matches[1] is the year the post was published.
     336                if ( intval( $query_vars['year'] ) !== intval( $matches[1] ) ) {
     337                        return $query_vars;
     338                }
     339
     340                // $matches[2] is the month the post was published.
     341                if ( 'day' === $compare && isset( $query_vars['monthnum'] ) && intval( $query_vars['monthnum'] ) !== intval( $matches[2] ) ) {
     342                        return $query_vars;
     343                }
     344        }
     345
     346        /*
     347         * If the located post contains nextpage pagination, then the URL chunk following postname may be
     348         * intended as the page number. Verify that it's a valid page before resolving to it.
     349         */
     350        $maybe_page = '';
     351        if ( 'year' === $compare && isset( $query_vars['monthnum'] ) ) {
     352                $maybe_page = $query_vars['monthnum'];
     353        } else if ( 'monthnum' === $compare && isset( $query_vars['day'] ) ) {
     354                $maybe_page = $query_vars['day'];
     355        }
     356
     357        $post_page_count = substr_count( $post->post_content, '<!--nextpage-->' ) + 1;
     358
     359        // If the post doesn't have multiple pages, but a 'page' candidate is found, resolve to the date archive.
     360        if ( 1 === $post_page_count && $maybe_page ) {
     361                return $query_vars;
     362        }
     363
     364        // If the post has multiple pages and the 'page' number isn't valid, resolve to the date archive.
     365        if ( $post_page_count > 1 && $maybe_page > $post_page_count ) {
     366                return $query_vars;
     367        }
     368
     369        // If we've gotten to this point, we have a slug/date clash. First, adjust for nextpage.
     370        if ( '' !== $maybe_page ) {
     371                $query_vars['page'] = intval( $maybe_page );
     372        }
     373
     374        // Next, unset autodetected date-related query vars.
     375        unset( $query_vars['year'] );
     376        unset( $query_vars['monthnum'] );
     377        unset( $query_vars['day'] );
     378
     379        // Then, set the identified post.
     380        $query_vars['name'] = $post->post_name;
     381
     382        // Finally, return the modified query vars.
     383        return $query_vars;
     384}
     385
    280386/**
    281387 * Examine a url and try to determine the post ID it represents.
    282388 *
    function url_to_postid($url) { 
    392498                                }
    393499                        }
    394500
     501                        // Resolve conflicts between posts with numeric slugs and date archive queries.
     502                        $query = wp_resolve_numeric_slug_conflicts( $query );
     503
    395504                        // Do the query
    396505                        $query = new WP_Query( $query );
    397506                        if ( ! empty( $query->posts ) && $query->is_singular )
  • tests/phpunit/tests/admin/includesPost.php

    diff --git tests/phpunit/tests/admin/includesPost.php tests/phpunit/tests/admin/includesPost.php
    index 5d2623a..e25a917 100644
    class Tests_Admin_includesPost extends WP_UnitTestCase { 
    313313                $wp_rewrite->set_permalink_structure( $old_permalink_structure );
    314314                flush_rewrite_rules();
    315315        }
     316
     317        /**
     318         * @ticket 5305
     319         */
     320        public function test_get_sample_permalink_should_avoid_slugs_that_would_create_clashes_with_year_archives() {
     321                global $wp_rewrite;
     322                $wp_rewrite->init();
     323                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     324                $wp_rewrite->flush_rules();
     325
     326                $p = $this->factory->post->create( array(
     327                        'post_name' => '2015',
     328                ) );
     329
     330                $found = get_sample_permalink( $p );
     331                $this->assertEquals( '2015-2', $found[1] );
     332
     333                $wp_rewrite->set_permalink_structure( '' );
     334                flush_rewrite_rules();
     335        }
     336
     337        /**
     338         * @ticket 5305
     339         */
     340        public function test_get_sample_permalink_should_allow_yearlike_slugs_if_permastruct_does_not_cause_an_archive_conflict() {
     341                global $wp_rewrite;
     342                $wp_rewrite->init();
     343                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     344                $wp_rewrite->flush_rules();
     345
     346                $p = $this->factory->post->create( array(
     347                        'post_name' => '2015',
     348                ) );
     349
     350                $found = get_sample_permalink( $p );
     351                $this->assertEquals( '2015', $found[1] );
     352
     353                $wp_rewrite->set_permalink_structure( '' );
     354                flush_rewrite_rules();
     355        }
     356
     357        /**
     358         * @ticket 5305
     359         */
     360        public function test_get_sample_permalink_should_avoid_slugs_that_would_create_clashes_with_month_archives() {
     361                global $wp_rewrite;
     362                $wp_rewrite->init();
     363                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     364                $wp_rewrite->flush_rules();
     365
     366                $p = $this->factory->post->create( array(
     367                        'post_name' => '11',
     368                ) );
     369
     370                $found = get_sample_permalink( $p );
     371                $this->assertEquals( '11-2', $found[1] );
     372
     373                $wp_rewrite->set_permalink_structure( '' );
     374                flush_rewrite_rules();
     375        }
     376
     377        /**
     378         * @ticket 5305
     379         */
     380        public function test_get_sample_permalink_should_ignore_potential_month_conflicts_for_invalid_monthnum() {
     381                global $wp_rewrite;
     382                $wp_rewrite->init();
     383                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     384                $wp_rewrite->flush_rules();
     385
     386                $p = $this->factory->post->create( array(
     387                        'post_name' => '13',
     388                ) );
     389
     390                $found = get_sample_permalink( $p );
     391                $this->assertEquals( '13', $found[1] );
     392
     393                $wp_rewrite->set_permalink_structure( '' );
     394                flush_rewrite_rules();
     395        }
     396
     397        /**
     398         * @ticket 5305
     399         */
     400        public function test_get_sample_permalink_should_avoid_slugs_that_would_create_clashes_with_day_archives() {
     401                global $wp_rewrite;
     402                $wp_rewrite->init();
     403                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     404                $wp_rewrite->flush_rules();
     405
     406                $p = $this->factory->post->create( array(
     407                        'post_name' => '30',
     408                ) );
     409
     410                $found = get_sample_permalink( $p );
     411                $this->assertEquals( '30-2', $found[1] );
     412
     413                $wp_rewrite->set_permalink_structure( '' );
     414                flush_rewrite_rules();
     415        }
     416
     417        /**
     418         * @ticket 5305
     419         */
     420        public function test_get_sample_permalink_should_iterate_slug_suffix_when_a_date_conflict_is_found() {
     421                global $wp_rewrite;
     422                $wp_rewrite->init();
     423                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     424                $wp_rewrite->flush_rules();
     425
     426                $this->factory->post->create( array(
     427                        'post_name' => '30-2',
     428                ) );
     429
     430                $p = $this->factory->post->create( array(
     431                        'post_name' => '30',
     432                ) );
     433
     434                $found = get_sample_permalink( $p );
     435                $this->assertEquals( '30-3', $found[1] );
     436
     437                $wp_rewrite->set_permalink_structure( '' );
     438                flush_rewrite_rules();
     439        }
     440
     441        /**
     442         * @ticket 5305
     443         */
     444        public function test_get_sample_permalink_should_ignore_potential_day_conflicts_for_invalid_day() {
     445                global $wp_rewrite;
     446                $wp_rewrite->init();
     447                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     448                $wp_rewrite->flush_rules();
     449
     450                $p = $this->factory->post->create( array(
     451                        'post_name' => '32',
     452                ) );
     453
     454                $found = get_sample_permalink( $p );
     455                $this->assertEquals( '32', $found[1] );
     456
     457                $wp_rewrite->set_permalink_structure( '' );
     458                flush_rewrite_rules();
     459        }
     460
     461        /**
     462         * @ticket 5305
     463         */
     464        public function test_get_sample_permalink_should_allow_daylike_slugs_if_permastruct_does_not_cause_an_archive_conflict() {
     465                global $wp_rewrite;
     466                $wp_rewrite->init();
     467                $wp_rewrite->set_permalink_structure( '/%year%/%month%/%day%/%postname%/' );
     468                $wp_rewrite->flush_rules();
     469
     470                $p = $this->factory->post->create( array(
     471                        'post_name' => '30',
     472                ) );
     473
     474                $found = get_sample_permalink( $p );
     475                $this->assertEquals( '30', $found[1] );
     476
     477                $wp_rewrite->set_permalink_structure( '' );
     478                flush_rewrite_rules();
     479        }
    316480}
  • tests/phpunit/tests/post/wpUniquePostSlug.php

    diff --git tests/phpunit/tests/post/wpUniquePostSlug.php tests/phpunit/tests/post/wpUniquePostSlug.php
    index 019e6bd..3256172 100644
    class Tests_Post_WpUniquePostSlug extends WP_UnitTestCase { 
    164164
    165165                $this->assertSame( 'foo', $actual );
    166166        }
     167
     168        /**
     169         * @ticket 5305
     170         */
     171        public function test_slugs_resulting_in_permalinks_that_resemble_year_archives_should_be_suffixed() {
     172                global $wp_rewrite;
     173                $wp_rewrite->init();
     174                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     175                $wp_rewrite->flush_rules();
     176
     177                $p = $this->factory->post->create( array(
     178                        'post_type' => 'post',
     179                        'post_name' => 'foo',
     180                ) );
     181
     182                $found = wp_unique_post_slug( '2015', $p, 'publish', 'post', 0 );
     183                $this->assertEquals( '2015-2', $found );
     184
     185                $wp_rewrite->set_permalink_structure( '' );
     186                flush_rewrite_rules();
     187        }
     188
     189        /**
     190         * @ticket 5305
     191         */
     192        public function test_yearlike_slugs_should_not_be_suffixed_if_permalink_structure_does_not_result_in_a_clash_with_year_archives() {
     193                global $wp_rewrite;
     194                $wp_rewrite->init();
     195                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     196                $wp_rewrite->flush_rules();
     197
     198                $p = $this->factory->post->create( array(
     199                        'post_type' => 'post',
     200                        'post_name' => 'foo',
     201                ) );
     202
     203                $found = wp_unique_post_slug( '2015', $p, 'publish', 'post', 0 );
     204                $this->assertEquals( '2015', $found );
     205
     206                $wp_rewrite->set_permalink_structure( '' );
     207                flush_rewrite_rules();
     208        }
     209
     210        /**
     211         * @ticket 5305
     212         */
     213        public function test_slugs_resulting_in_permalinks_that_resemble_month_archives_should_be_suffixed() {
     214                global $wp_rewrite;
     215                $wp_rewrite->init();
     216                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     217                $wp_rewrite->flush_rules();
     218
     219                $p = $this->factory->post->create( array(
     220                        'post_type' => 'post',
     221                        'post_name' => 'foo',
     222                ) );
     223
     224                $found = wp_unique_post_slug( '11', $p, 'publish', 'post', 0 );
     225                $this->assertEquals( '11-2', $found );
     226
     227                $wp_rewrite->set_permalink_structure( '' );
     228                flush_rewrite_rules();
     229        }
     230
     231        /**
     232         * @ticket 5305
     233         */
     234        public function test_monthlike_slugs_should_not_be_suffixed_if_permalink_structure_does_not_result_in_a_clash_with_month_archives() {
     235                global $wp_rewrite;
     236                $wp_rewrite->init();
     237                $wp_rewrite->set_permalink_structure( '/%year%/foo/%postname%/' );
     238                $wp_rewrite->flush_rules();
     239
     240                $p = $this->factory->post->create( array(
     241                        'post_type' => 'post',
     242                        'post_name' => 'foo',
     243                ) );
     244
     245                $found = wp_unique_post_slug( '11', $p, 'publish', 'post', 0 );
     246                $this->assertEquals( '11', $found );
     247
     248                $wp_rewrite->set_permalink_structure( '' );
     249                flush_rewrite_rules();
     250        }
     251
     252        /**
     253         * @ticket 5305
     254         */
     255        public function test_monthlike_slugs_should_not_be_suffixed_for_invalid_month_numbers() {
     256                global $wp_rewrite;
     257                $wp_rewrite->init();
     258                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     259                $wp_rewrite->flush_rules();
     260
     261                $p = $this->factory->post->create( array(
     262                        'post_type' => 'post',
     263                        'post_name' => 'foo',
     264                ) );
     265
     266                $found = wp_unique_post_slug( '13', $p, 'publish', 'post', 0 );
     267                $this->assertEquals( '13', $found );
     268
     269                $wp_rewrite->set_permalink_structure( '' );
     270                flush_rewrite_rules();
     271        }
     272
     273        /**
     274         * @ticket 5305
     275         */
     276        public function test_slugs_resulting_in_permalinks_that_resemble_day_archives_should_be_suffixed() {
     277                global $wp_rewrite;
     278                $wp_rewrite->init();
     279                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     280                $wp_rewrite->flush_rules();
     281
     282                $p = $this->factory->post->create( array(
     283                        'post_type' => 'post',
     284                        'post_name' => 'foo',
     285                ) );
     286
     287                $found = wp_unique_post_slug( '30', $p, 'publish', 'post', 0 );
     288                $this->assertEquals( '30-2', $found );
     289
     290                $wp_rewrite->set_permalink_structure( '' );
     291                flush_rewrite_rules();
     292        }
     293
     294        /**
     295         * @ticket 5305
     296         */
     297        public function test_daylike_slugs_should_not_be_suffixed_if_permalink_structure_does_not_result_in_a_clash_with_day_archives() {
     298                global $wp_rewrite;
     299                $wp_rewrite->init();
     300                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' );
     301                $wp_rewrite->flush_rules();
     302
     303                $p = $this->factory->post->create( array(
     304                        'post_type' => 'post',
     305                        'post_name' => 'foo',
     306                ) );
     307
     308                $found = wp_unique_post_slug( '30', $p, 'publish', 'post', 0 );
     309                $this->assertEquals( '30', $found );
     310
     311                $wp_rewrite->set_permalink_structure( '' );
     312                flush_rewrite_rules();
     313        }
     314
     315        /**
     316         * @ticket 5305
     317         */
     318        public function test_daylike_slugs_should_not_be_suffixed_for_invalid_day_numbers() {
     319                global $wp_rewrite;
     320                $wp_rewrite->init();
     321                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     322                $wp_rewrite->flush_rules();
     323
     324                $p = $this->factory->post->create( array(
     325                        'post_type' => 'post',
     326                        'post_name' => 'foo',
     327                ) );
     328
     329                $found = wp_unique_post_slug( '32', $p, 'publish', 'post', 0 );
     330                $this->assertEquals( '32', $found );
     331
     332                $wp_rewrite->set_permalink_structure( '' );
     333                flush_rewrite_rules();
     334        }
    167335}
  • new file tests/phpunit/tests/rewrite/numericSlugs.php

    diff --git tests/phpunit/tests/rewrite/numericSlugs.php tests/phpunit/tests/rewrite/numericSlugs.php
    new file mode 100644
    index 0000000..769c65c
    - +  
     1<?php
     2
     3/**
     4 * @group rewrite
     5 * @ticket 5305
     6 */
     7class Tests_Rewrite_NumericSlugs extends WP_UnitTestCase {
     8        private $old_current_user;
     9
     10        public function setUp() {
     11                parent::setUp();
     12                $this->author_id = $this->factory->user->create( array( 'role' => 'editor' ) );
     13
     14                // Override the post/archive slug collision prevention in `wp_unique_post_slug()`.
     15                add_filter( 'wp_unique_post_slug', array( $this, 'filter_unique_post_slug' ), 10, 6 );
     16        }
     17
     18        public function tearDown() {
     19                remove_filter( 'wp_unique_post_slug', array( $this, 'filter_unique_post_slug' ), 10, 6 );
     20        }
     21
     22        public function test_go_to_year_segment_collision_without_title() {
     23                global $wp_rewrite, $wpdb;
     24                $wp_rewrite->init();
     25                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     26                $wp_rewrite->flush_rules();
     27
     28                $id = $this->factory->post->create( array(
     29                        'post_author'  => $this->author_id,
     30                        'post_status'  => 'publish',
     31                        'post_content' => rand_str(),
     32                        'post_title'   => '',
     33                        'post_name'    => '2015',
     34                        'post_date'    => '2015-02-01 01:00:00'
     35                ) );
     36
     37                // Force an ID that resembles a year format
     38                $wpdb->update(
     39                        $wpdb->posts,
     40                        array(
     41                                'ID'   => '2015',
     42                                'guid' => 'http://example.org/?p=2015'
     43                        ),
     44                        array( 'ID' => $id )
     45                );
     46
     47                $this->go_to( get_permalink( '2015' ) );
     48
     49                $this->assertQueryTrue( 'is_single', 'is_singular' );
     50
     51                $wp_rewrite->set_permalink_structure('');
     52        }
     53
     54        public function test_url_to_postid_year_segment_collision_without_title() {
     55                global $wp_rewrite, $wpdb;
     56                $wp_rewrite->init();
     57                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     58                $wp_rewrite->flush_rules();
     59
     60                $id = $this->factory->post->create( array(
     61                        'post_author'  => $this->author_id,
     62                        'post_status'  => 'publish',
     63                        'post_content' => rand_str(),
     64                        'post_title'   => '',
     65                        'post_name'    => '2015',
     66                        'post_date'    => '2015-02-01 01:00:00'
     67                ) );
     68
     69                // Force an ID that resembles a year format
     70                $wpdb->update(
     71                        $wpdb->posts,
     72                        array(
     73                                'ID'   => '2015',
     74                                'guid' => 'http://example.org/?p=2015'
     75                        ),
     76                        array( 'ID' => $id )
     77                );
     78
     79                $this->assertEquals( '2015', url_to_postid( get_permalink( '2015' ) ) );
     80
     81                $wp_rewrite->set_permalink_structure('');
     82        }
     83
     84        public function test_go_to_year_segment_collision_with_title() {
     85                global $wp_rewrite;
     86                $wp_rewrite->init();
     87                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     88                $wp_rewrite->flush_rules();
     89
     90                $id = $this->factory->post->create( array(
     91                        'post_author'  => $this->author_id,
     92                        'post_status'  => 'publish',
     93                        'post_content' => rand_str(),
     94                        'post_title'   => '2015',
     95                        'post_date'    => '2015-02-01 01:00:00',
     96                ) );
     97
     98                $this->go_to( get_permalink( $id ) );
     99
     100                $this->assertQueryTrue( 'is_single', 'is_singular' );
     101
     102                $wp_rewrite->set_permalink_structure('');
     103        }
     104
     105        public function test_url_to_postid_year_segment_collision_with_title() {
     106                global $wp_rewrite;
     107                $wp_rewrite->init();
     108                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     109                $wp_rewrite->flush_rules();
     110
     111                $id = $this->factory->post->create( array(
     112                        'post_author'  => $this->author_id,
     113                        'post_status'  => 'publish',
     114                        'post_content' => rand_str(),
     115                        'post_title'   => '2015',
     116                        'post_date'    => '2015-02-01 01:00:00',
     117                ) );
     118
     119                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     120
     121                $wp_rewrite->set_permalink_structure('');
     122        }
     123
     124        public function test_go_to_month_segment_collision_without_title() {
     125                global $wp_rewrite;
     126                $wp_rewrite->init();
     127                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     128                $wp_rewrite->flush_rules();
     129
     130                $id = $this->factory->post->create( array(
     131                        'post_author'  => $this->author_id,
     132                        'post_status'  => 'publish',
     133                        'post_content' => rand_str(),
     134                        'post_title'   => '',
     135                        'post_name'    => '02',
     136                        'post_date'    => '2015-02-01 01:00:00',
     137                ) );
     138
     139                $this->go_to( get_permalink( $id ) );
     140
     141                $this->assertQueryTrue( 'is_single', 'is_singular' );
     142
     143                $wp_rewrite->set_permalink_structure('');
     144        }
     145
     146        public function test_url_to_postid_month_segment_collision_without_title() {
     147                global $wp_rewrite;
     148                $wp_rewrite->init();
     149                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     150                $wp_rewrite->flush_rules();
     151
     152                $id = $this->factory->post->create( array(
     153                        'post_author'  => $this->author_id,
     154                        'post_status'  => 'publish',
     155                        'post_content' => rand_str(),
     156                        'post_title'   => '',
     157                        'post_name'    => '02',
     158                        'post_date'    => '2015-02-01 01:00:00',
     159                ) );
     160
     161                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     162
     163                $wp_rewrite->set_permalink_structure('');
     164        }
     165
     166        public function test_go_to_month_segment_collision_without_title_no_leading_zero() {
     167                global $wp_rewrite;
     168                $wp_rewrite->init();
     169                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     170                $wp_rewrite->flush_rules();
     171
     172                $id = $this->factory->post->create( array(
     173                        'post_author'  => $this->author_id,
     174                        'post_status'  => 'publish',
     175                        'post_content' => rand_str(),
     176                        'post_title'   => '',
     177                        'post_name'    => '2',
     178                        'post_date'    => '2015-02-01 01:00:00',
     179                ) );
     180
     181                $this->go_to( get_permalink( $id ) );
     182
     183                $this->assertQueryTrue( 'is_single', 'is_singular' );
     184
     185                $wp_rewrite->set_permalink_structure('');
     186        }
     187
     188        public function test_url_to_postid_month_segment_collision_without_title_no_leading_zero() {
     189                global $wp_rewrite;
     190                $wp_rewrite->init();
     191                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     192                $wp_rewrite->flush_rules();
     193
     194                $id = $this->factory->post->create( array(
     195                        'post_author'  => $this->author_id,
     196                        'post_status'  => 'publish',
     197                        'post_content' => rand_str(),
     198                        'post_title'   => '',
     199                        'post_name'    => '2',
     200                        'post_date'    => '2015-02-01 01:00:00',
     201                ) );
     202
     203                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     204
     205                $wp_rewrite->set_permalink_structure('');
     206        }
     207
     208        public function test_go_to_month_segment_collision_with_title() {
     209                global $wp_rewrite;
     210                $wp_rewrite->init();
     211                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     212                $wp_rewrite->flush_rules();
     213
     214                $id = $this->factory->post->create( array(
     215                        'post_author'  => $this->author_id,
     216                        'post_status'  => 'publish',
     217                        'post_content' => rand_str(),
     218                        'post_title'   => '02',
     219                        'post_date'    => '2015-02-01 01:00:00',
     220                ) );
     221
     222                $this->go_to( get_permalink( $id ) );
     223
     224                $this->assertQueryTrue( 'is_single', 'is_singular' );
     225
     226                $wp_rewrite->set_permalink_structure('');
     227        }
     228
     229        public function test_url_to_postid_month_segment_collision_with_title() {
     230                global $wp_rewrite;
     231                $wp_rewrite->init();
     232                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     233                $wp_rewrite->flush_rules();
     234
     235                $id = $this->factory->post->create( array(
     236                        'post_author'  => $this->author_id,
     237                        'post_status'  => 'publish',
     238                        'post_content' => rand_str(),
     239                        'post_title'   => '02',
     240                        'post_date'    => '2015-02-01 01:00:00',
     241                ) );
     242
     243                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     244
     245                $wp_rewrite->set_permalink_structure('');
     246        }
     247
     248        public function test_go_to_month_segment_collision_with_title_no_leading_zero() {
     249                global $wp_rewrite;
     250                $wp_rewrite->init();
     251                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     252                $wp_rewrite->flush_rules();
     253
     254                $id = $this->factory->post->create( array(
     255                        'post_author'  => $this->author_id,
     256                        'post_status'  => 'publish',
     257                        'post_content' => rand_str(),
     258                        'post_title'   => '2',
     259                        'post_date'    => '2015-02-01 01:00:00',
     260                ) );
     261
     262                $this->go_to( get_permalink( $id ) );
     263
     264                $this->assertQueryTrue( 'is_single', 'is_singular' );
     265
     266                $wp_rewrite->set_permalink_structure('');
     267        }
     268
     269        public function test_url_to_postid_month_segment_collision_with_title_no_leading_zero() {
     270                global $wp_rewrite;
     271                $wp_rewrite->init();
     272                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     273                $wp_rewrite->flush_rules();
     274
     275                $id = $this->factory->post->create( array(
     276                        'post_author'  => $this->author_id,
     277                        'post_status'  => 'publish',
     278                        'post_content' => rand_str(),
     279                        'post_title'   => '2',
     280                        'post_date'    => '2015-02-01 01:00:00',
     281                ) );
     282
     283                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     284
     285                $wp_rewrite->set_permalink_structure('');
     286        }
     287
     288        public function test_go_to_day_segment_collision_without_title() {
     289                global $wp_rewrite;
     290                $wp_rewrite->init();
     291                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     292                $wp_rewrite->flush_rules();
     293
     294                $id = $this->factory->post->create( array(
     295                        'post_author'  => $this->author_id,
     296                        'post_status'  => 'publish',
     297                        'post_content' => rand_str(),
     298                        'post_title'   => '',
     299                        'post_name'    => '01',
     300                        'post_date'    => '2015-02-01 01:00:00',
     301                ) );
     302
     303                $this->go_to( get_permalink( $id ) );
     304
     305                $this->assertQueryTrue( 'is_single', 'is_singular' );
     306
     307                $wp_rewrite->set_permalink_structure('');
     308        }
     309
     310        public function test_url_to_postid_day_segment_collision_without_title() {
     311                global $wp_rewrite;
     312                $wp_rewrite->init();
     313                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     314                $wp_rewrite->flush_rules();
     315
     316                $id = $this->factory->post->create( array(
     317                        'post_author'  => $this->author_id,
     318                        'post_status'  => 'publish',
     319                        'post_content' => rand_str(),
     320                        'post_title'   => '',
     321                        'post_name'    => '01',
     322                        'post_date'    => '2015-02-01 01:00:00',
     323                ) );
     324
     325                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     326
     327                $wp_rewrite->set_permalink_structure('');
     328        }
     329
     330        public function test_go_to_day_segment_collision_with_title() {
     331                global $wp_rewrite;
     332                $wp_rewrite->init();
     333                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     334                $wp_rewrite->flush_rules();
     335
     336                $id = $this->factory->post->create( array(
     337                        'post_author'  => $this->author_id,
     338                        'post_status'  => 'publish',
     339                        'post_content' => rand_str(),
     340                        'post_title'   => '01',
     341                        'post_date'    => '2015-02-01 01:00:00',
     342                ) );
     343
     344                $this->go_to( get_permalink( $id ) );
     345
     346                $this->assertQueryTrue( 'is_single', 'is_singular' );
     347
     348                $wp_rewrite->set_permalink_structure('');
     349        }
     350
     351        public function test_url_to_postid_day_segment_collision_with_title() {
     352                global $wp_rewrite;
     353                $wp_rewrite->init();
     354                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     355                $wp_rewrite->flush_rules();
     356
     357                $id = $this->factory->post->create( array(
     358                        'post_author'  => $this->author_id,
     359                        'post_status'  => 'publish',
     360                        'post_content' => rand_str(),
     361                        'post_title'   => '01',
     362                        'post_date'    => '2015-02-01 01:00:00',
     363                ) );
     364
     365                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     366
     367                $wp_rewrite->set_permalink_structure('');
     368        }
     369
     370        public function test_numeric_slug_permalink_conflicts_should_only_be_resolved_for_the_main_query() {
     371                global $wp_rewrite;
     372                $wp_rewrite->init();
     373                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     374                $wp_rewrite->flush_rules();
     375
     376                $id = $this->factory->post->create( array(
     377                        'post_author'  => $this->author_id,
     378                        'post_status'  => 'publish',
     379                        'post_content' => rand_str(),
     380                        'post_title'   => '01',
     381                        'post_date'    => '2015-02-01 01:00:00',
     382                ) );
     383
     384                $q = new WP_Query( array(
     385                        'year'     => '2015',
     386                        'monthnum' => '02',
     387                        'day'      => '01',
     388                ) );
     389
     390                $this->assertTrue( $q->is_day );
     391                $this->assertFalse( $q->is_single );
     392
     393                $wp_rewrite->set_permalink_structure('');
     394        }
     395
     396        public function test_month_slug_collision_should_resolve_to_date_archive_when_year_does_not_match_post_year() {
     397                global $wp_rewrite;
     398                $wp_rewrite->init();
     399                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     400                $wp_rewrite->flush_rules();
     401
     402                // Make sure a post is published in 2013/02, to avoid 404s.
     403                $this->factory->post->create( array(
     404                        'post_author'  => $this->author_id,
     405                        'post_status'  => 'publish',
     406                        'post_content' => 'foo',
     407                        'post_title'   => 'bar',
     408                        'post_date'    => '2013-02-01 01:00:00',
     409                ) );
     410
     411                $id = $this->factory->post->create( array(
     412                        'post_author'  => $this->author_id,
     413                        'post_status'  => 'publish',
     414                        'post_content' => 'foo',
     415                        'post_title'   => '02',
     416                        'post_date'    => '2015-02-01 01:00:00',
     417                ) );
     418
     419                $permalink = get_permalink( $id );
     420                $permalink = str_replace( '/2015/', '/2013/', $permalink );
     421
     422                $this->go_to( $permalink );
     423
     424                $this->assertTrue( is_month() );
     425        }
     426
     427        public function test_day_slug_collision_should_resolve_to_date_archive_when_monthnum_does_not_match_post_month() {
     428                global $wp_rewrite;
     429                $wp_rewrite->init();
     430                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     431                $wp_rewrite->flush_rules();
     432
     433                // Make sure a post is published on 2015/01/01, to avoid 404s.
     434                $this->factory->post->create( array(
     435                        'post_author'  => $this->author_id,
     436                        'post_status'  => 'publish',
     437                        'post_content' => 'foo',
     438                        'post_title'   => 'bar',
     439                        'post_date'    => '2015-01-02 01:00:00',
     440                ) );
     441
     442                $id = $this->factory->post->create( array(
     443                        'post_author'  => $this->author_id,
     444                        'post_status'  => 'publish',
     445                        'post_content' => 'foo',
     446                        'post_title'   => '02',
     447                        'post_date'    => '2015-02-02 01:00:00',
     448                ) );
     449
     450                $permalink = get_permalink( $id );
     451                $permalink = str_replace( '/2015/02/', '/2015/01/', $permalink );
     452
     453                $this->go_to( $permalink );
     454
     455                $this->assertTrue( is_day() );
     456        }
     457
     458        public function test_date_slug_collision_should_distinguish_valid_pagination_from_date() {
     459                global $wp_rewrite;
     460                $wp_rewrite->init();
     461                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     462                $wp_rewrite->flush_rules();
     463
     464                $id = $this->factory->post->create( array(
     465                        'post_author'  => $this->author_id,
     466                        'post_status'  => 'publish',
     467                        'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3',
     468                        'post_title'   => '02',
     469                        'post_date'    => '2015-02-01 01:00:00',
     470                ) );
     471
     472                $this->go_to( get_permalink( $id ) . '1' );
     473
     474                $this->assertFalse( is_day() );
     475        }
     476
     477        public function test_date_slug_collision_should_distinguish_too_high_pagination_from_date() {
     478                global $wp_rewrite;
     479                $wp_rewrite->init();
     480                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     481                $wp_rewrite->flush_rules();
     482
     483                $id = $this->factory->post->create( array(
     484                        'post_author'  => $this->author_id,
     485                        'post_status'  => 'publish',
     486                        'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3',
     487                        'post_title'   => '02',
     488                        'post_date'    => '2015-02-05 01:00:00',
     489                ) );
     490
     491                $this->go_to( get_permalink( $id ) . '5' );
     492
     493                $this->assertTrue( is_day() );
     494        }
     495
     496        public function test_date_slug_collision_should_not_require_pagination_query_var() {
     497                global $wp_rewrite;
     498                $wp_rewrite->init();
     499                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     500                $wp_rewrite->flush_rules();
     501
     502                $id = $this->factory->post->create( array(
     503                        'post_author'  => $this->author_id,
     504                        'post_status'  => 'publish',
     505                        'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3',
     506                        'post_title'   => '02',
     507                        'post_date'    => '2015-02-05 01:00:00',
     508                ) );
     509
     510                $this->go_to( get_permalink( $id ) );
     511
     512                $this->assertQueryTrue( 'is_single', 'is_singular' );
     513                $this->assertFalse( is_date() );
     514        }
     515
     516        public function test_date_slug_collision_should_be_ignored_when_pagination_var_is_present_but_post_does_not_have_multiple_pages() {
     517                global $wp_rewrite;
     518                $wp_rewrite->init();
     519                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     520                $wp_rewrite->flush_rules();
     521
     522                $id = $this->factory->post->create( array(
     523                        'post_author'  => $this->author_id,
     524                        'post_status'  => 'publish',
     525                        'post_content' => 'This post does not have pagination.',
     526                        'post_title'   => '02',
     527                        'post_date'    => '2015-02-05 01:00:00',
     528                ) );
     529
     530                $this->go_to( get_permalink( $id ) . '5' );
     531
     532                $this->assertTrue( is_day() );
     533        }
     534
     535        public function filter_unique_post_slug( $slug, $post_id, $post_status, $post_type, $post_parent, $original_slug ) {
     536                return $original_slug;
     537        }
     538}