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

Yoast / wordpress-seo / dd6e866a9e6d253114633104d9e3858d807178ba

19 Jun 2024 10:03AM UTC coverage: 48.628% (-4.3%) from 52.936%
dd6e866a9e6d253114633104d9e3858d807178ba

push

github

web-flow
Merge pull request #21431 from Yoast/21429-update-copy-in-the-introduction-and-consent-modals

Updates the copy for the introduction and consent modals

7441 of 13454 branches covered (55.31%)

Branch coverage included in aggregate %.

0 of 3 new or added lines in 2 files covered. (0.0%)

3718 existing lines in 107 files now uncovered.

25100 of 53464 relevant lines covered (46.95%)

62392.47 hits per line

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

0.0
/inc/sitemaps/class-taxonomy-sitemap-provider.php
1
<?php
2
/**
3
 * WPSEO plugin file.
4
 *
5
 * @package WPSEO\XML_Sitemaps
6
 */
7

8
/**
9
 * Sitemap provider for author archives.
10
 */
11
class WPSEO_Taxonomy_Sitemap_Provider implements WPSEO_Sitemap_Provider {
12

13
        /**
14
         * Holds image parser instance.
15
         *
16
         * @var WPSEO_Sitemap_Image_Parser
17
         */
18
        protected static $image_parser;
19

20
        /**
21
         * Determines whether images should be included in the XML sitemap.
22
         *
23
         * @var bool
24
         */
25
        private $include_images;
26

27
        /**
28
         * Set up object properties for data reuse.
29
         */
30
        public function __construct() {
×
31
                /**
32
                 * Filter - Allows excluding images from the XML sitemap.
33
                 *
34
                 * @param bool $include True to include, false to exclude.
35
                 */
36
                $this->include_images = apply_filters( 'wpseo_xml_sitemap_include_images', true );
×
37
        }
38

39
        /**
40
         * Check if provider supports given item type.
41
         *
42
         * @param string $type Type string to check for.
43
         *
44
         * @return bool
45
         */
46
        public function handles_type( $type ) {
×
47

48
                $taxonomy = get_taxonomy( $type );
×
49

50
                if ( $taxonomy === false || ! $this->is_valid_taxonomy( $taxonomy->name ) || ! $taxonomy->public ) {
×
51
                        return false;
×
52
                }
53

54
                return true;
×
55
        }
56

57
        /**
58
         * Retrieves the links for the sitemap.
59
         *
60
         * @param int $max_entries Entries per sitemap.
61
         *
62
         * @return array
63
         */
UNCOV
64
        public function get_index_links( $max_entries ) {
×
65

UNCOV
66
                $taxonomies = get_taxonomies( [ 'public' => true ], 'objects' );
×
67

UNCOV
68
                if ( empty( $taxonomies ) ) {
×
69
                        return [];
×
70
                }
71

UNCOV
72
                $taxonomy_names = array_filter( array_keys( $taxonomies ), [ $this, 'is_valid_taxonomy' ] );
×
UNCOV
73
                $taxonomies     = array_intersect_key( $taxonomies, array_flip( $taxonomy_names ) );
×
74

75
                // Retrieve all the taxonomies and their terms so we can do a proper count on them.
76

77
                /**
78
                 * Filter the setting of excluding empty terms from the XML sitemap.
79
                 *
80
                 * @param bool  $exclude        Defaults to true.
81
                 * @param array $taxonomy_names Array of names for the taxonomies being processed.
82
                 */
UNCOV
83
                $hide_empty = apply_filters( 'wpseo_sitemap_exclude_empty_terms', true, $taxonomy_names );
×
84

UNCOV
85
                $all_taxonomies = [];
×
86

UNCOV
87
                foreach ( $taxonomy_names as $taxonomy_name ) {
×
88
                        /**
89
                         * Filter the setting of excluding empty terms from the XML sitemap for a specific taxonomy.
90
                         *
91
                         * @param bool   $exclude       Defaults to the sitewide setting.
92
                         * @param string $taxonomy_name The name of the taxonomy being processed.
93
                         */
UNCOV
94
                        $hide_empty_tax = apply_filters( 'wpseo_sitemap_exclude_empty_terms_taxonomy', $hide_empty, $taxonomy_name );
×
95

UNCOV
96
                        $term_args      = [
×
UNCOV
97
                                'taxonomy'   => $taxonomy_name,
×
UNCOV
98
                                'hide_empty' => $hide_empty_tax,
×
UNCOV
99
                                'fields'     => 'ids',
×
UNCOV
100
                        ];
×
UNCOV
101
                        $taxonomy_terms = get_terms( $term_args );
×
102

UNCOV
103
                        if ( count( $taxonomy_terms ) > 0 ) {
×
UNCOV
104
                                $all_taxonomies[ $taxonomy_name ] = $taxonomy_terms;
×
105
                        }
106
                }
107

UNCOV
108
                $index = [];
×
109

UNCOV
110
                foreach ( $taxonomies as $tax_name => $tax ) {
×
111

UNCOV
112
                        if ( ! isset( $all_taxonomies[ $tax_name ] ) ) { // No eligible terms found.
×
UNCOV
113
                                continue;
×
114
                        }
115

UNCOV
116
                        $total_count = ( isset( $all_taxonomies[ $tax_name ] ) ) ? count( $all_taxonomies[ $tax_name ] ) : 1;
×
UNCOV
117
                        $max_pages   = 1;
×
118

UNCOV
119
                        if ( $total_count > $max_entries ) {
×
UNCOV
120
                                $max_pages = (int) ceil( $total_count / $max_entries );
×
121
                        }
122

UNCOV
123
                        $last_modified_gmt = WPSEO_Sitemaps::get_last_modified_gmt( $tax->object_type );
×
124

UNCOV
125
                        for ( $page_counter = 0; $page_counter < $max_pages; $page_counter++ ) {
×
126

UNCOV
127
                                $current_page = ( $page_counter === 0 ) ? '' : ( $page_counter + 1 );
×
128

UNCOV
129
                                if ( ! is_array( $tax->object_type ) || count( $tax->object_type ) === 0 ) {
×
130
                                        continue;
×
131
                                }
132

UNCOV
133
                                $terms = array_splice( $all_taxonomies[ $tax_name ], 0, $max_entries );
×
134

UNCOV
135
                                if ( ! $terms ) {
×
136
                                        continue;
×
137
                                }
138

UNCOV
139
                                $args  = [
×
UNCOV
140
                                        'post_type'      => $tax->object_type,
×
UNCOV
141
                                        'tax_query'      => [
×
UNCOV
142
                                                [
×
UNCOV
143
                                                        'taxonomy' => $tax_name,
×
UNCOV
144
                                                        'terms'    => $terms,
×
UNCOV
145
                                                ],
×
UNCOV
146
                                        ],
×
UNCOV
147
                                        'orderby'        => 'modified',
×
UNCOV
148
                                        'order'          => 'DESC',
×
UNCOV
149
                                        'posts_per_page' => 1,
×
UNCOV
150
                                ];
×
UNCOV
151
                                $query = new WP_Query( $args );
×
152

UNCOV
153
                                if ( $query->have_posts() ) {
×
UNCOV
154
                                        $date = $query->posts[0]->post_modified_gmt;
×
155
                                }
156
                                else {
157
                                        $date = $last_modified_gmt;
×
158
                                }
159

UNCOV
160
                                $index[] = [
×
UNCOV
161
                                        'loc'     => WPSEO_Sitemaps_Router::get_base_url( $tax_name . '-sitemap' . $current_page . '.xml' ),
×
UNCOV
162
                                        'lastmod' => $date,
×
UNCOV
163
                                ];
×
164
                        }
165
                }
166

UNCOV
167
                return $index;
×
168
        }
169

170
        /**
171
         * Get set of sitemap link data.
172
         *
173
         * @param string $type         Sitemap type.
174
         * @param int    $max_entries  Entries per sitemap.
175
         * @param int    $current_page Current page of the sitemap.
176
         *
177
         * @return array
178
         *
179
         * @throws OutOfBoundsException When an invalid page is requested.
180
         */
UNCOV
181
        public function get_sitemap_links( $type, $max_entries, $current_page ) {
×
UNCOV
182
                global $wpdb;
×
183

UNCOV
184
                $links = [];
×
UNCOV
185
                if ( ! $this->handles_type( $type ) ) {
×
186
                        return $links;
×
187
                }
188

UNCOV
189
                $taxonomy = get_taxonomy( $type );
×
190

UNCOV
191
                $steps  = $max_entries;
×
UNCOV
192
                $offset = ( $current_page > 1 ) ? ( ( $current_page - 1 ) * $max_entries ) : 0;
×
193

194
                /** This filter is documented in inc/sitemaps/class-taxonomy-sitemap-provider.php */
UNCOV
195
                $hide_empty = apply_filters( 'wpseo_sitemap_exclude_empty_terms', true, [ $taxonomy->name ] );
×
196
                /** This filter is documented in inc/sitemaps/class-taxonomy-sitemap-provider.php */
UNCOV
197
                $hide_empty_tax = apply_filters( 'wpseo_sitemap_exclude_empty_terms_taxonomy', $hide_empty, $taxonomy->name );
×
UNCOV
198
                $terms          = get_terms(
×
UNCOV
199
                        [
×
UNCOV
200
                                'taxonomy'               => $taxonomy->name,
×
UNCOV
201
                                'hide_empty'             => $hide_empty_tax,
×
UNCOV
202
                                'update_term_meta_cache' => false,
×
UNCOV
203
                                'offset'                 => $offset,
×
UNCOV
204
                                'number'                 => $steps,
×
UNCOV
205
                        ]
×
UNCOV
206
                );
×
207

208
                // If there are no terms fetched for this range, we are on an invalid page.
UNCOV
209
                if ( empty( $terms ) ) {
×
210
                        throw new OutOfBoundsException( 'Invalid sitemap page requested' );
×
211
                }
212

UNCOV
213
                $post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses() );
×
214

UNCOV
215
                $replacements = array_merge(
×
UNCOV
216
                        [
×
UNCOV
217
                                'post_modified_gmt',
×
UNCOV
218
                                $wpdb->posts,
×
UNCOV
219
                                $wpdb->term_relationships,
×
UNCOV
220
                                'object_id',
×
UNCOV
221
                                'ID',
×
UNCOV
222
                                $wpdb->term_taxonomy,
×
UNCOV
223
                                'term_taxonomy_id',
×
UNCOV
224
                                'term_taxonomy_id',
×
UNCOV
225
                                'taxonomy',
×
UNCOV
226
                                'term_id',
×
UNCOV
227
                                'post_status',
×
UNCOV
228
                        ],
×
UNCOV
229
                        $post_statuses,
×
UNCOV
230
                        [ 'post_password' ]
×
UNCOV
231
                );
×
232

233
                /**
234
                 * Filter: 'wpseo_exclude_from_sitemap_by_term_ids' - Allow excluding terms by ID.
235
                 *
236
                 * @param array $terms_to_exclude The terms to exclude.
237
                 */
UNCOV
238
                $terms_to_exclude = apply_filters( 'wpseo_exclude_from_sitemap_by_term_ids', [] );
×
239

UNCOV
240
                foreach ( $terms as $term ) {
×
241

UNCOV
242
                        if ( in_array( $term->term_id, $terms_to_exclude, true ) ) {
×
243
                                continue;
×
244
                        }
245

UNCOV
246
                        $url = [];
×
247

UNCOV
248
                        $tax_noindex = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'noindex' );
×
249

UNCOV
250
                        if ( $tax_noindex === 'noindex' ) {
×
251
                                continue;
×
252
                        }
253

UNCOV
254
                        $canonical  = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'canonical' );
×
UNCOV
255
                        $url['loc'] = get_term_link( $term, $term->taxonomy );
×
256

UNCOV
257
                        if ( is_string( $canonical ) && $canonical !== '' && $canonical !== $url['loc'] ) {
×
258
                                continue;
×
259
                        }
260

UNCOV
261
                        $current_replacements = $replacements;
×
UNCOV
262
                        array_splice( $current_replacements, 9, 0, $term->taxonomy );
×
UNCOV
263
                        array_splice( $current_replacements, 11, 0, $term->term_id );
×
264

265
                        //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
266
                        //phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
UNCOV
267
                        $url['mod'] = $wpdb->get_var(
×
268
                                //phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
UNCOV
269
                                $wpdb->prepare(
×
UNCOV
270
                                        '
×
271
                        SELECT MAX(p.%i) AS lastmod
272
                        FROM        %i AS p
273
                        INNER JOIN %i AS term_rel
274
                                ON                term_rel.%i = p.%i
275
                        INNER JOIN %i AS term_tax
276
                                ON                term_tax.%i = term_rel.%i
277
                                AND                term_tax.%i = %s
278
                                AND                term_tax.%i = %d
UNCOV
279
                        WHERE        p.%i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ")
×
280
                                AND                p.%i = ''
UNCOV
281
                        ",
×
UNCOV
282
                                        $current_replacements
×
UNCOV
283
                                )
×
UNCOV
284
                        );
