Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
16.67% covered (danger)
16.67%
5 / 30
50.00% covered (danger)
50.00%
1 / 2
CRAP
n/a
0 / 0
jetpack_canonical_urls_check_conflicts
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
30
jetpack_canonical_urls_output_tag
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2/**
3 * Module Name: Canonical URLs
4 * Module Description: Add canonical URL tags to archive pages to prevent duplicate content in search engines.
5 * Sort Order: 36
6 * First Introduced: 15.6
7 * Requires Connection: No
8 * Requires User Connection: No
9 * Auto Activate: No
10 * Module Tags: Traffic
11 * Feature: Traffic
12 * Additional Search Queries: canonical, seo, duplicate content, woocommerce, archive
13 *
14 * @package automattic/jetpack
15 */
16
17if ( ! defined( 'ABSPATH' ) ) {
18    exit( 0 );
19}
20
21// Disable canonical URL output when a conflicting SEO plugin is active.
22add_filter( 'jetpack_disable_canonical_urls', 'jetpack_canonical_urls_check_conflicts' );
23
24/**
25 * Can be used to prevent the Canonical URLs module from outputting canonical tags.
26 *
27 * @module canonical-urls
28 *
29 * @since 15.6
30 *
31 * @param bool $disabled Whether canonical URL output is disabled. Defaults to false.
32 */
33if ( ! apply_filters( 'jetpack_disable_canonical_urls', false ) ) {
34    require_once __DIR__ . '/canonical-urls/class-jetpack-canonical-urls-resolver.php';
35    add_action( 'wp_head', 'jetpack_canonical_urls_output_tag' );
36}
37
38/**
39 * Check if a conflicting SEO plugin is active and disable canonical URL output.
40 *
41 * @since 15.6
42 *
43 * @param bool $disabled Whether canonical URL output is already disabled.
44 * @return bool Whether canonical URL output should be disabled.
45 */
46function jetpack_canonical_urls_check_conflicts( $disabled ) {
47    // WordPress.com Simple's stub Jetpack class lacks this method, and Simple runs no plugins.
48    if ( $disabled || ! method_exists( 'Jetpack', 'is_plugin_active' ) ) {
49        return $disabled;
50    }
51
52    $conflicting_plugins = array(
53        'wordpress-seo/wp-seo.php',
54        'wordpress-seo-premium/wp-seo-premium.php',
55        'all-in-one-seo-pack/all_in_one_seo_pack.php',
56        'all-in-one-seo-pack-pro/all_in_one_seo_pack.php',
57        'seo-by-rank-math/rank-math.php',
58        'autodescription/autodescription.php',
59        'slim-seo/slim-seo.php',
60        'wp-seopress/seopress.php',
61        'wp-seopress-pro/seopress-pro.php',
62        'seo-key/seo-key.php',
63        'seo-key-pro/seo-key.php',
64    );
65
66    foreach ( $conflicting_plugins as $plugin ) {
67        if ( Jetpack::is_plugin_active( $plugin ) ) {
68            return true;
69        }
70    }
71
72    return $disabled;
73}
74
75/**
76 * Output the canonical link tag for non-singular pages.
77 *
78 * WordPress core handles singular posts/pages via rel_canonical(),
79 * so this function only outputs canonical tags for archive pages.
80 *
81 * @since 15.6
82 */
83function jetpack_canonical_urls_output_tag() {
84    if ( is_singular() ) {
85        return;
86    }
87
88    $url = Jetpack_Canonical_Urls_Resolver::get_canonical_url();
89
90    if ( ! empty( $url ) ) {
91        echo '<link rel="canonical" href="' . esc_url( $url ) . '" />' . "\n";
92    }
93}