• 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
/admin/class-meta-columns.php
1
<?php
2
/**
3
 * WPSEO plugin file.
4
 *
5
 * @package WPSEO\Admin
6
 */
7

8
use Yoast\WP\SEO\Context\Meta_Tags_Context;
9
use Yoast\WP\SEO\Helpers\Score_Icon_Helper;
10
use Yoast\WP\SEO\Integrations\Admin\Admin_Columns_Cache_Integration;
11
use Yoast\WP\SEO\Surfaces\Values\Meta;
12

13
/**
14
 * Class WPSEO_Meta_Columns.
15
 */
16
class WPSEO_Meta_Columns {
17

18
        /**
19
         * Holds the context objects for each indexable.
20
         *
21
         * @var Meta_Tags_Context[]
22
         */
23
        protected $context = [];
24

25
        /**
26
         * Holds the SEO analysis.
27
         *
28
         * @var WPSEO_Metabox_Analysis_SEO
29
         */
30
        private $analysis_seo;
31

32
        /**
33
         * Holds the readability analysis.
34
         *
35
         * @var WPSEO_Metabox_Analysis_Readability
36
         */
37
        private $analysis_readability;
38

39
        /**
40
         * Admin columns cache.
41
         *
42
         * @var Admin_Columns_Cache_Integration
43
         */
44
        private $admin_columns_cache;
45

46
        /**
47
         * Holds the Score_Icon_Helper.
48
         *
49
         * @var Score_Icon_Helper
50
         */
51
        private $score_icon_helper;
52

53
        /**
54
         * When page analysis is enabled, just initialize the hooks.
55
         */
56
        public function __construct() {
×
57
                if ( apply_filters( 'wpseo_use_page_analysis', true ) === true ) {
×
58
                        add_action( 'admin_init', [ $this, 'setup_hooks' ] );
×
59
                }
60

61
                $this->analysis_seo         = new WPSEO_Metabox_Analysis_SEO();
×
62
                $this->analysis_readability = new WPSEO_Metabox_Analysis_Readability();
×
63
                $this->admin_columns_cache  = YoastSEO()->classes->get( Admin_Columns_Cache_Integration::class );
×
64
                $this->score_icon_helper    = YoastSEO()->helpers->score_icon;
×
65
        }
66

67
        /**
68
         * Sets up up the hooks.
69
         *
70
         * @return void
71
         */
72
        public function setup_hooks() {
×
73
                $this->set_post_type_hooks();
×
74

75
                if ( $this->analysis_seo->is_enabled() ) {
×
76
                        add_action( 'restrict_manage_posts', [ $this, 'posts_filter_dropdown' ] );
×
77
                }
78

79
                if ( $this->analysis_readability->is_enabled() ) {
×
80
                        add_action( 'restrict_manage_posts', [ $this, 'posts_filter_dropdown_readability' ] );
×
81
                }
82

83
                add_filter( 'request', [ $this, 'column_sort_orderby' ] );
×
84
                add_filter( 'default_hidden_columns', [ $this, 'column_hidden' ], 10, 1 );
×
85
        }
86

87
        /**
88
         * Adds the column headings for the SEO plugin for edit posts / pages overview.
89
         *
90
         * @param array $columns Already existing columns.
91
         *
92
         * @return array Array containing the column headings.
93
         */
UNCOV
94
        public function column_heading( $columns ) {
×
UNCOV
95
                if ( $this->display_metabox() === false ) {
×
96
                        return $columns;
×
97
                }
98

UNCOV
99
                $added_columns = [];
×
100

UNCOV
101
                if ( $this->analysis_seo->is_enabled() ) {
×
UNCOV
102
                        $added_columns['wpseo-score'] = '<span class="yoast-column-seo-score yoast-column-header-has-tooltip" data-tooltip-text="'
×
UNCOV
103
                                                                                        . esc_attr__( 'SEO score', 'wordpress-seo' )
×
UNCOV
104
                                                                                        . '"><span class="screen-reader-text">'
×
UNCOV
105
                                                                                        . __( 'SEO score', 'wordpress-seo' )
×
UNCOV
106
                                                                                        . '</span></span></span>';
×
107
                }
108

UNCOV
109
                if ( $this->analysis_readability->is_enabled() ) {
×
UNCOV
110
                        $added_columns['wpseo-score-readability'] = '<span class="yoast-column-readability yoast-column-header-has-tooltip" data-tooltip-text="'
×
UNCOV
111
                                                                                                                . esc_attr__( 'Readability score', 'wordpress-seo' )
×
UNCOV
112
                                                                                                                . '"><span class="screen-reader-text">'
×
UNCOV
113
                                                                                                                . __( 'Readability score', 'wordpress-seo' )
×
UNCOV
114
                                                                                                                . '</span></span></span>';
×
115
                }
116

UNCOV
117
                $added_columns['wpseo-title']    = __( 'SEO Title', 'wordpress-seo' );
×
UNCOV
118
                $added_columns['wpseo-metadesc'] = __( 'Meta Desc.', 'wordpress-seo' );
×
119

UNCOV
120
                if ( $this->analysis_seo->is_enabled() ) {
×
UNCOV
121
                        $added_columns['wpseo-focuskw'] = __( 'Keyphrase', 'wordpress-seo' );
×
122
                }
123

UNCOV
124
                return array_merge( $columns, $added_columns );
×
125
        }
126

127
        /**
128
         * Displays the column content for the given column.
129
         *
130
         * @param string $column_name Column to display the content for.
131
         * @param int    $post_id     Post to display the column content for.
132
         *
133
         * @return void
134
         */
135
        public function column_content( $column_name, $post_id ) {
×
136
                if ( $this->display_metabox() === false ) {
×
137
                        return;
×
138
                }
139

140
                switch ( $column_name ) {
141
                        case 'wpseo-score':
×
142
                                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in render_score_indicator() method.
143
                                echo $this->parse_column_score( $post_id );
×
144

145
                                return;
×
146

147
                        case 'wpseo-score-readability':
×
148
                                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in render_score_indicator() method.
149
                                echo $this->parse_column_score_readability( $post_id );
×
150

151
                                return;
×
152

153
                        case 'wpseo-title':
×
154
                                $meta = $this->get_meta( $post_id );
×
155
                                if ( $meta ) {
×
156
                                        echo esc_html( $meta->title );
×
157
                                }
158

159
                                return;
×
160

161
                        case 'wpseo-metadesc':
×
162
                                $metadesc_val = '';
×
163
                                $meta         = $this->get_meta( $post_id );
×
164
                                if ( $meta ) {
×
165
                                        $metadesc_val = $meta->meta_description;
×
166
                                }
167
                                if ( $metadesc_val === '' ) {
×
168
                                        echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">',
×
169
                                        /* translators: Hidden accessibility text. */
170
                                        esc_html__( 'Meta description not set.', 'wordpress-seo' ),
×
171
                                        '</span>';
×
172

173
                                        return;
×
174
                                }
175

176
                                echo esc_html( $metadesc_val );
×
177

178
                                return;
×
179

180
                        case 'wpseo-focuskw':
×
181
                                $focuskw_val = WPSEO_Meta::get_value( 'focuskw', $post_id );
×
182

183
                                if ( $focuskw_val === '' ) {
×
184
                                        echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">',
×
185
                                        /* translators: Hidden accessibility text. */
186
                                        esc_html__( 'Focus keyphrase not set.', 'wordpress-seo' ),
×
187
                                        '</span>';
×
188

189
                                        return;
×
190
                                }
191

192
                                echo esc_html( $focuskw_val );
×
193

194
                                return;
×
195
                }
196
        }
197

198
        /**
199
         * Indicates which of the SEO columns are sortable.
200
         *
201
         * @param array $columns Appended with their orderby variable.
202
         *
203
         * @return array Array containing the sortable columns.
204
         */
205
        public function column_sort( $columns ) {
×
206
                if ( $this->display_metabox() === false ) {
×
207
                        return $columns;
×
208
                }
209

210
                $columns['wpseo-metadesc'] = 'wpseo-metadesc';
×
211

212
                if ( $this->analysis_seo->is_enabled() ) {
×
213
                        $columns['wpseo-focuskw'] = 'wpseo-focuskw';
×
214
                        $columns['wpseo-score']   = 'wpseo-score';
×
215
                }
216

217
                if ( $this->analysis_readability->is_enabled() ) {
×
218
                        $columns['wpseo-score-readability'] = 'wpseo-score-readability';
×
219
                }
220

221
                return $columns;
×
222
        }
223

224
        /**
225
         * Hides the SEO title, meta description and focus keyword columns if the user hasn't chosen which columns to hide.
226
         *
227
         * @param array $hidden The hidden columns.
228
         *
229
         * @return array Array containing the columns to hide.
230
         */
UNCOV
231
        public function column_hidden( $hidden ) {
×
UNCOV
232
                if ( ! is_array( $hidden ) ) {
×
UNCOV
233
                        $hidden = [];
×
234
                }
235

UNCOV
236
                array_push( $hidden, 'wpseo-title', 'wpseo-metadesc' );
×
237

UNCOV
238
                if ( $this->analysis_seo->is_enabled() ) {
×
UNCOV
239
                        $hidden[] = 'wpseo-focuskw';
×
240
                }
241

UNCOV
242
                return $hidden;
×
243
        }
244

245
        /**
246
         * Adds a dropdown that allows filtering on the posts SEO Quality.
247
         *
248
         * @return void
249
         */
250
        public function posts_filter_dropdown() {
×
251
                if ( ! $this->can_display_filter() ) {
×
252
                        return;
×
253
                }
254

255
                $ranks = WPSEO_Rank::get_all_ranks();
×
256

257
                /* translators: Hidden accessibility text. */
258
                echo '<label class="screen-reader-text" for="wpseo-filter">' . esc_html__( 'Filter by SEO Score', 'wordpress-seo' ) . '</label>';
×
259
                echo '<select name="seo_filter" id="wpseo-filter">';
×
260

261
                // phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
262
                echo $this->generate_option( '', __( 'All SEO Scores', 'wordpress-seo' ) );
×
263

264
                foreach ( $ranks as $rank ) {
×
265
                        $selected = selected( $this->get_current_seo_filter(), $rank->get_rank(), false );
×
266

267
                        // phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
268
                        echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_label(), $selected );
×
269
                }
270

271
                echo '</select>';
×
272
        }
