WordPress.org

Make WordPress Core

Ticket #5305: 5305.9.diff

File 5305.9.diff, 12.0 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..c0c5a9d 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         * Resolve 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                /*
     2368                 * 'day' and 'monthnum' values are cast to integers, which strips leading zeroes.
     2369                 * If we detect that the value originally passed to the query had a leading zero, re-add it to avoid
     2370                 * the potential of false slug matches.
     2371                 */
     2372                if ( 'year' !== $compare && isset( $this->query[ $compare ] ) && '0' === substr( $this->query[ $compare ], 0, 1 ) ) {
     2373                        $value = zeroise( $value, 2 );
     2374                }
     2375
     2376                $post = get_page_by_path( $value, OBJECT, 'post' );
     2377                if ( ! ( $post instanceof WP_Post ) ) {
     2378                        return;
     2379                }
     2380
     2381                /*
     2382                 * If the located post contains nextpage pagination, then the URL chunk following postname may be
     2383                 * intended as the page number. Verify that it's a valid page before resolving to it.
     2384                 */
     2385                $maybe_page = '';
     2386                if ( 'year' === $compare && $this->is_month ) {
     2387                        $maybe_page = $this->get( 'monthnum' );
     2388                } else if ( 'monthnum' === $compare && $this->is_day ) {
     2389                        $maybe_page = $this->get( 'day' );
     2390                }
     2391
     2392                $post_page_count = substr_count( $post->post_content, '<!--nextpage-->' ) + 1;
     2393
     2394                // If the post does not have pages, but a 'page' candidate is found, resolve to the date archive.
     2395                if ( 1 === $post_page_count && $maybe_page ) {
     2396                        return;
     2397                }
     2398
     2399                // If the post has pages and the 'page' candidate is not a valid page, resolve to the date archive.
     2400                if ( $post_page_count > 1 && $maybe_page > $post_page_count ) {
     2401                        return;
     2402                }
     2403
     2404                // If we've gotten to this point, we have a slug/date clash. First, adjust pagination.
     2405                if ( '' !== $maybe_page ) {
     2406                        $this->set( 'page', $maybe_page );
     2407                }
     2408
     2409                // Next, unset autodetected date-related query vars.
     2410                $this->is_archive = false;
     2411                $this->is_date    = false;
     2412                $this->is_year    = false;
     2413                $this->is_month   = false;
     2414                $this->is_day     = false;
     2415                $this->set( 'year', '' );
     2416                $this->set( 'monthnum', '' );
     2417                $this->set( 'day', '' );
     2418
     2419                // Finally, tell the query that it's a singular query for the identified post.
     2420                $this->is_single   = true;
     2421                $this->is_singular = true;
     2422                $this->set( 'name', $post->post_name );
     2423        }
     2424
     2425        /**
    23242426         * Sets the 404 property and saves whether query is feed.
    23252427         *
    23262428         * @since 2.0.0
  • tests/phpunit/tests/post.php

    diff --git tests/phpunit/tests/post.php tests/phpunit/tests/post.php
    index ae549e0..6b0f66b 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_too_high_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        /**
     715         * @ticket 5305
     716         */
     717        public function test_date_slug_collision_should_not_require_pagination_query_var() {
     718                global $wp_rewrite;
     719                $wp_rewrite->init();
     720                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     721                $wp_rewrite->flush_rules();
     722
     723                $id = $this->factory->post->create( array(
     724                        'post_author'  => $this->author_id,
     725                        'post_status'  => 'publish',
     726                        'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3',
     727                        'post_title'   => '02',
     728                        'post_date'    => '2015-02-05 01:00:00',
     729                ) );
     730
     731                $this->go_to( get_permalink( $id ) );
     732
     733                $this->assertQueryTrue( 'is_single', 'is_singular' );
     734                $this->assertFalse( is_date() );
     735        }
     736
     737        /**
     738         * @ticket 5305
     739         */
     740        public function test_date_slug_collision_should_be_ignored_when_pagination_var_is_present_but_post_does_not_have_multiple_pages() {
     741                global $wp_rewrite;
     742                $wp_rewrite->init();
     743                $wp_rewrite->set_permalink_structure( '/%year%/%postname%/' );
     744                $wp_rewrite->flush_rules();
     745
     746                $id = $this->factory->post->create( array(
     747                        'post_author'  => $this->author_id,
     748                        'post_status'  => 'publish',
     749                        'post_content' => 'This post does not have pagination.',
     750                        'post_title'   => '02',
     751                        'post_date'    => '2015-02-05 01:00:00',
     752                ) );
     753
     754                $this->go_to( get_permalink( $id ) . '5' );
     755
     756                $this->assertTrue( is_day() );
     757        }
     758
     759        /**
    473760         * @ticket 21013
    474761         */
    475762        function test_wp_unique_post_slug_with_non_latin_slugs() {