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

Yoast / wordpress-seo / f44229b0911ab3251ebf3aec976097d0ed682dee

24 Mar 2025 06:25PM UTC coverage: 48.68% (-0.03%) from 48.71%
f44229b0911ab3251ebf3aec976097d0ed682dee

push

github

web-flow
Merge pull request #22139 from Yoast/JRF/CSQA/remove-unused-use-statements

CS/QA: remove unused import use statements

16083 of 33038 relevant lines covered (48.68%)

3.61 hits per line

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

0.0
/src/integrations/front-end/feed-improvements.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
use Yoast\WP\SEO\Surfaces\Meta_Surface;
9

10
/**
11
 * Class Feed_Improvements
12
 */
13
class Feed_Improvements implements Integration_Interface {
14

15
        /**
16
         * Holds the options helper.
17
         *
18
         * @var Options_Helper
19
         */
20
        private $options;
21

22
        /**
23
         * Holds the meta helper surface.
24
         *
25
         * @var Meta_Surface
26
         */
27
        private $meta;
28

29
        /**
30
         * Canonical_Header constructor.
31
         *
32
         * @codeCoverageIgnore It only sets depedencies.
33
         *
34
         * @param Options_Helper $options The options helper.
35
         * @param Meta_Surface   $meta    The meta surface.
36
         */
37
        public function __construct( Options_Helper $options, Meta_Surface $meta ) {
38
                $this->options = $options;
39
                $this->meta    = $meta;
40
        }
41

42
        /**
43
         * Returns the conditionals based in which this loadable should be active.
44
         *
45
         * @return array
46
         */
47
        public static function get_conditionals() {
×
48
                return [ Front_End_Conditional::class ];
×
49
        }
50

51
        /**
52
         * Registers hooks to WordPress.
53
         *
54
         * @return void
55
         */
56
        public function register_hooks() {
×
57
                \add_filter( 'get_bloginfo_rss', [ $this, 'filter_bloginfo_rss' ], 10, 2 );
×
58
                \add_filter( 'document_title_separator', [ $this, 'filter_document_title_separator' ] );
×
59

60
                \add_action( 'do_feed_rss', [ $this, 'handle_rss_feed' ], 9 );
×
61
                \add_action( 'do_feed_rss2', [ $this, 'send_canonical_header' ], 9 );
×
62
                \add_action( 'do_feed_rss2', [ $this, 'add_robots_headers' ], 9 );
×
63
        }
64

65
        /**
66
         * Filter `bloginfo_rss` output to give the URL for what's being shown instead of just always the homepage.
67
         *
68
         * @param string $show The output so far.
69
         * @param string $what What is being shown.
70
         *
71
         * @return string
72
         */
73
        public function filter_bloginfo_rss( $show, $what ) {
×
74
                if ( $what === 'url' ) {
×
75
                        return $this->get_url_for_queried_object( $show );
×
76
                }
77

78
                return $show;
×
79
        }
80

81
        /**
82
         * Makes sure send canonical header always runs, because this RSS hook does not support the for_comments parameter
83
         *
84
         * @return void
85
         */
86
        public function handle_rss_feed() {
×
87
                $this->send_canonical_header( false );
×
88
        }
89

90
        /**
91
         * Adds a canonical link header to the main canonical URL for the requested feed object. If it is not a comment
92
         * feed.
93
         *
94
         * @param bool $for_comments If the RRS feed is meant for a comment feed.
95
         *
96
         * @return void
97
         */
98
        public function send_canonical_header( $for_comments ) {
×
99

100
                if ( $for_comments || \headers_sent() ) {
×
101
                        return;
×
102
                }
103

104
                $queried_object = \get_queried_object();
×
105
                // Don't call get_class with null. This gives a warning.
106
                $class = ( $queried_object !== null ) ? \get_class( $queried_object ) : null;
×
107

108
                $url = $this->get_url_for_queried_object( $this->meta->for_home_page()->canonical );
×
109
                if ( ( ! empty( $url ) && $url !== $this->meta->for_home_page()->canonical ) || $class === null ) {
×
110
                        \header( \sprintf( 'Link: <%s>; rel="canonical"', $url ), false );
×
111
                }
112
        }
113

114
        /**
115
         * Adds noindex, follow tag for comment feeds.
116
         *
117
         * @param bool $for_comments If the RSS feed is meant for a comment feed.
118
         *
119
         * @return void
120
         */
121
        public function add_robots_headers( $for_comments ) {
×
122
                if ( $for_comments && ! \headers_sent() ) {
×
123
                        \header( 'X-Robots-Tag: noindex, follow', true );
×
124
                }
125
        }
126

127
        /**
128
         * Makes sure the title separator set in Yoast SEO is used for all feeds.
129
         *
130
         * @param string $separator The separator from WordPress.
131
         *
132
         * @return string The separator from Yoast SEO's settings.
133
         */
134
        public function filter_document_title_separator( $separator ) {
×
135
                return \html_entity_decode( $this->options->get_title_separator() );
×
136
        }
137

138
        /**
139
         * Determines the main URL for the queried object.
140
         *
141
         * @param string $url The URL determined so far.
142
         *
143
         * @return string The canonical URL for the queried object.
144
         */
145
        protected function get_url_for_queried_object( $url = '' ) {
×
146
                $queried_object = \get_queried_object();
×
147
                // Don't call get_class with null. This gives a warning.
148
                $class = ( $queried_object !== null ) ? \get_class( $queried_object ) : null;
×
149
                $meta  = false;
×
150

151
                switch ( $class ) {
152
                        // Post type archive feeds.
153
                        case 'WP_Post_Type':
×
154
                                $meta = $this->meta->for_post_type_archive( $queried_object->name );
×
155
                                break;
×
156
                        // Post comment feeds.
157
                        case 'WP_Post':
×
158
                                $meta = $this->meta->for_post( $queried_object->ID );
×
159
                                break;
×
160
                        // Term feeds.
161
                        case 'WP_Term':
×
162
                                $meta = $this->meta->for_term( $queried_object->term_id );
×
163
                                break;
×
164
                        // Author feeds.
165
                        case 'WP_User':
×
166
                                $meta = $this->meta->for_author( $queried_object->ID );
×
167
                                break;
×
168
                        // This would be NULL on the home page and on date archive feeds.
169
                        case null:
170
                                $meta = $this->meta->for_home_page();
×
171
                                break;
×
172
                        default:
173
                                break;
×
174
                }
175

176
                if ( $meta ) {
×
177
                        return $meta->canonical;
×
178
                }
179

180
                return $url;
×
181
        }
182
}
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