273

274
        /**
275
         * Adds a dropdown that allows filtering on the posts Readability Quality.
276
         *
277
         * @return void
278
         */
279
        public function posts_filter_dropdown_readability() {
×
280
                if ( ! $this->can_display_filter() ) {
×
281
                        return;
×
282
                }
283

284
                $ranks = WPSEO_Rank::get_all_readability_ranks();
×
285

286
                /* translators: Hidden accessibility text. */
287
                echo '<label class="screen-reader-text" for="wpseo-readability-filter">' . esc_html__( 'Filter by Readability Score', 'wordpress-seo' ) . '</label>';
×
288
                echo '<select name="readability_filter" id="wpseo-readability-filter">';
×
289

290
                // phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
291
                echo $this->generate_option( '', __( 'All Readability Scores', 'wordpress-seo' ) );
×
292

293
                foreach ( $ranks as $rank ) {
×
294
                        $selected = selected( $this->get_current_readability_filter(), $rank->get_rank(), false );
×
295

296
                        // phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
297
                        echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_readability_labels(), $selected );
×
298
                }
299

300
                echo '</select>';
×
301
        }
302

303
        /**
304
         * Generates an <option> element.
305
         *
306
         * @param string $value    The option's value.
307
         * @param string $label    The option's label.
308
         * @param string $selected HTML selected attribute for an option.
309
         *
310
         * @return string The generated <option> element.
311
         */