×
285

UNCOV
286
                        if ( $this->include_images ) {
×
UNCOV
287
                                $url['images'] = $this->get_image_parser()->get_term_images( $term );
×
288
                        }
289

290
                        // Deprecated, kept for backwards data compat. R.
UNCOV
291
                        $url['chf'] = 'daily';
×
UNCOV
292
                        $url['pri'] = 1;
×
293

294
                        /** This filter is documented at inc/sitemaps/class-post-type-sitemap-provider.php */
UNCOV
295
                        $url = apply_filters( 'wpseo_sitemap_entry', $url, 'term', $term );
×
296

UNCOV
297
                        if ( ! empty( $url ) ) {
×
UNCOV
298
                                $links[] = $url;
×
299
                        }
300
                }
301

UNCOV
302
                return $links;
×
303
        }
304

305
        /**
306
         * Check if taxonomy by name is valid to appear in sitemaps.
307
         *
308
         * @param string $taxonomy_name Taxonomy name to check.
309
         *
310
         * @return bool
311
         */
UNCOV
312
        public function is_valid_taxonomy( $taxonomy_name ) {
×
313

UNCOV
314
                if ( WPSEO_Options::get( "noindex-tax-{$taxonomy_name}" ) === true ) {
×
UNCOV
315
                        return false;
×
316
                }
317

UNCOV
318
                if ( in_array( $taxonomy_name, [ 'link_category', 'nav_menu', 'wp_pattern_category' ], true ) ) {
×
UNCOV
319
                        return false;
×
320
                }
321

322
                if ( $taxonomy_name === 'post_format' && WPSEO_Options::get( 'disable-post_format', false ) ) {
×
323
                        return false;
×
324
                }
325

326
                /**
327
                 * Filter to exclude the taxonomy from the XML sitemap.
328
                 *
329
                 * @param bool   $exclude       Defaults to false.
330
                 * @param string $taxonomy_name Name of the taxonomy to exclude..
331
                 */
332
                if ( apply_filters( 'wpseo_sitemap_exclude_taxonomy', false, $taxonomy_name ) ) {
×
333
                        return false;
×
334
                }
335

336
                return true;
×
337
        }
338

339
        /**
340
         * Get the Image Parser.
341
         *
342
         * @return WPSEO_Sitemap_Image_Parser
343
         */
344
        protected function get_image_parser() {
×
345
                if ( ! isset( self::$image_parser ) ) {
×
346
                        self::$image_parser = new WPSEO_Sitemap_Image_Parser();
×
347
                }
348

349
                return self::$image_parser;
×
350
        }
351
}
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

© 2025 Coveralls, Inc