WordPress.org

Make WordPress Core

Ticket #36168: 36168-get_canonical-2.diff

File 36168-get_canonical-2.diff, 6.3 KB (added by jipmoors, 4 years ago)

Fixed apply_filters and added tests

  • src/wp-includes/link-template.php

     
    106106}
    107107
    108108/**
     109 * Retrieves the canonical URL for current post or post ID.
     110 *
     111 * @since
     112 *
     113 * @param int|WP_Post $post Optional. Post ID or post object. Default is the global `$post`.
     114 *
     115 * @return false|string The canonical URL or false if the post does not exist or has not been published yet.
     116 */
     117function get_canonical_url( $post = 0 ) {
     118        $post = get_post( $post );
     119       
     120        if ( ! is_object( $post ) ) {
     121                return false;
     122        }
     123
     124        if ( 'publish' !== $post->post_status ) {
     125                return false;
     126        }
     127
     128        $canonical_url = get_permalink( $post, false );
     129
     130        // If we're generating a canonical for the current page, make sure it has pagination if needed.
     131        if ( $post->ID === get_queried_object_id() ) {
     132                $page = get_query_var( 'page', 0 );
     133                if ( $page >= 2 ) {
     134                        if ( '' == get_option( 'permalink_structure' ) ) {
     135                                $canonical_url = add_query_arg( 'page', $page, $canonical_url );
     136                        } else {
     137                                $canonical_url = trailingslashit( $canonical_url ) . user_trailingslashit( $page, 'single_paged' );
     138                        }
     139                }
     140
     141                $cpage = get_query_var( 'cpage' );
     142                if ( $cpage ) {
     143                        $canonical_url = get_comments_pagenum_link( $cpage );
     144                }
     145        }
     146
     147        /**
     148         * Filter the canonical URL.
     149         *
     150         * @since
     151         *
     152         * @param string $string Canonical URL.
     153         * @param WP_Post $post  Post object. Default is the global `$post`.
     154         */
     155        return apply_filters( 'get_canonical_url', $canonical_url, $post );
     156}
     157
     158/**
    109159 * Retrieve full permalink for current post or post ID.
    110160 *
    111161 * @since 1.0.0
     
    35113561                return;
    35123562        }
    35133563
    3514         if ( ! $id = get_queried_object_id() ) {
     3564        $id = get_queried_object_id();
     3565        if ( 0 === $id ) {
    35153566                return;
    35163567        }
    35173568
    3518         $url = get_permalink( $id );
    3519 
    3520         $page = get_query_var( 'page' );
    3521         if ( $page >= 2 ) {
    3522                 if ( '' == get_option( 'permalink_structure' ) ) {
    3523                         $url = add_query_arg( 'page', $page, $url );
    3524                 } else {
    3525                         $url = trailingslashit( $url ) . user_trailingslashit( $page, 'single_paged' );
    3526                 }
     3569        $url = get_canonical_url( $id );
     3570        if ( ! empty( $url ) && is_string( $url ) ) {
     3571                echo '<link rel="canonical" href="' . esc_url( $url ) . '" />' . "\n";
    35273572        }
    3528 
    3529         $cpage = get_query_var( 'cpage' );
    3530         if ( $cpage ) {
    3531                 $url = get_comments_pagenum_link( $cpage );
    3532         }
    3533         echo '<link rel="canonical" href="' . esc_url( $url ) . "\" />\n";
    35343573}
    35353574
    35363575/**
  • tests/phpunit/tests/canonical/getCanonicalURL.php

     
     1<?php
     2
     3/**
     4 * @group canonical
     5 */
     6
     7class Tests_Get_Canonical_URL extends WP_UnitTestCase {
     8
     9        /**
     10         * Cleaning up
     11         */
     12        public function tearDown() {
     13                parent::tearDown();
     14
     15                delete_option('permalink_structure');
     16
     17                remove_filter( 'get_canonical_url', array($this, 'apply_canonical_filter' ) );
     18        }
     19
     20        /**
     21         * Test for a non existing post
     22         */
     23        public function test_non_existing_post() {
     24                $subject = get_canonical_url(1);
     25               
     26                $this->assertFalse( $subject );
     27        }
     28
     29        /**
     30         * Test for a page that is not published
     31         */
     32        public function test_post_status() {
     33                $post = new stdClass();
     34                $post->post_status = 'draft';
     35               
     36                $subject = get_canonical_url( $post );
     37               
     38                $this->assertFalse( $subject );
     39        }
     40
     41        /**
     42         * Test for a page that is not the queried object
     43         */
     44        public function test_non_current_page() {
     45                $post_id = self::factory()->post->create( array(
     46                        'post_status' => 'publish',
     47                ) );
     48               
     49                $subject = get_canonical_url( $post_id );
     50                $this->assertEquals( get_permalink( $post_id ), $subject );
     51        }
     52
     53        /**
     54         * Test non permalink structure page usage
     55         */
     56        public function test_paged() {
     57                global $wp_query;
     58               
     59                $page = 2;
     60                $post_id = self::factory()->post->create( array(
     61                        'post_status' => 'publish',
     62                ) );
     63               
     64                // Should add page to the URL.
     65                $wp_query->query_vars['page'] = $page;
     66
     67                // Set up queried object.
     68                $wp_query->queried_object = get_post($post_id);
     69                $wp_query->queried_object_id = $post_id;
     70               
     71                $url = get_permalink( $post_id );
     72                $test = add_query_arg( 'page', $page, $url );
     73               
     74                $subject = get_canonical_url( $post_id );
     75               
     76                $this->assertEquals( $test, $subject );
     77        }
     78
     79        /**
     80         * Test permalink structure page usage
     81         */
     82        public function test_paged_permalink_structure() {
     83                global $wp_query;
     84               
     85                update_option('permalink_structure', '1');
     86               
     87                $page = 2;
     88                $post_id = self::factory()->post->create( array(
     89                        'post_status' => 'publish',
     90                ) );
     91
     92                // Should add page to the URL.
     93                $wp_query->query_vars['page'] = $page;
     94               
     95                // Set up queried object.
     96                $wp_query->queried_object = get_post($post_id);
     97                $wp_query->queried_object_id = $post_id;
     98
     99                $url = get_permalink( $post_id );
     100                $test = trailingslashit( $url ) . user_trailingslashit( $page, 'single_paged' );
     101               
     102                $subject = get_canonical_url( $post_id );
     103               
     104                $this->assertEquals( $test, $subject );
     105        }
     106
     107        /**
     108         * Test usage of cpage
     109         */
     110        public function test_cpage() {
     111                global $wp_query;
     112               
     113                $cpage = 1;
     114
     115                $post_id = self::factory()->post->create( array(
     116                        'post_status' => 'publish',
     117                ) );
     118               
     119                // Set cpage value.
     120                $wp_query->query_vars['cpage'] = $cpage;
     121
     122                // Set up queried object.
     123                $wp_query->queried_object = get_post($post_id);
     124                $wp_query->queried_object_id = $post_id;
     125               
     126                $subject = get_canonical_url( $post_id );
     127               
     128                $this->assertEquals( get_comments_pagenum_link( $cpage ), $subject );
     129        }
     130
     131        /**
     132         * Test calling of filter
     133         */
     134        public function test_filter_applied() {
     135                $post_id = self::factory()->post->create( array(
     136                        'post_status' => 'publish',
     137                ) );
     138
     139                // Apply filter
     140                add_filter( 'get_canonical_url', array($this, 'apply_canonical_filter' ), 10, 2 );
     141               
     142                $subject = get_canonical_url( $post_id );
     143
     144                $this->assertEquals( $this->apply_canonical_filter( get_permalink( $post_id ), get_post( $post_id ) ), $subject );
     145        }
     146
     147        /**
     148         * Filter callback for testing of filter usage
     149         *
     150         * @param $url
     151         * @param $post
     152         *
     153         * @return string
     154         */
     155        public function apply_canonical_filter( $url, $post ) {
     156                return 'http://filtered.canonical.com';
     157        }
     158}