312
        protected function generate_option( $value, $label, $selected = '' ) {
×
313
                return '<option ' . $selected . ' value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
×
314
        }
315

316
        /**
317
         * Returns the meta object for a given post ID.
318
         *
319
         * @param int $post_id The post ID.
320
         *
321
         * @return Meta The meta object.
322
         */
323
        protected function get_meta( $post_id ) {
×
324
                $indexable = $this->admin_columns_cache->get_indexable( $post_id );
×
325

326
                return YoastSEO()->meta->for_indexable( $indexable, 'Post_Type' );
×
327
        }
328

329
        /**
330
         * Determines the SEO score filter to be later used in the meta query, based on the passed SEO filter.
331
         *
332
         * @param string $seo_filter The SEO filter to use to determine what further filter to apply.
333
         *
334
         * @return array The SEO score filter.
335
         */
UNCOV
336
        protected function determine_seo_filters( $seo_filter ) {
×
UNCOV
337
                if ( $seo_filter === WPSEO_Rank::NO_FOCUS ) {
×
UNCOV
338
                        return $this->create_no_focus_keyword_filter();
×
339
                }
340

UNCOV
341
                if ( $seo_filter === WPSEO_Rank::NO_INDEX ) {
×
UNCOV
342
                        return $this->create_no_index_filter();
×
343
                }
344

UNCOV
345
                $rank = new WPSEO_Rank( $seo_filter );
×
346

UNCOV
347
                return $this->create_seo_score_filter( $rank->get_starting_score(), $rank->get_end_score() );
×
348
        }
