• 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/class-wpseo-admin-bar-menu.php
1
<?php
2
/**
3
 * WPSEO plugin file.
4
 *
5
 * @package WPSEO
6
 */
7

8
use Yoast\WP\SEO\Helpers\Product_Helper;
9
use Yoast\WP\SEO\Helpers\Score_Icon_Helper;
10
use Yoast\WP\SEO\Integrations\Support_Integration;
11
use Yoast\WP\SEO\Models\Indexable;
12
use Yoast\WP\SEO\Presenters\Admin\Premium_Badge_Presenter;
13
use Yoast\WP\SEO\Promotions\Application\Promotion_Manager;
14
use Yoast\WP\SEO\Repositories\Indexable_Repository;
15

16
/**
17
 * Class for the Yoast SEO admin bar menu.
18
 */
19
class WPSEO_Admin_Bar_Menu implements WPSEO_WordPress_Integration {
20

21
        /**
22
         * The identifier used for the menu.
23
         *
24
         * @var string
25
         */
26
        public const MENU_IDENTIFIER = 'wpseo-menu';
27

28
        /**
29
         * The identifier used for the Keyword Research submenu.
30
         *
31
         * @var string
32
         */
33
        public const KEYWORD_RESEARCH_SUBMENU_IDENTIFIER = 'wpseo-kwresearch';
34

35
        /**
36
         * The identifier used for the Analysis submenu.
37
         *
38
         * @var string
39
         */
40
        public const ANALYSIS_SUBMENU_IDENTIFIER = 'wpseo-analysis';
41

42
        /**
43
         * The identifier used for the Settings submenu.
44
         *
45
         * @var string
46
         */
47
        public const SETTINGS_SUBMENU_IDENTIFIER = 'wpseo-settings';
48

49
        /**
50
         * The identifier used for the Network Settings submenu.
51
         *
52
         * @var string
53
         */
54
        public const NETWORK_SETTINGS_SUBMENU_IDENTIFIER = 'wpseo-network-settings';
55

56
        /**
57
         * Asset manager instance.
58
         *
59
         * @var WPSEO_Admin_Asset_Manager
60
         */
61
        protected $asset_manager;
62

63
        /**
64
         * Holds the Score_Icon_Helper instance.
65
         *
66
         * @var Score_Icon_Helper
67
         */
68
        protected $indexable_repository;
69

70
        /**
71
         * Holds the Score_Icon_Helper instance.
72
         *
73
         * @var Score_Icon_Helper
74
         */
75
        protected $score_icon_helper;
76

77
        /**
78
         * Holds the Product_Helper instance.
79
         *
80
         * @var Product_Helper
81
         */
82
        protected $product_helper;
83

84
        /**
85
         * Holds the shortlinker instance.
86
         *
87
         * @var WPSEO_Shortlinker
88
         */
89
        protected $shortlinker;
90

91
        /**
92
         * Whether SEO Score is enabled.
93
         *
94
         * @var bool
95
         */
96
        protected $is_seo_enabled = null;
97

98
        /**
99
         * Whether readability is enabled.
100
         *
101
         * @var bool
102
         */
103
        protected $is_readability_enabled = null;
104

105
        /**
106
         * The indexable for the current WordPress page, if found.
107
         *
108
         * @var bool|Indexable
109
         */
110
        protected $current_indexable = null;
111

112
        /**
113
         * Constructs the WPSEO_Admin_Bar_Menu.
114
         *
115
         * @param WPSEO_Admin_Asset_Manager|null $asset_manager        Optional. Asset manager to use.
116
         * @param Indexable_Repository|null      $indexable_repository Optional. The Indexable_Repository.
117
         * @param Score_Icon_Helper|null         $score_icon_helper    Optional. The Score_Icon_Helper.
118
         * @param Product_Helper|null            $product_helper       Optional. The product helper.
119
         * @param WPSEO_Shortlinker|null         $shortlinker          The shortlinker.
120
         */
121
        public function __construct(
×
122
                ?WPSEO_Admin_Asset_Manager $asset_manager = null,
123
                ?Indexable_Repository $indexable_repository = null,
124
                ?Score_Icon_Helper $score_icon_helper = null,
125
                ?Product_Helper $product_helper = null,
126
                ?WPSEO_Shortlinker $shortlinker = null
127
        ) {
128
                if ( ! $asset_manager ) {
×
129
                        $asset_manager = new WPSEO_Admin_Asset_Manager();
×
130
                }
131
                if ( ! $indexable_repository ) {
×
132
                        $indexable_repository = YoastSEO()->classes->get( Indexable_Repository::class );
×
133
                }
134
                if ( ! $score_icon_helper ) {
×
135
                        $score_icon_helper = YoastSEO()->helpers->score_icon;
×
136
                }
137
                if ( ! $product_helper ) {
×
138
                        $product_helper = YoastSEO()->helpers->product;
×
139
                }
140
                if ( ! $shortlinker ) {
×
141
                        $shortlinker = new WPSEO_Shortlinker();
×
142
                }
143

144
                $this->product_helper       = $product_helper;
×
145
                $this->asset_manager        = $asset_manager;
×
146
                $this->indexable_repository = $indexable_repository;
×
147
                $this->score_icon_helper    = $score_icon_helper;
×
148
                $this->shortlinker          = $shortlinker;
×
149
        }
150

151
        /**
152
         * Gets whether SEO score is enabled, with cache applied.
153
         *
154
         * @return bool True if SEO score is enabled, false otherwise.
155
         */
156
        protected function get_is_seo_enabled() {
×
157
                if ( is_null( $this->is_seo_enabled ) ) {
×
158
                        $this->is_seo_enabled = ( new WPSEO_Metabox_Analysis_SEO() )->is_enabled();
×
159
                }
160

161
                return $this->is_seo_enabled;
×
162
        }
163

164
        /**
165
         * Gets whether readability is enabled, with cache applied.
166
         *
167
         * @return bool True if readability is enabled, false otherwise.
168
         */
169
        protected function get_is_readability_enabled() {
×
170
                if ( is_null( $this->is_readability_enabled ) ) {
×
171
                        $this->is_readability_enabled = ( new WPSEO_Metabox_Analysis_Readability() )->is_enabled();
×
172
                }
173

174
                return $this->is_readability_enabled;
×
175
        }
176

177
        /**
178
         * Returns the indexable for the current WordPress page, with cache applied.
179
         *
180
         * @return bool|Indexable The indexable, false if none could be found.
181
         */
182
        protected function get_current_indexable() {
×
183
                if ( is_null( $this->current_indexable ) ) {
×
184
                        $this->current_indexable = $this->indexable_repository->for_current_page();
×
185
                }
186

187
                return $this->current_indexable;
×
188
        }
189

190
        /**
191
         * Adds the admin bar menu.
192
         *
193
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
194
         *
195
         * @return void
196
         */
UNCOV
197
        public function add_menu( WP_Admin_Bar $wp_admin_bar ) {
×
198
                // On block editor pages, the admin bar only shows on mobile, where having this menu icon is not very helpful.
UNCOV
199
                if ( is_admin() ) {
×
200
                        $screen = get_current_screen();
×
201
                        if ( isset( $screen ) && $screen->is_block_editor() ) {
×
202
                                return;
×
203
                        }
204
                }
205

206
                // If the current user can't write posts, this is all of no use, so let's not output an admin menu.
UNCOV
207
                if ( ! current_user_can( 'edit_posts' ) ) {
×
UNCOV
208
                        return;
×
209
                }
210

UNCOV
211
                $this->add_root_menu( $wp_admin_bar );
×
212

213
                /**
214
                 * Adds a submenu item in the top of the adminbar.
215
                 *
216
                 * @param WP_Admin_Bar $wp_admin_bar    Admin bar instance to add the menu to.
217
                 * @param string       $menu_identifier The menu identifier.
218
                 */
UNCOV
219
                do_action( 'wpseo_add_adminbar_submenu', $wp_admin_bar, self::MENU_IDENTIFIER );
×
220

UNCOV
221
                if ( ! is_admin() ) {
×
222

UNCOV
223
                        if ( is_singular() || is_tag() || is_tax() || is_category() ) {
×
224
                                $is_seo_enabled         = $this->get_is_seo_enabled();
×
225
                                $is_readability_enabled = $this->get_is_readability_enabled();
×
226

227
                                $indexable = $this->get_current_indexable();
×
228

229
                                if ( $is_seo_enabled ) {
×
230
                                        $focus_keyword = ( ! is_a( $indexable, 'Yoast\WP\SEO\Models\Indexable' ) || is_null( $indexable->primary_focus_keyword ) ) ? __( 'not set', 'wordpress-seo' ) : $indexable->primary_focus_keyword;
×
231

232
                                        $wp_admin_bar->add_menu(
×
UNCOV
233
                                                [
×
234
                                                        'parent' => self::MENU_IDENTIFIER,
×
235
                                                        'id'     => 'wpseo-seo-focus-keyword',
×
236
                                                        'title'  => __( 'Focus keyphrase: ', 'wordpress-seo' ) . '<span class="wpseo-focus-keyword">' . $focus_keyword . '</span>',
×
UNCOV
237
                                                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
238
                                                ]
×
UNCOV
239
                                        );
×
240
                                        $wp_admin_bar->add_menu(
×
UNCOV
241
                                                [
×
242
                                                        'parent' => self::MENU_IDENTIFIER,
×
243
                                                        'id'     => 'wpseo-seo-score',
×
244
                                                        'title'  => __( 'SEO score', 'wordpress-seo' ) . ': ' . $this->score_icon_helper->for_seo( $indexable, 'adminbar-sub-menu-score' )
×
245
                                                                        ->present(),
×
UNCOV
246
                                                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
247
                                                ]
×
UNCOV
248
                                        );
×
249
                                }
250

251
                                if ( $is_readability_enabled ) {
×
252
                                        $wp_admin_bar->add_menu(
×
UNCOV
253
                                                [
×
254
                                                        'parent' => self::MENU_IDENTIFIER,
×
255
                                                        'id'     => 'wpseo-readability-score',
×
256
                                                        'title'  => __( 'Readability', 'wordpress-seo' ) . ': ' . $this->score_icon_helper->for_readability( $indexable->readability_score, 'adminbar-sub-menu-score' )
×
257
                                                                        ->present(),
×
UNCOV
258
                                                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
259
                                                ]
×
UNCOV
260
                                        );
×
261
                                }
262

263
                                if ( ! $this->product_helper->is_premium() ) {
×
264
                                        $wp_admin_bar->add_menu(
×
UNCOV
265
                                                [
×
266
                                                        'parent' => self::MENU_IDENTIFIER,
×
267
                                                        'id'     => 'wpseo-frontend-inspector',
×
268
                                                        'href'   => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-frontend-inspector' ),
×
269
                                                        'title'  => __( 'Front-end SEO inspector', 'wordpress-seo' ) . new Premium_Badge_Presenter( 'wpseo-frontend-inspector-badge' ),
×
UNCOV
270
                                                        'meta'   => [
×
UNCOV
271
                                                                'tabindex' => '0',
×
UNCOV
272
                                                                'target'   => '_blank',
×
UNCOV
273
                                                        ],
×
UNCOV
274
                                                ]
×
UNCOV
275
                                        );
×
276
                                }
277
                        }
UNCOV
278
                        $this->add_analysis_submenu( $wp_admin_bar );
×
UNCOV
279
                        $this->add_seo_tools_submenu( $wp_admin_bar );
×
UNCOV
280
                        $this->add_how_to_submenu( $wp_admin_bar );
×
UNCOV
281
                        $this->add_get_help_submenu( $wp_admin_bar );
×
282
                }
283

UNCOV
284
                if ( ! is_admin() || is_blog_admin() ) {
×
UNCOV
285
                        $this->add_settings_submenu( $wp_admin_bar );
×
286
                }
287
                elseif ( is_network_admin() ) {
×
288
                        $this->add_network_settings_submenu( $wp_admin_bar );
×
289
                }
290

UNCOV
291
                if ( ! $this->product_helper->is_premium() ) {
×
UNCOV
292
                        $this->add_premium_link( $wp_admin_bar );
×
293
                }
294
        }
295

296
        /**
297
         * Enqueues admin bar assets.
298
         *
299
         * @return void
300
         */
UNCOV
301
        public function enqueue_assets() {
×
UNCOV
302
                if ( ! is_admin_bar_showing() ) {
×
UNCOV
303
                        return;
×
304
                }
305

306
                // If the current user can't write posts, this is all of no use, so let's not output an admin menu.
UNCOV
307
                if ( ! current_user_can( 'edit_posts' ) ) {
×
308
                        return;
×
309
                }
310

UNCOV
311
                $this->asset_manager->register_assets();
×
UNCOV
312
                $this->asset_manager->enqueue_style( 'adminbar' );
×
313
        }
314

315
        /**
316
         * Registers the hooks.
317
         *
318
         * @return void
319
         */
UNCOV
320
        public function register_hooks() {
×
UNCOV
321
                if ( ! $this->meets_requirements() ) {
×
322
                        return;
×
323
                }
324

UNCOV
325
                add_action( 'admin_bar_menu', [ $this, 'add_menu' ], 95 );
×
326

UNCOV
327
                add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_assets' ] );
×
UNCOV
328
                add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
×
329
        }
330

331
        /**
332
         * Checks whether the requirements to use this class are met.
333
         *
334
         * @return bool True if requirements are met, false otherwise.
335
         */
UNCOV
336
        public function meets_requirements() {
×
UNCOV
337
                if ( is_network_admin() ) {
×
338
                        return WPSEO_Utils::is_plugin_network_active();
×
339
                }
340

UNCOV
341
                if ( WPSEO_Options::get( 'enable_admin_bar_menu' ) !== true ) {
×
UNCOV
342
                        return false;
×
343
                }
344

UNCOV
345
                return ! is_admin() || is_blog_admin();
×
346
        }
347

348
        /**
349
         * Adds the admin bar root menu.
350
         *
351
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
352
         *
353
         * @return void
354
         */
355
        protected function add_root_menu( WP_Admin_Bar $wp_admin_bar ) {
×
356
                $title = $this->get_title();
×
357

358
                $score              = '';
×
359
                $settings_url       = '';
×
360
                $counter            = '';
×
361
                $notification_popup = '';
×
362

363
                $post = $this->get_singular_post();
×
364
                if ( $post ) {
×
365
                        $score = $this->get_post_score( $post );
×
366
                }
367

368
                $term = $this->get_singular_term();
×
369
                if ( $term ) {
×
370
                        $score = $this->get_term_score( $term );
×
371
                }
372

373
                $can_manage_options = $this->can_manage_options();
×
374

375
                if ( $can_manage_options ) {
×
376
                        $settings_url = $this->get_settings_page_url();
×
377
                }
378

379
                if ( empty( $score ) && ! is_network_admin() && $can_manage_options ) {
×
380
                        $counter            = $this->get_notification_counter();
×
381
                        $notification_popup = $this->get_notification_popup();
×
382
                }
383

UNCOV
384
                $admin_bar_menu_args = [
×
385
                        'id'    => self::MENU_IDENTIFIER,
×
386
                        'title' => $title . $score . $counter . $notification_popup,
×
387
                        'href'  => $settings_url,
×
388
                        'meta'  => [ 'tabindex' => ! empty( $settings_url ) ? false : '0' ],
×
UNCOV
389
                ];
×
390
                $wp_admin_bar->add_menu( $admin_bar_menu_args );
×
391

392
                if ( ! empty( $counter ) ) {
×
UNCOV
393
                        $admin_bar_menu_args = [
×
394
                                'parent' => self::MENU_IDENTIFIER,
×
395
                                'id'     => 'wpseo-notifications',
×
396
                                'title'  => __( 'Notifications', 'wordpress-seo' ) . $counter,
×
397
                                'href'   => $settings_url,
×
398
                                'meta'   => [ 'tabindex' => ! empty( $settings_url ) ? false : '0' ],
×
UNCOV
399
                        ];
×
400
                        $wp_admin_bar->add_menu( $admin_bar_menu_args );
×
401
                }
402
        }
403

404
        /**
405
         * Adds the admin bar analysis submenu.
406
         *
407
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
408
         *
409
         * @return void
410
         */
411
        protected function add_analysis_submenu( WP_Admin_Bar $wp_admin_bar ) {
×
412
                try {
413
                        $url = YoastSEO()->meta->for_current_page()->canonical;
×
414
                } catch ( Exception $e ) {
×
415
                        // This is not the type of error we can handle here.
416
                        return;
×
417
                }
418

419
                if ( ! $url ) {
×
420
                        return;
×
421
                }
422

UNCOV
423
                $menu_args = [
×
424
                        'parent' => self::MENU_IDENTIFIER,
×
UNCOV
425
                        'id'     => self::ANALYSIS_SUBMENU_IDENTIFIER,
×
426
                        'title'  => __( 'Analyze this page', 'wordpress-seo' ),
×
UNCOV
427
                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
428
                ];
×
429
                $wp_admin_bar->add_menu( $menu_args );
×
430

431
                $encoded_url   = rawurlencode( $url );
×
UNCOV
432
                $submenu_items = [
×
UNCOV
433
                        [
×
434
                                'id'    => 'wpseo-inlinks',
×
435
                                'title' => __( 'Check links to this URL', 'wordpress-seo' ),
×
436
                                'href'  => 'https://search.google.com/search-console/links/drilldown?resource_id=' . rawurlencode( get_option( 'siteurl' ) ) . '&type=EXTERNAL&target=' . $encoded_url . '&domain=',
×
UNCOV
437
                        ],
×
UNCOV
438
                        [
×
439
                                'id'    => 'wpseo-structureddata',
×
440
                                'title' => __( 'Google Rich Results Test', 'wordpress-seo' ),
×
441
                                'href'  => 'https://search.google.com/test/rich-results?url=' . $encoded_url,
×
UNCOV
442
                        ],
×
UNCOV
443
                        [
×
444
                                'id'    => 'wpseo-facebookdebug',
×
445
                                'title' => __( 'Facebook Debugger', 'wordpress-seo' ),
×
446
                                'href'  => '//developers.facebook.com/tools/debug/?q=' . $encoded_url,
×
UNCOV
447
                        ],
×
UNCOV
448
                        [
×
449
                                'id'    => 'wpseo-pagespeed',
×
450
                                'title' => __( 'Google Page Speed Test', 'wordpress-seo' ),
×
451
                                'href'  => '//developers.google.com/speed/pagespeed/insights/?url=' . $encoded_url,
×
UNCOV
452
                        ],
×
UNCOV
453
                ];
×
454

455
                $this->add_submenu_items( $submenu_items, $wp_admin_bar, self::ANALYSIS_SUBMENU_IDENTIFIER );
×
456
        }
457

458
        /**
459
         * Adds the admin bar tools submenu.
460
         *
461
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
462
         *
463
         * @return void
464
         */
465
        protected function add_seo_tools_submenu( WP_Admin_Bar $wp_admin_bar ) {
×
UNCOV
466
                $menu_args = [
×
467
                        'parent' => self::MENU_IDENTIFIER,
×
468
                        'id'     => 'wpseo-sub-tools',
×
469
                        'title'  => __( 'SEO Tools', 'wordpress-seo' ),
×
UNCOV
470
                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
471
                ];
×
472
                $wp_admin_bar->add_menu( $menu_args );
×
473

UNCOV
474
                $submenu_items = [
×
UNCOV
475
                        [
×
476
                                'id'    => 'wpseo-semrush',
×
477
                                'title' => 'Semrush',
×
478
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-semrush' ),
×
UNCOV
479
                        ],
×
UNCOV
480
                        [
×
481
                                'id'    => 'wpseo-wincher',
×
482
                                'title' => 'Wincher',
×
483
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-wincher' ),
×
UNCOV
484
                        ],
×
UNCOV
485
                        [
×
486
                                'id'    => 'wpseo-google-trends',
×
487
                                'title' => 'Google trends',
×
488
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-gtrends' ),
×
UNCOV
489
                        ],
×
UNCOV
490
                ];
×
491

492
                $this->add_submenu_items( $submenu_items, $wp_admin_bar, 'wpseo-sub-tools' );
×
493
        }
494

495
        /**
496
         * Adds the admin bar How To submenu.
497
         *
498
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
499
         *
500
         * @return void
501
         */
502
        protected function add_how_to_submenu( WP_Admin_Bar $wp_admin_bar ) {
×
UNCOV
503
                $menu_args = [
×
504
                        'parent' => self::MENU_IDENTIFIER,
×
505
                        'id'     => 'wpseo-sub-howto',
×
506
                        'title'  => __( 'How to', 'wordpress-seo' ),
×
UNCOV
507
                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
508
                ];
×
509
                $wp_admin_bar->add_menu( $menu_args );
×
510

UNCOV
511
                $submenu_items = [
×
UNCOV
512
                        [
×
513
                                'id'    => 'wpseo-learn-seo',
×
514
                                'title' => __( 'Learn more SEO', 'wordpress-seo' ),
×
515
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-learn-more-seo' ),
×
UNCOV
516
                        ],
×
UNCOV
517
                        [
×
518
                                'id'    => 'wpseo-improve-blogpost',
×
519
                                'title' => __( 'Improve your blog post', 'wordpress-seo' ),
×
520
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-improve-blog-post' ),
×
UNCOV
521
                        ],
×
UNCOV
522
                        [
×
523
                                'id'    => 'wpseo-write-better-content',
×
524
                                'title' => __( 'Write better content', 'wordpress-seo' ),
×
525
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-write-better' ),
×
UNCOV
526
                        ],
×
UNCOV
527
                ];
×
528

529
                $this->add_submenu_items( $submenu_items, $wp_admin_bar, 'wpseo-sub-howto' );
×
530
        }
531

532
        /**
533
         * Adds the admin bar How To submenu.
534
         *
535
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
536
         *
537
         * @return void
538
         */
539
        protected function add_get_help_submenu( WP_Admin_Bar $wp_admin_bar ) {
×
UNCOV
540
                $menu_args = [
×
541
                        'parent' => self::MENU_IDENTIFIER,
×
542
                        'id'     => 'wpseo-sub-get-help',
×
543
                        'title'  => __( 'Help', 'wordpress-seo' ),
×
UNCOV
544
                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
545
                ];
×
546

547
                if ( current_user_can( Support_Integration::CAPABILITY ) ) {
×
548
                        $menu_args['href'] = admin_url( 'admin.php?page=' . Support_Integration::PAGE );
×
549
                        $wp_admin_bar->add_menu( $menu_args );
×
550

551
                        return;
×
552
                }
553
                $wp_admin_bar->add_menu( $menu_args );
×
554

UNCOV
555
                $submenu_items = [
×
UNCOV
556
                        [
×
557
                                'id'    => 'wpseo-yoast-help',
×
558
                                'title' => __( 'Yoast.com help section', 'wordpress-seo' ),
×
559
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-yoast-help' ),
×
UNCOV
560
                        ],
×
UNCOV
561
                        [
×
562
                                'id'    => 'wpseo-premium-support',
×
563
                                'title' => __( 'Yoast Premium support', 'wordpress-seo' ),
×
564
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-premium-support' ),
×
UNCOV
565
                        ],
×
UNCOV
566
                        [
×
567
                                'id'    => 'wpseo-wp-support-forums',
×
568
                                'title' => __( 'WordPress.org support forums', 'wordpress-seo' ),
×
569
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-wp-support-forums' ),
×
UNCOV
570
                        ],
×
UNCOV
571
                        [
×
572
                                'id'    => 'wpseo-learn-seo-2',
×
573
                                'title' => __( 'Learn more SEO', 'wordpress-seo' ),
×
574
                                'href'  => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-learn-more-seo-help' ),
×
UNCOV
575
                        ],
×
UNCOV
576
                ];
×
577

578
                $this->add_submenu_items( $submenu_items, $wp_admin_bar, 'wpseo-sub-get-help' );
×
579
        }
580

581
        /**
582
         * Adds the admin bar How To submenu.
583
         *
584
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
585
         *
586
         * @return void
587
         */
588
        protected function add_premium_link( WP_Admin_Bar $wp_admin_bar ) {
×
589
                $sale_percentage = '';
×
590
                if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-2023-promotion' ) ) {
×
591
                        $sale_percentage = sprintf(
×
592
                                '<span class="admin-bar-premium-promotion">%1$s</span>',
×
593
                                esc_html__( '-30%', 'wordpress-seo' )
×
UNCOV
594
                        );
×
595
                }
596
                $wp_admin_bar->add_menu(
×
UNCOV
597
                        [
×
598
                                'parent' => self::MENU_IDENTIFIER,
×
599
                                'id'     => 'wpseo-get-premium',
×
600
                                // Circumvent an issue in the WP admin bar API in order to pass `data` attributes. See https://core.trac.wordpress.org/ticket/38636.
601
                                'title'  => sprintf(
×
602
                                        '<a href="%1$s" target="_blank" data-action="load-nfd-ctb" data-ctb-id="f6a84663-465f-4cb5-8ba5-f7a6d72224b2" style="padding:0;">%2$s &raquo; %3$s</a>',
×
603
                                        esc_url( $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-get-premium' ) ),
×
604
                                        esc_html__( 'Get Yoast SEO Premium', 'wordpress-seo' ),
×
605
                                        $sale_percentage
×
UNCOV
606
                                ),
×
UNCOV
607
                                'meta'   => [
×
UNCOV
608
                                        'tabindex' => '0',
×
UNCOV
609
                                ],
×
UNCOV
610
                        ]
×
UNCOV
611
                );
×
612
        }
613

614
        /**
615
         * Adds the admin bar settings submenu.
616
         *
617
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
618
         *
619
         * @return void
620
         */
621
        protected function add_settings_submenu( WP_Admin_Bar $wp_admin_bar ) {
×
622
                if ( ! $this->can_manage_options() ) {
×
623
                        return;
×
624
                }
625

626
                $admin_menu    = new WPSEO_Admin_Menu( new WPSEO_Menu() );
×
627
                $submenu_pages = $admin_menu->get_submenu_pages();
×
628

UNCOV
629
                $menu_args = [
×
630
                        'parent' => self::MENU_IDENTIFIER,
×
UNCOV
631
                        'id'     => self::SETTINGS_SUBMENU_IDENTIFIER,
×
632
                        'title'  => __( 'SEO Settings', 'wordpress-seo' ),
×
UNCOV
633
                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
634
                ];
×
635
                $wp_admin_bar->add_menu( $menu_args );
×
636

637
                foreach ( $submenu_pages as $submenu_page ) {
×
638
                        if ( ! current_user_can( $submenu_page[3] ) ) {
×
639
                                continue;
×
640
                        }
641

642
                        // Don't add the Google Search Console menu item.
643
                        if ( $submenu_page[4] === 'wpseo_search_console' ) {
×
644
                                continue;
×
645
                        }
646

647
                        $id = 'wpseo-' . str_replace( '_', '-', str_replace( 'wpseo_', '', $submenu_page[4] ) );
×
648
                        if ( $id === 'wpseo-dashboard' ) {
×
649
                                $id = 'wpseo-general';
×
650
                        }
651

UNCOV
652
                        $menu_args = [
×
653
                                'parent' => self::SETTINGS_SUBMENU_IDENTIFIER,
×
654
                                'id'     => $id,
×
655
                                'title'  => $submenu_page[2],
×
656
                                'href'   => admin_url( 'admin.php?page=' . rawurlencode( $submenu_page[4] ) ),
×
UNCOV
657
                        ];
×
658
                        $wp_admin_bar->add_menu( $menu_args );
×
659
                }
660
        }
661

662
        /**
663
         * Adds the admin bar network settings submenu.
664
         *
665
         * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to.
666
         *
667
         * @return void
668
         */
669
        protected function add_network_settings_submenu( WP_Admin_Bar $wp_admin_bar ) {
×
670
                if ( ! $this->can_manage_options() ) {
×
671
                        return;
×
672
                }
673

674
                $network_admin_menu = new WPSEO_Network_Admin_Menu( new WPSEO_Menu() );
×
675
                $submenu_pages      = $network_admin_menu->get_submenu_pages();
×
676

UNCOV
677
                $menu_args = [
×
678
                        'parent' => self::MENU_IDENTIFIER,
×
UNCOV
679
                        'id'     => self::NETWORK_SETTINGS_SUBMENU_IDENTIFIER,
×
680
                        'title'  => __( 'SEO Settings', 'wordpress-seo' ),
×
UNCOV
681
                        'meta'   => [ 'tabindex' => '0' ],
×
UNCOV
682
                ];
×
683
                $wp_admin_bar->add_menu( $menu_args );
×
684

685
                foreach ( $submenu_pages as $submenu_page ) {
×
686
                        if ( ! current_user_can( $submenu_page[3] ) ) {
×
687
                                continue;
×
688
                        }
689

690
                        $id = 'wpseo-' . str_replace( '_', '-', str_replace( 'wpseo_', '', $submenu_page[4] ) );
×
691
                        if ( $id === 'wpseo-dashboard' ) {
×
692
                                $id = 'wpseo-general';
×
693
                        }
694

UNCOV
695
                        $menu_args = [
×
696
                                'parent' => self::NETWORK_SETTINGS_SUBMENU_IDENTIFIER,
×
697
                                'id'     => $id,
×
698
                                'title'  => $submenu_page[2],
×
699
                                'href'   => network_admin_url( 'admin.php?page=' . rawurlencode( $submenu_page[4] ) ),
×
UNCOV
700
                        ];
×
701
                        $wp_admin_bar->add_menu( $menu_args );
×
702
                }
703
        }
704

705
        /**
706
         * Gets the menu title markup.
707
         *
708
         * @return string Admin bar title markup.
709
         */
710
        protected function get_title() {
×
711
                return '<div id="yoast-ab-icon" class="ab-item yoast-logo svg"><span class="screen-reader-text">' . __( 'SEO', 'wordpress-seo' ) . '</span></div>';
×
712
        }
713

714
        /**
715
         * Gets the current post if in a singular post context.
716
         *
717
         * @global string       $pagenow Current page identifier.
718
         * @global WP_Post|null $post    Current post object, or null if none available.
719
         *
720
         * @return WP_Post|null Post object, or null if not in singular context.
721
         */
722
        protected function get_singular_post() {
×
723
                global $pagenow, $post;
×
724

725
                if ( ! is_singular() && ( ! is_blog_admin() || ! WPSEO_Metabox::is_post_edit( $pagenow ) ) ) {
×
726
                        return null;
×
727
                }
728

729
                if ( ! isset( $post ) || ! is_object( $post ) || ! $post instanceof WP_Post ) {
×
730
                        return null;
×
731
                }
732

733
                return $post;
×
734
        }
735

736
        /**
737
         * Gets the focus keyword for a given post.
738
         *
739
         * @param WP_Post $post Post object to get its focus keyword.
740
         *
741
         * @return string Focus keyword, or empty string if none available.
742
         */
UNCOV
743
        protected function get_post_focus_keyword( $post ) {
×
UNCOV
744
                if ( ! is_object( $post ) || ! property_exists( $post, 'ID' ) ) {
×
UNCOV
745
                        return '';
×
746
                }
747

748
                /**
749
                 * Filter: 'wpseo_use_page_analysis' Determines if the analysis should be enabled.
750
                 *
751
                 * @param bool $enabled Determines if the analysis should be enabled.
752
                 */
UNCOV
753
                if ( apply_filters( 'wpseo_use_page_analysis', true ) !== true ) {
×
UNCOV
754
                        return '';
×
755
                }
756

UNCOV
757
                return WPSEO_Meta::get_value( 'focuskw', $post->ID );
×
758
        }
759

760
        /**
761
         * Gets the score for a given post.
762
         *
763
         * @param WP_Post $post Post object to get its score.
764
         *
765
         * @return string Score markup, or empty string if none available.
766
         */
767
        protected function get_post_score( $post ) {
×
768
                if ( ! is_object( $post ) || ! property_exists( $post, 'ID' ) ) {
×
769
                        return '';
×
770
                }
771

772
                if ( apply_filters( 'wpseo_use_page_analysis', true ) !== true ) {
×
773
                        return '';
×
774
                }
775

776
                return $this->get_score_icon();
×
777
        }
778

779
        /**
780
         * Gets the current term if in a singular term context.
781
         *
782
         * @global string       $pagenow  Current page identifier.
783
         * @global WP_Query     $wp_query Current query object.
784
         * @global WP_Term|null $tag      Current term object, or null if none available.
785
         *
786
         * @return WP_Term|null Term object, or null if not in singular context.
787
         */
788
        protected function get_singular_term() {
×
789
                global $pagenow, $wp_query, $tag;
×
790

791
                if ( is_category() || is_tag() || is_tax() ) {
×
792
                        return $wp_query->get_queried_object();
×
793
                }
794

795
                if ( WPSEO_Taxonomy::is_term_edit( $pagenow ) && ! WPSEO_Taxonomy::is_term_overview( $pagenow ) && isset( $tag ) && is_object( $tag ) && ! is_wp_error( $tag ) ) {
×
796
                        return get_term( $tag->term_id );
×
797
                }
798

799
                return null;
×
800
        }
801

802
        /**
803
         * Gets the score for a given term.
804
         *
805
         * @param WP_Term $term Term object to get its score.
806
         *
807
         * @return string Score markup, or empty string if none available.
808
         */
809
        protected function get_term_score( $term ) {
×
810
                if ( ! is_object( $term ) || ! property_exists( $term, 'term_id' ) || ! property_exists( $term, 'taxonomy' ) ) {
×
811
                        return '';
×
812
                }
813

814
                return $this->get_score_icon();
×
815
        }
816

817
        /**
818
         * Create the score icon.
819
         *
820
         * @return string The score icon, or empty string.
821
         */
822
        protected function get_score_icon() {
×
823
                $is_seo_enabled         = $this->get_is_seo_enabled();
×
824
                $is_readability_enabled = $this->get_is_readability_enabled();
×
825

826
                $indexable = $this->get_current_indexable();
×
827

828
                if ( $is_seo_enabled ) {
×
829
                        return $this->score_icon_helper->for_seo( $indexable, 'adminbar-seo-score' )->present();
×
830
                }
831

832
                if ( $is_readability_enabled ) {
×
833
                        return $this->score_icon_helper->for_readability( $indexable->readability_score, 'adminbar-seo-score' )
×
834
                                ->present();
×
835
                }
836

837
                return '';
×
838
        }
839

840
        /**
841
         * Gets the URL to the main admin settings page.
842
         *
843
         * @return string Admin settings page URL.
844
         */
845
        protected function get_settings_page_url() {
×
846
                return self_admin_url( 'admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER );
×
847
        }
848

849
        /**
850
         * Gets the notification counter if in a valid context.
851
         *
852
         * @return string Notification counter markup, or empty string if not available.
853
         */
854
        protected function get_notification_counter() {
×
855
                $notification_center = Yoast_Notification_Center::get();
×
856
                $notification_count  = $notification_center->get_notification_count();
×
857

858
                if ( ! $notification_count ) {
×
859
                        return '';
×
860
                }
861

862
                /* translators: Hidden accessibility text; %s: number of notifications. */
863
                $counter_screen_reader_text = sprintf( _n( '%s notification', '%s notifications', $notification_count, 'wordpress-seo' ), number_format_i18n( $notification_count ) );
×
864

865
                return sprintf( ' <div class="wp-core-ui wp-ui-notification yoast-issue-counter"><span class="yoast-issues-count" aria-hidden="true">%d</span><span class="screen-reader-text">%s</span></div>', $notification_count, $counter_screen_reader_text );
×
866
        }
867

868
        /**
869
         * Gets the notification popup if in a valid context.
870
         *
871
         * @return string Notification popup markup, or empty string if not available.
872
         */
873
        protected function get_notification_popup() {
×
874
                $notification_center     = Yoast_Notification_Center::get();
×
875
                $new_notifications       = $notification_center->get_new_notifications();
×
876
                $new_notifications_count = count( $new_notifications );
×
877

878
                if ( ! $new_notifications_count ) {
×
879
                        return '';
×
880
                }
881

882
                $notification = sprintf(
×
883
                        _n(
×
884
                                'There is a new notification.',
×
885
                                'There are new notifications.',
×
886
                                $new_notifications_count,
×
887
                                'wordpress-seo'
×
UNCOV
888
                        ),
×
889
                        $new_notifications_count
×
UNCOV
890
                );
×
891

892
                return '<div class="yoast-issue-added">' . $notification . '</div>';
×
893
        }
894

895
        /**
896
         * Checks whether the current user can manage options in the current context.
897
         *
898
         * @return bool True if capabilities are sufficient, false otherwise.
899
         */
900
        protected function can_manage_options() {
×
901
                return ( is_network_admin() && current_user_can( 'wpseo_manage_network_options' ) )
×
902
                        || ( ! is_network_admin() && WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) );
×
903
        }
904

905
        /**
906
         * Add submenu items to a menu item.
907
         *
908
         * @param array        $submenu_items Submenu items array.
909
         * @param WP_Admin_Bar $wp_admin_bar  Admin bar object.
910
         * @param string       $parent_id     Parent menu item ID.
911
         *
912
         * @return void
913
         */
914
        protected function add_submenu_items( array $submenu_items, WP_Admin_Bar $wp_admin_bar, $parent_id ) {
×
915
                foreach ( $submenu_items as $menu_item ) {
×
UNCOV
916
                        $menu_args = [
×
917
                                'parent' => $parent_id,
×
918
                                'id'     => $menu_item['id'],
×
919
                                'title'  => $menu_item['title'],
×
920
                                'href'   => $menu_item['href'],
×
UNCOV
921
                                'meta'   => [ 'target' => '_blank' ],
×
UNCOV
922
                        ];
×
923
                        $wp_admin_bar->add_menu( $menu_args );
×
924
                }
925
        }
926
}
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