WordPress.org

Make WordPress Core

Ticket #5305: 5305.8.diff

File 5305.8.diff, 10.3 KB (added by valendesigns, 5 years ago)
  • src/wp-includes/query.php

    diff --git src/wp-includes/query.php src/wp-includes/query.php
    index f076533..5cdf07e 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         * @access protected
     2330         */
     2331        protected function resolve_numeric_slugs() {
     2332                if ( ! $this->is_date ) {
     2333                        return;
     2334                }
     2335
     2336                // Identify the 'postname' position in the permastruct array.
     2337                $permastructs = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
     2338
     2339                $postname_index = array_search( '%postname%', $permastructs );
     2340
     2341                if ( false === $postname_index ) {
     2342                        return;
     2343                }
     2344
     2345                /*
     2346                 * A numeric slug could be confused with a year, month, or day, depending on position.
     2347                 * To account for the possibility of post pagination (eg 2015/2 for the second page of a post called
     2348                 * '2015'), our `is_*` checks are generous: check for year-slug clashes when `is_year` *or* `is_month`,
     2349                 * and check for month-slug clashes when `is_month` *or* `is_day`.
     2350                 */
     2351                $compare = '';
     2352                if ( 0 === $postname_index && ( $this->is_year || $this->is_month ) ) {
     2353                        $compare = 'year';
     2354                } else if ( '%year%' === $permastructs[ $postname_index - 1 ] && ( $this->is_month || $this->is_day ) ) {
     2355                        $compare = 'monthnum';
     2356                } else if ( '%monthnum%' === $permastructs[ $postname_index - 1 ] && $this->is_day ) {
     2357                        $compare = 'day';
     2358                }
     2359
     2360                if ( ! $compare ) {
     2361                        return;
     2362                }
     2363
     2364                // Set the value of the numeric slug
     2365                $value = $this->get( $compare );
     2366
     2367                // Check the original query var for a leading zero and zeroise `$value` if needed.
     2368                if ( 'year' !== $compare ) {
     2369                        if ( isset( $this->query[ $compare ] ) && substr( $this->query[ $compare ], 0, 1 ) === '0' ) {
     2370                                $value = zeroise( $value, 2 );
     2371                        }
     2372                }
     2373
     2374                $post = get_page_by_path( $value, OBJECT, 'post' );
     2375                if ( ! ( $post instanceof WP_Post ) ) {
     2376                        return;
     2377                }
     2378
     2379                // Set the page value
     2380                $page = '';
     2381                if ( 'year' === $compare && $this->is_month ) {
     2382                        $page = $this->get( 'monthnum' );
     2383                } else if ( 'monthnum' === $compare && $this->is_day ) {
     2384                        $page = $this->get( 'day' );
     2385                }
     2386
     2387                // If the page is not valid, bail!
     2388                if ( '' !== $page && false !== strpos( $post->post_content, '<!--nextpage-->' ) && ( $page - 1 ) > substr_count( $post->post_content, '<!--nextpage-->' ) ) {
     2389                        return;
     2390                }
     2391
     2392                /*
     2393                 * If we've gotten to this point, we have a slug/date clash.
     2394                 * First, attempt to adjust pagination, which would have previously been identified as
     2395                 * part of the date query.
     2396                 */
     2397                if ( '' !== $page ) {
     2398                        $this->set( 'page', $page );
     2399                }
     2400
     2401                // Next, unset autodetected date-related query vars.
     2402                $this->is_archive = false;
     2403                $this->is_date    = false;
     2404                $this->is_year    = false;
     2405                $this->is_month   = false;
     2406                $this->is_day     = false;
     2407                $this->set( 'year', '' );
     2408                $this->set( 'monthnum', '' );
     2409                $this->set( 'day', '' );
     2410
     2411                // Finally, tell the query that it's a singular query for the identified post.
     2412                $this->is_single   = true;
     2413                $this->is_singular = true;
     2414                $this->set( 'name', $post->post_name );
     2415        }
     2416
     2417        /**
    23242418         * Sets the 404 property and saves whether query is feed.
    23252419         *
    23262420         * @since 2.0.0
  • tests/phpunit/tests/post.php

    diff --git tests/phpunit/tests/post.php tests/phpunit/tests/post.php
    index ae549e0..7ebf18e 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_without_title_no_leading_zero() {
     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'   => '',
     568                        'post_name'    => '2',
     569                        'post_date'    => '2015-02-01 01:00:00',
     570                ) );
     571
     572                $this->go_to( get_permalink( $id ) );
     573
     574                $this->assertQueryTrue( 'is_single', 'is_singular' );
     575
     576                $wp_rewrite->set_permalink_structure('');
     577        }
     578
     579        /**
     580         * @ticket 5305
     581         */
     582        function test_permalink_month_segment_collision_with_title() {
     583                global $wp_rewrite;
     584                $wp_rewrite->init();
     585                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     586                $wp_rewrite->flush_rules();
     587
     588                $id = $this->factory->post->create( array(
     589                        'post_author'  => $this->author_id,
     590                        'post_status'  => 'publish',
     591                        'post_content' => rand_str(),
     592                        'post_title'   => '02',
     593                        'post_date'    => '2015-02-01 01:00:00',
     594                ) );
     595
     596                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     597
     598                $wp_rewrite->set_permalink_structure('');
     599        }
     600       
     601        /**
     602         * @ticket 5305
     603         */
     604        function test_permalink_month_segment_collision_with_title_no_leading_zero() {
     605                global $wp_rewrite;
     606                $wp_rewrite->init();
     607                $wp_rewrite->set_permalink_structure( '/%year%/%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'   => '2',
     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        function test_permalink_day_segment_collision_without_title() {
     627                global $wp_rewrite;
     628                $wp_rewrite->init();
     629                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%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' => rand_str(),
     636                        'post_title'   => '',
     637                        'post_name'    => '01',
     638                        'post_date'    => '2015-02-01 01:00:00',
     639                ) );
     640
     641                $this->go_to( get_permalink( $id ) );
     642
     643                $this->assertQueryTrue( 'is_single', 'is_singular' );
     644
     645                $wp_rewrite->set_permalink_structure('');
     646        }
     647
     648        /**
     649         * @ticket 5305
     650         */
     651        function test_permalink_day_segment_collision_with_title() {
     652                global $wp_rewrite;
     653                $wp_rewrite->init();
     654                $wp_rewrite->set_permalink_structure( '/%year%/%monthnum%/%postname%/' );
     655                $wp_rewrite->flush_rules();
     656
     657                $id = $this->factory->post->create( array(
     658                        'post_author'  => $this->author_id,
     659                        'post_status'  => 'publish',
     660                        'post_content' => rand_str(),
     661                        'post_title'   => '01',
     662                        'post_date'    => '2015-02-01 01:00:00',
     663                ) );
     664
     665                $this->assertEquals( $id, url_to_postid( get_permalink( $id ) ) );
     666
     667                $wp_rewrite->set_permalink_structure('');
     668        }
     669
     670        /**
     671         * @ticket 5305
     672         */
     673        public function test_date_slug_collision_should_distinguish_valid_pagination_from_date() {
     674                global $wp_rewrite;
     675                $wp_rewrite->init();
     676                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     677                $wp_rewrite->flush_rules();
     678
     679                $id = $this->factory->post->create( array(
     680                        'post_author'  => $this->author_id,
     681                        'post_status'  => 'publish',
     682                        'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3',
     683                        'post_title'   => '02',
     684                        'post_date'    => '2015-02-01 01:00:00',
     685                ) );
     686
     687                $this->go_to( get_permalink( $id ) . '1' );
     688
     689                $this->assertFalse( is_day() );
     690        }
     691       
     692        /**
     693         * @ticket 5305
     694         */
     695        public function test_date_slug_collision_should_distinguish_invalid_pagination_from_date() {
     696                global $wp_rewrite;
     697                $wp_rewrite->init();
     698                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     699                $wp_rewrite->flush_rules();
     700
     701                $id = $this->factory->post->create( array(
     702                        'post_author'  => $this->author_id,
     703                        'post_status'  => 'publish',
     704                        'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3',
     705                        'post_title'   => '02',
     706                        'post_date'    => '2015-02-05 01:00:00',
     707                ) );
     708               
     709                $this->go_to( get_permalink( $id ) . '5' );
     710
     711                $this->assertTrue( is_day() );
     712        }
     713
     714        /**
    473715         * @ticket 21013
    474716         */
    475717        function test_wp_unique_post_slug_with_non_latin_slugs() {