349

350
        /**
351
         * Determines the Readability score filter to the meta query, based on the passed Readability filter.
352
         *
353
         * @param string $readability_filter The Readability filter to use to determine what further filter to apply.
354
         *
355
         * @return array The Readability score filter.
356
         */
UNCOV
357
        protected function determine_readability_filters( $readability_filter ) {
×
UNCOV
358
                $rank = new WPSEO_Rank( $readability_filter );
×
359

UNCOV
360
                return $this->create_readability_score_filter( $rank->get_starting_score(), $rank->get_end_score() );
×
361
        }
362

363
        /**
364
         * Creates a keyword filter for the meta query, based on the passed Keyword filter.
365
         *
366
         * @param string $keyword_filter The keyword filter to use.
367
         *
368
         * @return array The keyword filter.
369
         */
370
        protected function get_keyword_filter( $keyword_filter ) {
×
UNCOV
371
                return [
×
372
                        'post_type' => get_query_var( 'post_type', 'post' ),
×
373
                        'key'       => WPSEO_Meta::$meta_prefix . 'focuskw',
×
374
                        'value'     => sanitize_text_field( $keyword_filter ),
×
UNCOV
375
                ];
×
376
        }
377

378
        /**
379
         * Determines whether the passed filter is considered to be valid.
380
         *
381
         * @param mixed $filter The filter to check against.
382
         *
383
         * @return bool Whether the filter is considered valid.
384
         */
UNCOV
385
        protected function is_valid_filter( $filter ) {
×
UNCOV
386
                return ! empty( $filter ) && is_string( $filter );
×
387
        }
388

389
        /**
390
         * Collects the filters and merges them into a single array.
391
         *
392
         * @return array Array containing all the applicable filters.
393
         */
394
        protected function collect_filters() {
×
395
                $active_filters = [];
×
396

397
                $seo_filter             = $this->get_current_seo_filter();
×
398
                $readability_filter     = $this->get_current_readability_filter();
×
399
                $current_keyword_filter = $this->get_current_keyword_filter();
×
400

401
                if ( $this->is_valid_filter( $seo_filter ) ) {
×
402
                        $active_filters = array_merge(
×
403
                                $active_filters,
×
404
                                $this->determine_seo_filters( $seo_filter )
×
UNCOV
405
                        );
×
406
                }
407

408
                if ( $this->is_valid_filter( $readability_filter ) ) {
×
409
                        $active_filters = array_merge(
×
410
                                $active_filters,
×
411
                                $this->determine_readability_filters( $readability_filter )
×
UNCOV
412
                        );
×
413
                }
414

415
                if ( $this->is_valid_filter( $current_keyword_filter ) ) {
×
416
                        /**
417
                         * Adapt the meta query used to filter the post overview on keyphrase.
418
                         *
419
                         * @internal
420
                         *
421
                         * @param array $keyphrase      The keyphrase used in the filter.
422
                         * @param array $keyword_filter The current keyword filter.
423
                         */
424
                        $keyphrase_filter = apply_filters(
×
425
                                'wpseo_change_keyphrase_filter_in_request',
×
426
                                $this->get_keyword_filter( $current_keyword_filter ),
×
427
                                $current_keyword_filter
×
UNCOV
428
                        );
×
429

430
                        if ( is_array( $keyphrase_filter ) ) {
×
431
                                $active_filters = array_merge(
×
432
                                        $active_filters,
×
433
                                        [ $keyphrase_filter ]
×
UNCOV
434
                                );
×
435
                        }
436
                }
437

438
                /**
439
                 * Adapt the active applicable filters on the posts overview.
440
                 *
441
                 * @internal
442
                 *
443
                 * @param array $active_filters The current applicable filters.
444
                 */
445
                return apply_filters( 'wpseo_change_applicable_filters', $active_filters );
×
446
        }
