• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / 7004843404

27 Nov 2023 11:48AM UTC coverage: 49.206% (-0.03%) from 49.232%
7004843404

push

github

web-flow
Merge pull request #20858 from Yoast/improve-copy-in-the-ftc-57

15305 of 31104 relevant lines covered (49.21%)

4.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

25.0
/src/integrations/front-end/crawl-cleanup-rss.php
1
<?php
2

3
namespace Yoast\WP\SEO\Integrations\Front_End;
4

5
use Yoast\WP\SEO\Conditionals\Front_End_Conditional;
6
use Yoast\WP\SEO\Helpers\Options_Helper;
7
use Yoast\WP\SEO\Integrations\Integration_Interface;
8

9
/**
10
 * Adds actions that cleanup unwanted rss feed links.
11
 */
12
class Crawl_Cleanup_Rss implements Integration_Interface {
13

14
        /**
15
         * The options helper.
16
         *
17
         * @var Options_Helper
18
         */
19
        private $options_helper;
20

21
        /**
22
         * Crawl Cleanup RSS integration constructor.
23
         *
24
         * @param Options_Helper $options_helper The option helper.
25
         */
26
        public function __construct( Options_Helper $options_helper ) {
×
27
                $this->options_helper = $options_helper;
×
28
        }
29

30
        /**
31
         * Returns the conditionals based on which this loadable should be active.
32
         *
33
         * @return array The conditionals.
34
         */
35
        public static function get_conditionals() {
2✔
36
                return [ Front_End_Conditional::class ];
2✔
37
        }
38

39
        /**
40
         * Register our RSS related hooks.
41
         */
42
        public function register_hooks() {
2✔
43
                if ( $this->is_true( 'remove_feed_global' ) ) {
2✔
44
                        \add_action( 'feed_links_show_posts_feed', '__return_false' );
2✔
45
                }
46

47
                if ( $this->is_true( 'remove_feed_global_comments' ) ) {
2✔
48
                        \add_action( 'feed_links_show_comments_feed', '__return_false' );
2✔
49
                }
50

51
                \add_action( 'wp', [ $this, 'maybe_disable_feeds' ] );
2✔
52
                \add_action( 'wp', [ $this, 'maybe_redirect_feeds' ], -10000 );
2✔
53
        }
1✔
54

55
        /**
56
         * Disable feeds on selected cases.
57
         */
58
        public function maybe_disable_feeds() {
8✔
59
                if ( \is_singular() && $this->is_true( 'remove_feed_post_comments' )
8✔
60
                        || ( \is_author() && $this->is_true( 'remove_feed_authors' ) )
6✔
61
                        || ( \is_category() && $this->is_true( 'remove_feed_categories' ) )
4✔
62
                        || ( \is_tag() && $this->is_true( 'remove_feed_tags' ) )
4✔
63
                        || ( \is_tax() && $this->is_true( 'remove_feed_custom_taxonomies' ) )
4✔
64
                        || ( \is_post_type_archive() && $this->is_true( 'remove_feed_post_types' ) )
4✔
65
                        || ( \is_search() && $this->is_true( 'remove_feed_search' ) ) ) {
8✔
66
                        \remove_action( 'wp_head', 'feed_links_extra', 3 );
4✔
67
                }
68
        }
4✔
69

70
        /**
71
         * Redirect feeds we don't want away.
72
         */
73
        public function maybe_redirect_feeds() {
×
74
                global $wp_query;
×
75

76
                if ( ! \is_feed() ) {
×
77
                        return;
×
78
                }
79

80
                if ( \in_array( \get_query_var( 'feed' ), [ 'atom', 'rdf' ], true ) && $this->is_true( 'remove_atom_rdf_feeds' ) ) {
×
81
                        $this->redirect_feed( \home_url(), 'We disable Atom/RDF feeds for performance reasons.' );
×
82
                }
83

84
                // Only if we're on the global feed, the query is _just_ `'feed' => 'feed'`, hence this check.
85
                if ( ( $wp_query->query === [ 'feed' => 'feed' ]
×
86
                        || $wp_query->query === [ 'feed' => 'atom' ]
×
87
                        || $wp_query->query === [ 'feed' => 'rdf' ] )
×
88
                        && $this->is_true( 'remove_feed_global' ) ) {
×
89
                        $this->redirect_feed( \home_url(), 'We disable the RSS feed for performance reasons.' );
×
90
                }
91

92
                if ( \is_comment_feed() && ! ( \is_singular() || \is_attachment() ) && $this->is_true( 'remove_feed_global_comments' ) ) {
×
93
                        $this->redirect_feed( \home_url(), 'We disable comment feeds for performance reasons.' );
×
94
                }
95
                elseif ( \is_comment_feed()
×
96
                                && \is_singular()
×
97
                                && ( $this->is_true( 'remove_feed_post_comments' ) || $this->is_true( 'remove_feed_global_comments' ) ) ) {
×
98
                        $url = \get_permalink( \get_queried_object() );
×
99
                        $this->redirect_feed( $url, 'We disable post comment feeds for performance reasons.' );
×
100
                }
101

102
                if ( \is_author() && $this->is_true( 'remove_feed_authors' ) ) {
×
103
                        $author_id = (int) \get_query_var( 'author' );
×
104
                        $url       = \get_author_posts_url( $author_id );
×
105
                        $this->redirect_feed( $url, 'We disable author feeds for performance reasons.' );
×
106
                }
107

108
                if ( ( \is_category() && $this->is_true( 'remove_feed_categories' ) )
×
109
                        || ( \is_tag() && $this->is_true( 'remove_feed_tags' ) )
×
110
                        || ( \is_tax() && $this->is_true( 'remove_feed_custom_taxonomies' ) ) ) {
×
111
                        $term = \get_queried_object();
×
112
                        $url  = \get_term_link( $term, $term->taxonomy );
×
113
                        if ( \is_wp_error( $url ) ) {
×
114
                                $url = \home_url();
×
115
                        }
116
                        $this->redirect_feed( $url, 'We disable taxonomy feeds for performance reasons.' );
×
117
                }
118

119
                if ( ( \is_post_type_archive() ) && $this->is_true( 'remove_feed_post_types' ) ) {
×
120
                        $url = \get_post_type_archive_link( $this->get_queried_post_type() );
×
121
                        $this->redirect_feed( $url, 'We disable post type feeds for performance reasons.' );
×
122
                }
123

124
                if ( \is_search() && $this->is_true( 'remove_feed_search' ) ) {
×
125
                        $url = \trailingslashit( \home_url() ) . '?s=' . \get_search_query();
×
126
                        $this->redirect_feed( $url, 'We disable search RSS feeds for performance reasons.' );
×
127
                }
128
        }
129

130
        /**
131
         * Sends a cache control header.
132
         *
133
         * @param int $expiration The expiration time.
134
         */
135
        public function cache_control_header( $expiration ) {
×
136
                \header_remove( 'Expires' );
×
137

138
                // The cacheability of the current request. 'public' allows caching, 'private' would not allow caching by proxies like CloudFlare.
139
                $cacheability = 'public';
×
140
                $format       = '%1$s, max-age=%2$d, s-maxage=%2$d, stale-while-revalidate=120, stale-if-error=14400';
×
141

142
                if ( \is_user_logged_in() ) {
×
143
                        $expiration   = 0;
×
144
                        $cacheability = 'private';
×
145
                        $format       = '%1$s, max-age=%2$d';
×
146
                }
147

148
                \header( \sprintf( 'Cache-Control: ' . $format, $cacheability, $expiration ), true );
×
149
        }
150

151
        /**
152
         * Redirect a feed result to somewhere else.
153
         *
154
         * @param string $url    The location we're redirecting to.
155
         * @param string $reason The reason we're redirecting.
156
         */
157
        private function redirect_feed( $url, $reason ) {
×
158
                \header_remove( 'Content-Type' );
×
159
                \header_remove( 'Last-Modified' );
×
160

161
                $this->cache_control_header( 7 * \DAY_IN_SECONDS );
×
162

163
                \wp_safe_redirect( $url, 301, 'Yoast SEO: ' . $reason );
×
164
                exit;
×
165
        }
166

167
        /**
168
         * Retrieves the queried post type.
169
         *
170
         * @return string The queried post type.
171
         */
172
        private function get_queried_post_type() {
×
173
                $post_type = \get_query_var( 'post_type' );
×
174
                if ( \is_array( $post_type ) ) {
×
175
                        $post_type = \reset( $post_type );
×
176
                }
177
                return $post_type;
×
178
        }
179

180
        /**
181
         * Checks if the value of an option is set to true.
182
         *
183
         * @param string $option_name The option name.
184
         *
185
         * @return bool
186
         */
187
        private function is_true( $option_name ) {
×
188
                return $this->options_helper->get( $option_name ) === true;
×
189
        }
190
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc