WordPress.org

Make WordPress Core

Ticket #5305: 5305.7.diff

File 5305.7.diff, 7.9 KB (added by boonebgorges, 5 years ago)
  • src/wp-includes/query.php

    diff --git src/wp-includes/query.php src/wp-includes/query.php
    index f076533..609e46e 100644
    class WP_Query { 
    17431743                        $qv['withcomments'] = 1;
    17441744                }
    17451745
     1746                $this->resolve_numeric_slugs();
     1747
    17461748                $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
    17471749
    17481750                if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) )
    class WP_Query { 
    23212323        }
    23222324
    23232325        /**
     2326         * Resolves numeric slugs that collide with date permalinks.
     2327         *
     2328         * @since 4.2.0
     2329         */
     2330        protected function resolve_numeric_slugs() {
     2331                if ( ! $this->is_date ) {
     2332                        return;
     2333                }
     2334
     2335                // Identify the 'postname' position in the permastruct array.
     2336                $permastructs = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
     2337
     2338                $postname_index = array_search( '%postname%', $permastructs );
     2339
     2340                if ( false === $postname_index ) {
     2341                        return;
     2342                }
     2343
     2344                /*
     2345                 * A numeric slug could be confused with a year, month, or day, depending on position.
     2346                 * To account for the possibility of post pagination (eg 2015/2 for the second page of a post called
     2347                 * '2015'), our `is_*` checks are generous: check for year-slug clashes when `is_year` *or* `is_month`,
     2348                 * and check for month-slug clashes when `is_month` *or* `is_day`.
     2349                 */
     2350                $compare = $value = '';
     2351                if ( 0 === $postname_index && ( $this->is_year || $this->is_month ) ) {
     2352                        $compare = 'year';
     2353                        $value = $this->get( 'year' );
     2354                } else if ( '%year%' === $permastructs[ $postname_index - 1 ] && ( $this->is_month || $this->is_day ) ) {
     2355                        $compare = 'month';
     2356                        $value = $this->get( 'monthnum' );
     2357                } else if ( '%monthnum%' === $permastructs[ $postname_index - 1 ] && $this->is_day ) {
     2358                        $compare = 'day';
     2359                        $value = $this->get( 'day' );
     2360                }
     2361
     2362                if ( ! $compare ) {
     2363                        return;
     2364                }
     2365
     2366                // todo - why?
     2367                if ( 'year' !== $compare ) {
     2368                        $value = zeroise( $value, 2 );
     2369                }
     2370
     2371                $post = get_page_by_path( $value, OBJECT, 'post' );
     2372                if ( ! ( $post instanceof WP_Post ) ) {
     2373                        return;
     2374                }
     2375
     2376                /*
     2377                 * If we've gotten to this point, we have a slug/date clash.
     2378                 * First, adjust pagination, which would have previously been identified as part of the date query.
     2379                 */
     2380                if ( 'year' === $compare && $this->is_month ) {
     2381                        $this->set( 'page', $this->get( 'monthnum' ) );
     2382                } else if ( 'month' === $compare && $this->is_day ) {
     2383                        $this->set( 'page', $this->get( 'day' ) );
     2384                }
     2385
     2386                // Next, unset autodetected date-related query vars.
     2387                $this->is_archive = false;
     2388                $this->is_date    = false;
     2389                $this->is_year    = false;
     2390                $this->is_month   = false;
     2391                $this->is_day     = false;
     2392                $this->set( 'year', '' );
     2393                $this->set( 'monthnum', '' );
     2394                $this->set( 'day', '' );
     2395
     2396                // Finally, tell the query that it's a singular query for the identified post.
     2397                $this->is_single   = true;
     2398                $this->is_singular = true;
     2399                $this->set( 'name', $post->post_name );
     2400        }
     2401
     2402        /**
    23242403         * Sets the 404 property and saves whether query is feed.
    23252404         *
    23262405         * @since 2.0.0
  • tests/phpunit/tests/post.php

    diff --git tests/phpunit/tests/post.php tests/phpunit/tests/post.php
    index ae549e0..e7f4f8c 100644
    class Tests_Post extends WP_UnitTestCase { 
    470470        }
    471471
    472472        /**
     473         * @ticket 5305
     474         */
     475        function test_permalink_year_segment_collision_without_title() {
     476                global $wp_rewrite, $wpdb;
     477                $wp_rewrite->init();
     478                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     479                $wp_rewrite->flush_rules();
     480
     481                $id = $this->factory->post->create( array(
     482                        'post_author'  => $this->author_id,
     483                        'post_status'  => 'publish',
     484                        'post_content' => rand_str(),
     485                        'post_title'   => '',
     486                        'post_name'    => '2015',
     487                        'post_date'    => '2015-02-01 01:00:00'
     488                ) );
     489
     490                // Force an ID that resembles a year format
     491                $wpdb->update(
     492                        $wpdb->posts,
     493                        array(
     494                                'ID'   => '2015',
     495                                'guid' => 'http://example.org/?p=2015'
     496                        ),
     497                        array( 'ID' => $id )
     498                );
     499
     500                $this->go_to( get_permalink( '2015' ) );
     501
     502                $this->assertQueryTrue( 'is_single', 'is_singular' );
     503
     504                $wp_rewrite->set_permalink_structure('');
     505        }
     506
     507        /**
     508         * @ticket 5305
     509         */
     510        function test_permalink_year_segment_collision_with_title() {
     511                global $wp_rewrite;
     512                $wp_rewrite->init();
     513                $wp_rewrite->set_permalink_structure( '/%postname%/' );
     514                $wp_rewrite->flush_rules();
     515
     516                $id = $this->factory->post->create( array(
     517                        'post_author'  => $this->author_id,
     518                        'post_status'  => 'publish',
     519                        'post_content' => rand_str(),
     520                        'post_title'   => '2015',
     521                        'post_date'    => '2015-02-01 01:00:00',
     522                ) );
     523
     524                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     525
     526                $wp_rewrite->set_permalink_structure('');
     527        }
     528
     529        /**
     530         * @ticket 5305
     531         */
     532        function test_permalink_month_segment_collision_without_title() {
     533                global $wp_rewrite;
     534                $wp_rewrite->init();
     535                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     536                $wp_rewrite->flush_rules();
     537
     538                $id = $this->factory->post->create( array(
     539                        'post_author'  => $this->author_id,
     540                        'post_status'  => 'publish',
     541                        'post_content' => rand_str(),
     542                        'post_title'   => '',
     543                        'post_name'    => '02',
     544                        'post_date'    => '2015-02-01 01:00:00',
     545                ) );
     546
     547                $this->go_to( get_permalink( $id ) );
     548
     549                $this->assertQueryTrue( 'is_single', 'is_singular' );
     550
     551                $wp_rewrite->set_permalink_structure('');
     552        }
     553
     554        /**
     555         * @ticket 5305
     556         */
     557        function test_permalink_month_segment_collision_with_title() {
     558                global $wp_rewrite;
     559                $wp_rewrite->init();
     560                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     561                $wp_rewrite->flush_rules();
     562
     563                $id = $this->factory->post->create( array(
     564                        'post_author'  => $this->author_id,
     565                        'post_status'  => 'publish',
     566                        'post_content' => rand_str(),
     567                        'post_title'   => '02',
     568                        'post_date'    => '2015-02-01 01:00:00',
     569                ) );
     570
     571                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     572
     573                $wp_rewrite->set_permalink_structure('');
     574        }
     575
     576        /**
     577         * @ticket 5305
     578         */
     579        function test_permalink_day_segment_collision_without_title() {
     580                global $wp_rewrite;
     581                $wp_rewrite->init();
     582                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     583                $wp_rewrite->flush_rules();
     584
     585                $id = $this->factory->post->create( array(
     586                        'post_author'  => $this->author_id,
     587                        'post_status'  => 'publish',
     588                        'post_content' => rand_str(),
     589                        'post_title'   => '',
     590                        'post_name'    => '01',
     591                        'post_date'    => '2015-02-01 01:00:00',
     592                ) );
     593
     594                $this->go_to( get_permalink( $id ) );
     595
     596                $this->assertQueryTrue( 'is_single', 'is_singular' );
     597
     598                $wp_rewrite->set_permalink_structure('');
     599        }
     600
     601        /**
     602         * @ticket 5305
     603         */
     604        function test_permalink_day_segment_collision_with_title() {
     605                global $wp_rewrite;
     606                $wp_rewrite->init();
     607                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     608                $wp_rewrite->flush_rules();
     609
     610                $id = $this->factory->post->create( array(
     611                        'post_author'  => $this->author_id,
     612                        'post_status'  => 'publish',
     613                        'post_content' => rand_str(),
     614                        'post_title'   => '01',
     615                        'post_date'    => '2015-02-01 01:00:00',
     616                ) );
     617
     618                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     619
     620                $wp_rewrite->set_permalink_structure('');
     621        }
     622
     623        /**
     624         * @ticket 5305
     625         */
     626        public function test_date_slug_collision_should_distinguish_pagination_from_date() {
     627                global $wp_rewrite;
     628                $wp_rewrite->init();
     629                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     630                $wp_rewrite->flush_rules();
     631
     632                $id = $this->factory->post->create( array(
     633                        'post_author'  => $this->author_id,
     634                        'post_status'  => 'publish',
     635                        'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3',
     636                        'post_title'   => '02',
     637                        'post_date'    => '2015-02-01 01:00:00',
     638                ) );
     639
     640                $this->go_to( get_permalink( $id ) . '1' );
     641
     642                $this->assertFalse( is_day() );
     643        }
     644
     645        /**
    473646         * @ticket 21013
    474647         */
    475648        function test_wp_unique_post_slug_with_non_latin_slugs() {