447

448
        /**
449
         * Modify the query based on the filters that are being passed.
450
         *
451
         * @param array $vars Query variables that need to be modified based on the filters.
452
         *
453
         * @return array Array containing the meta query to use for filtering the posts overview.
454
         */
455
        public function column_sort_orderby( $vars ) {
×
456
                $collected_filters = $this->collect_filters();
×
457

458
                $order_by_column = $vars['orderby'];
×
459
                if ( isset( $order_by_column ) ) {
×
460
                        // Based on the selected column, create a meta query.
461
                        $order_by = $this->filter_order_by( $order_by_column );
×
462

463
                        /**
464
                         * Adapt the order by part of the query on the posts overview.
465
                         *
466
                         * @internal
467
                         *
468
                         * @param array  $order_by        The current order by.
469
                         * @param string $order_by_column The current order by column.
470
                         */
471
                        $order_by = apply_filters( 'wpseo_change_order_by', $order_by, $order_by_column );
×
472

473
                        $vars = array_merge( $vars, $order_by );
×
474
                }
475

476
                return $this->build_filter_query( $vars, $collected_filters );
×
477
        }
478

479
        /**
480
         * Retrieves the meta robots query values to be used within the meta query.
481
         *
482
         * @return array Array containing the query parameters regarding meta robots.
483
         */
484
        protected function get_meta_robots_query_values() {
×
UNCOV
485
                return [
×
486
                        'relation' => 'OR',
×
UNCOV
487
                        [
×
488
                                'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
×
489
                                'compare' => 'NOT EXISTS',
×
UNCOV
490
                        ],
×
UNCOV
491
                        [
×
492
                                'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
×
493
                                'value'   => '1',
×
494
                                'compare' => '!=',
×
UNCOV
495
                        ],
×
UNCOV
496
                ];
×
497
        }
498

499
        /**
500
         * Determines the score filters to be used. If more than one is passed, it created an AND statement for the query.
501
         *
502
         * @param array $score_filters Array containing the score filters.
503
         *
504
         * @return array Array containing the score filters that need to be applied to the meta query.
505
         */
506
        protected function determine_score_filters( $score_filters ) {
×
507
                if ( count( $score_filters ) > 1 ) {
×
508
                        return array_merge( [ 'relation' => 'AND' ], $score_filters );
×
509
                }
510

511
                return $score_filters;
×
512
        }
513

514
        /**
515
         * Retrieves the post type from the $_GET variable.
516
         *
517
         * @return string|null The sanitized current post type or null when the variable is not set in $_GET.
518
         */
UNCOV
519
        public function get_current_post_type() {
×
520
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
521
                if ( isset( $_GET['post_type'] ) && is_string( $_GET['post_type'] ) ) {
×
522
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
523
                        return sanitize_text_field( wp_unslash( $_GET['post_type'] ) );
×
524
                }
UNCOV
525
                return null;
×
526
        }
527

528
        /**
529
         * Retrieves the SEO filter from the $_GET variable.
530
         *
531
         * @return string|null The sanitized seo filter or null when the variable is not set in $_GET.
532
         */
