• 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

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(
38
                Options_Helper $options,
39
                Meta_Surface $meta
40
        ) {
41
                $this->options = $options;
42
                $this->meta    = $meta;
43
        }
44

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

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

63
                \add_action( 'do_feed_rss', [ $this, 'handle_rss_feed' ], 9 );
×
64
                \add_action( 'do_feed_rss2', [ $this, 'send_canonical_header' ], 9 );
×
65
                \add_action( 'do_feed_rss2', [ $this, 'add_robots_headers' ], 9 );
×
66
        }
67

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

81
                return $show;
×
82
        }
83

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

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

103
                if ( $for_comments || \headers_sent() ) {
×
104
                        return;
×
105
                }
106

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

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

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

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

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

174
                return $url;
×
175
        }
176
}
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