UNCOV
533
        public function get_current_seo_filter() {
×
534
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
535
                if ( isset( $_GET['seo_filter'] ) && is_string( $_GET['seo_filter'] ) ) {
×
536
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
537
                        return sanitize_text_field( wp_unslash( $_GET['seo_filter'] ) );
×
538
                }
UNCOV
539
                return null;
×
540
        }
541

542
        /**
543
         * Retrieves the Readability filter from the $_GET variable.
544
         *
545
         * @return string|null The sanitized readability filter or null when the variable is not set in $_GET.
546
         */
UNCOV
547
        public function get_current_readability_filter() {
×
548
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
549
                if ( isset( $_GET['readability_filter'] ) && is_string( $_GET['readability_filter'] ) ) {
×
550
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
551
                        return sanitize_text_field( wp_unslash( $_GET['readability_filter'] ) );
×
552
                }
UNCOV
553
                return null;
×
554
        }
555

556
        /**
557
         * Retrieves the keyword filter from the $_GET variable.
558
         *
559
         * @return string|null The sanitized seo keyword filter or null when the variable is not set in $_GET.
560
         */
UNCOV
561
        public function get_current_keyword_filter() {
×
562
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
563
                if ( isset( $_GET['seo_kw_filter'] ) && is_string( $_GET['seo_kw_filter'] ) ) {
×
564
                        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
UNCOV
565
                        return sanitize_text_field( wp_unslash( $_GET['seo_kw_filter'] ) );
×
566
                }
UNCOV
567
                return null;
×
568
        }
569

570
        /**
571
         * Uses the vars to create a complete filter query that can later be executed to filter out posts.
572
         *
573
         * @param array $vars    Array containing the variables that will be used in the meta query.
574
         * @param array $filters Array containing the filters that we need to apply in the meta query.
575
         *
576
         * @return array Array containing the complete filter query.
577
         */
UNCOV
578
        protected function build_filter_query( $vars, $filters ) {
×
579
                // If no filters were applied, just return everything.
UNCOV
580
                if ( count( $filters ) === 0 ) {
×
UNCOV
581
                        return $vars;
×
582
                }
583

UNCOV
584
                $result               = [ 'meta_query' => [] ];
×
UNCOV
585
                $result['meta_query'] = array_merge( $result['meta_query'], [ $this->determine_score_filters( $filters ) ] );
×
586

UNCOV
587
                $current_seo_filter = $this->get_current_seo_filter();
×
588

589
                // This only applies for the SEO score filter because it can because the SEO score can be altered by the no-index option.
UNCOV
590
                if ( $this->is_valid_filter( $current_seo_filter ) && ! in_array( $current_seo_filter, [ WPSEO_Rank::NO_INDEX, WPSEO_Rank::NO_FOCUS ], true ) ) {
×
591
                        $result['meta_query'] = array_merge( $result['meta_query'], [ $this->get_meta_robots_query_values() ] );
×
592
                }
593

UNCOV
594
                return array_merge( $vars, $result );
×
595
        }
596

597
        /**
598
         * Creates a Readability score filter.
599
         *
600
         * @param number $low  The lower boundary of the score.
601
         * @param number $high The higher boundary of the score.
602
         *
603
         * @return array The Readability Score filter.
604
         */
605
        protected function create_readability_score_filter( $low, $high ) {
×
UNCOV
606
                return [
×
UNCOV
607
                        [
×
608
                                'key'     => WPSEO_Meta::$meta_prefix . 'content_score',
×
609
                                'value'   => [ $low, $high ],
×
610
                                'type'    => 'numeric',
×
611
                                'compare' => 'BETWEEN',
×
UNCOV
612
                        ],
×
UNCOV
613
                ];
×
614
        }
615

616
        /**
617
         * Creates an SEO score filter.
618
         *
619
         * @param number $low  The lower boundary of the score.
620
         * @param number $high The higher boundary of the score.
621
         *
622
         * @return array The SEO score filter.
623
         */
624
        protected function create_seo_score_filter( $low, $high ) {
×
UNCOV
625
                return [
×
UNCOV
626
                        [
×
627
                                'key'     => WPSEO_Meta::$meta_prefix . 'linkdex',
×
628
                                'value'   => [ $low, $high ],
×
629
                                'type'    => 'numeric',
×
630
                                'compare' => 'BETWEEN',
×
UNCOV
631
                        ],
×
UNCOV
632
                ];
×
633
        }
634

635
        /**
636
         * Creates a filter to retrieve posts that were set to no-index.
637
         *
638
         * @return array Array containin the no-index filter.
639
         */
640
        protected function create_no_index_filter() {
×
UNCOV
641
                return [
×
UNCOV
642
                        [
×
643
                                'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
×
644
                                'value'   => '1',
×
645
                                'compare' => '=',
×
UNCOV
646
                        ],
×
UNCOV
647
                ];
×
648
        }
649

650
        /**
651
         * Creates a filter to retrieve posts that have no keyword set.
652
         *
653
         * @return array Array containing the no focus keyword filter.
654
         */
655
        protected function create_no_focus_keyword_filter() {
×
UNCOV
656
                return [
×
UNCOV
657
                        [
×
658
                                'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
×
659
                                'value'   => 'needs-a-value-anyway',
×
660
                                'compare' => 'NOT EXISTS',
×
UNCOV
661
                        ],
×
UNCOV
662
                        [
×
663
                                'key'     => WPSEO_Meta::$meta_prefix . 'linkdex',
×
664
                                'value'   => 'needs-a-value-anyway',
×
665
                                'compare' => 'NOT EXISTS',
×
UNCOV
666
                        ],
×
UNCOV
667
                ];
×
668
        }
669

670
        /**
671
         * Determines whether a particular post_id is of an indexable post type.
672
         *
673
         * @param string $post_id The post ID to check.
674
         *
675
         * @return bool Whether or not it is indexable.
676
         */
UNCOV
677
        protected function is_indexable( $post_id ) {
×
UNCOV
678
                if ( ! empty( $post_id ) && ! $this->uses_default_indexing( $post_id ) ) {
×
UNCOV
679
                        return WPSEO_Meta::get_value( 'meta-robots-noindex', $post_id ) === '2';
×
680
                }
681

UNCOV
682
                $post = get_post( $post_id );
×
683

UNCOV
684
                if ( is_object( $post ) ) {
×
685
                        // If the option is false, this means we want to index it.
UNCOV
686
                        return WPSEO_Options::get( 'noindex-' . $post->post_type, false ) === false;
×
687
                }
688

UNCOV
689
                return true;
×
690
        }
691

692
        /**
693
         * Determines whether the given post ID uses the default indexing settings.
694
         *
695
         * @param int $post_id The post ID to check.
696
         *
697
         * @return bool Whether or not the default indexing is being used for the post.
698
         */
UNCOV
699
        protected function uses_default_indexing( $post_id ) {
×
UNCOV
700
                return WPSEO_Meta::get_value( 'meta-robots-noindex', $post_id ) === '0';
×
701
        }
702

703
        /**
704
         * Returns filters when $order_by is matched in the if-statement.
705
         *
706
         * @param string $order_by The ID of the column by which to order the posts.
707
         *
708
         * @return array Array containing the order filters.
709
         */
710
        private function filter_order_by( $order_by ) {
×
711
                switch ( $order_by ) {
712
                        case 'wpseo-metadesc':
×
UNCOV
713
                                return [
×
714
                                        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting.
715
                                        'meta_key' => WPSEO_Meta::$meta_prefix . 'metadesc',
×
716
                                        'orderby'  => 'meta_value',
×
UNCOV
717
                                ];
×
718

719
                        case 'wpseo-focuskw':
×
UNCOV
720
                                return [
×
721
                                        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting.
722
                                        'meta_key' => WPSEO_Meta::$meta_prefix . 'focuskw',
×
723
                                        'orderby'  => 'meta_value',
×
UNCOV
724
                                ];
×
725

726
                        case 'wpseo-score':
×
UNCOV
727
                                return [
×
728
                                        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting.
729
                                        'meta_key' => WPSEO_Meta::$meta_prefix . 'linkdex',
×
730
                                        'orderby'  => 'meta_value_num',
×
UNCOV
731
                                ];
×
732

733
                        case 'wpseo-score-readability':
×
UNCOV
734
                                return [
×
735
                                        // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting.
736
                                        'meta_key' => WPSEO_Meta::$meta_prefix . 'content_score',
×
737
                                        'orderby'  => 'meta_value_num',
×
UNCOV
738
                                ];
×
739
                }
740

741
                return [];
×
742
        }
743

744
        /**
745
         * Parses the score column.
746
         *
747
         * @param int $post_id The ID of the post for which to show the score.
748
         *
749
         * @return string The HTML for the SEO score indicator.
750
         */
751
        private function parse_column_score( $post_id ) {
×
752
                $meta = $this->get_meta( $post_id );
×
753

754
                if ( $meta ) {
×
755
                        return $this->score_icon_helper->for_seo( $meta->indexable, '', __( 'Post is set to noindex.', 'wordpress-seo' ) );
×
756
                }
757
        }
758

759
        /**
760
         * Parsing the readability score column.
761
         *
762
         * @param int $post_id The ID of the post for which to show the readability score.
763
         *
764
         * @return string The HTML for the readability score indicator.
765
         */
766
        private function parse_column_score_readability( $post_id ) {
×
767
                $meta = $this->get_meta( $post_id );
×
768
                if ( $meta ) {
×
769
                        return $this->score_icon_helper->for_readability( $meta->indexable->readability_score );
×
770
                }
771
        }
772

773
        /**
774
         * Sets up the hooks for the post_types.
775
         *
776
         * @return void
777
         */
778
        private function set_post_type_hooks() {
×
779
                $post_types = WPSEO_Post_Type::get_accessible_post_types();
×
780

781
                if ( ! is_array( $post_types ) || $post_types === [] ) {
×
782
                        return;
×
783
                }
784

785
                foreach ( $post_types as $post_type ) {
×
786
                        if ( $this->display_metabox( $post_type ) === false ) {
×
787
                                continue;
×
788
                        }
789

790
                        add_filter( 'manage_' . $post_type . '_posts_columns', [ $this, 'column_heading' ], 10, 1 );
×
791
                        add_action( 'manage_' . $post_type . '_posts_custom_column', [ $this, 'column_content' ], 10, 2 );
×
792
                        add_action( 'manage_edit-' . $post_type . '_sortable_columns', [ $this, 'column_sort' ], 10, 2 );
×
793
                }
794

795
                unset( $post_type );
×
796
        }
797

798
        /**
799
         * Wraps the WPSEO_Metabox check to determine whether the metabox should be displayed either by
800
         * choice of the admin or because the post type is not a public post type.
801
         *
802
         * @since 7.0
803
         *
804
         * @param string|null $post_type Optional. The post type to test, defaults to the current post post_type.
805
         *
806
         * @return bool Whether or not the meta box (and associated columns etc) should be hidden.
807
         */
808
        private function display_metabox( $post_type = null ) {
×
809
                $current_post_type = $this->get_current_post_type();
×
810

811
                if ( ! isset( $post_type ) && ! empty( $current_post_type ) ) {
×
812
                        $post_type = $current_post_type;
×
813
                }
814

815
                return WPSEO_Utils::is_metabox_active( $post_type, 'post_type' );
×
816
        }
817

818
        /**
819
         * Determines whether or not filter dropdowns should be displayed.
820
         *
821
         * @return bool Whether or the current page can display the filter drop downs.
822
         */
823
        public function can_display_filter() {
×
824
                if ( $GLOBALS['pagenow'] === 'upload.php' ) {
×
825
                        return false;
×
826
                }
827

828
                if ( $this->display_metabox() === false ) {
×
829
                        return false;
×
830
                }
831

832
                $screen = get_current_screen();
×
833
                if ( $screen === null ) {
×
834
                        return false;
×
835
                }
836

837
                return WPSEO_Post_Type::is_post_type_accessible( $screen->post_type );
×
838
        }
839
}
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