PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.5
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
← All changes | admin/class-admin-init.php +86 -204 18.128.5 View file →
@@ -35,8 +35,9 @@
35 35 $this->asset_manager = new WPSEO_Admin_Asset_Manager();
36 36
37 37 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_dismissible' ] );
38 38 add_action( 'admin_init', [ $this, 'unsupported_php_notice' ], 15 );
39 + add_action( 'admin_init', [ $this, 'remove_translations_notification' ], 15 );
39 40 add_action( 'admin_init', [ $this->asset_manager, 'register_assets' ] );
40 41 add_action( 'admin_init', [ $this, 'show_hook_deprecation_warnings' ] );
41 42 add_action( 'admin_init', [ 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ] );
42 43 add_action( 'admin_notices', [ $this, 'permalink_settings_notice' ] );
@@ -41,27 +42,8 @@
41 42 add_action( 'admin_init', [ 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ] );
42 43 add_action( 'admin_notices', [ $this, 'permalink_settings_notice' ] );
43 44 add_action( 'post_submitbox_misc_actions', [ $this, 'add_publish_box_section' ] );
44 45
45 - /*
46 - * The `admin_notices` hook fires on single site admin pages vs.
47 - * `network_admin_notices` which fires on multisite admin pages and
48 - * `user_admin_notices` which fires on multisite user admin pagss.
49 - */
50 - add_action( 'admin_notices', [ $this, 'search_engines_discouraged_notice' ] );
51 -
52 - $health_checks = [
53 - new WPSEO_Health_Check_Page_Comments(),
54 - new WPSEO_Health_Check_Ryte(),
55 - new WPSEO_Health_Check_Postname_Permalink(),
56 - new WPSEO_Health_Check_Curl_Version(),
57 - new WPSEO_Health_Check_Link_Table_Not_Accessible(),
58 - ];
59 -
60 - foreach ( $health_checks as $health_check ) {
61 - $health_check->register_test();
62 - }
63 -
64 46 $this->load_meta_boxes();
65 47 $this->load_taxonomy_class();
66 48 $this->load_admin_page_class();
67 49 $this->load_admin_user_class();
@@ -70,8 +52,10 @@
70 52 }
71 53
72 54 /**
73 55 * Enqueue our styling for dismissible yoast notifications.
56 + *
57 + * @return void
74 58 */
75 59 public function enqueue_dismissible() {
76 60 $this->asset_manager->enqueue_style( 'dismissible' );
77 61 }
@@ -76,8 +60,18 @@
76 60 $this->asset_manager->enqueue_style( 'dismissible' );
77 61 }
78 62
79 63 /**
64 + * Removes any notification for incomplete translations.
65 + *
66 + * @return void
67 + */
68 + public function remove_translations_notification() {
69 + $notification_center = Yoast_Notification_Center::get();
70 + $notification_center->remove_notification_by_id( 'i18nModuleTranslationAssistance' );
71 + }
72 +
73 + /**
80 74 * Creates an unsupported PHP version notification in the notification center.
81 75 *
82 76 * @return void
83 77 */
@@ -114,28 +108,59 @@
114 108 *
115 109 * @return bool
116 110 */
117 111 private function on_wpseo_admin_page() {
118 - return $this->pagenow === 'admin.php' && strpos( filter_input( INPUT_GET, 'page' ), 'wpseo' ) === 0;
112 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
113 + if ( ! isset( $_GET['page'] ) || ! is_string( $_GET['page'] ) ) {
114 + return false;
115 + }
116 +
117 + if ( $this->pagenow !== 'admin.php' ) {
118 + return false;
119 + }
120 +
121 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
122 + $current_page = sanitize_text_field( wp_unslash( $_GET['page'] ) );
123 + return strpos( $current_page, 'wpseo' ) === 0;
119 124 }
120 125
121 126 /**
122 - * Determine whether we should load the meta box class and if so, load it.
127 + * Whether we should load the meta box classes.
128 + *
129 + * @return bool true if we should load the meta box classes, false otherwise.
123 130 */
124 - private function load_meta_boxes() {
125 -
126 - $is_editor = WPSEO_Metabox::is_post_overview( $this->pagenow ) || WPSEO_Metabox::is_post_edit( $this->pagenow );
127 - $is_inline_save = filter_input( INPUT_POST, 'action' ) === 'inline-save';
128 -
131 + private function should_load_meta_boxes() {
129 132 /**
130 133 * Filter: 'wpseo_always_register_metaboxes_on_admin' - Allow developers to change whether
131 134 * the WPSEO metaboxes are only registered on the typical pages (lean loading) or always
132 135 * registered when in admin.
133 136 *
134 - * @api bool Whether to always register the metaboxes or not. Defaults to false.
137 + * @param bool $register_metaboxes Whether to always register the metaboxes or not. Defaults to false.
135 138 */
136 - if ( $is_editor || $is_inline_save || apply_filters( 'wpseo_always_register_metaboxes_on_admin', false )
137 - ) {
139 + if ( apply_filters( 'wpseo_always_register_metaboxes_on_admin', false ) ) {
140 + return true;
141 + }
142 +
143 + // If we are in a post editor.
144 + if ( WPSEO_Metabox::is_post_overview( $this->pagenow ) || WPSEO_Metabox::is_post_edit( $this->pagenow ) ) {
145 + return true;
146 + }
147 +
148 + // If we are doing an inline save.
149 + if ( check_ajax_referer( 'inlineeditnonce', '_inline_edit', false ) && isset( $_POST['action'] ) && sanitize_text_field( wp_unslash( $_POST['action'] ) ) === 'inline-save' ) {
150 + return true;
151 + }
152 +
153 + return false;
154 + }
155 +
156 + /**
157 + * Determine whether we should load the meta box class and if so, load it.
158 + *
159 + * @return void
160 + */
161 + private function load_meta_boxes() {
162 + if ( $this->should_load_meta_boxes() ) {
138 163 $GLOBALS['wpseo_metabox'] = new WPSEO_Metabox();
139 164 $GLOBALS['wpseo_meta_columns'] = new WPSEO_Meta_Columns();
140 165 }
141 166 }
@@ -141,8 +166,10 @@
141 166 }
142 167
143 168 /**
144 169 * Determine if we should load our taxonomy edit class and if so, load it.
170 + *
171 + * @return void
145 172 */
146 173 private function load_taxonomy_class() {
147 174 if (
148 175 WPSEO_Taxonomy::is_term_edit( $this->pagenow )
@@ -155,8 +182,10 @@
155 182 /**
156 183 * Determine if we should load our admin pages class and if so, load it.
157 184 *
158 185 * Loads admin page class for all admin pages starting with `wpseo_`.
186 + *
187 + * @return void
159 188 */
160 189 private function load_admin_user_class() {
161 190 if ( in_array( $this->pagenow, [ 'user-edit.php', 'profile.php' ], true )
162 191 && current_user_can( 'edit_users' )
@@ -168,8 +197,10 @@
168 197 /**
169 198 * Determine if we should load our admin pages class and if so, load it.
170 199 *
171 200 * Loads admin page class for all admin pages starting with `wpseo_`.
201 + *
202 + * @return void
172 203 */
173 204 private function load_admin_page_class() {
174 205
175 206 if ( $this->on_wpseo_admin_page() ) {
@@ -175,21 +206,27 @@
175 206 if ( $this->on_wpseo_admin_page() ) {
176 207 // For backwards compatabilty, this still needs a global, for now...
177 208 $GLOBALS['wpseo_admin_pages'] = new WPSEO_Admin_Pages();
178 209
179 - $page = filter_input( INPUT_GET, 'page' );
180 - // Only register the yoast i18n when the page is a Yoast SEO page.
181 - if ( WPSEO_Utils::is_yoast_seo_free_page( $page ) ) {
182 - $this->register_i18n_promo_class();
183 - if ( $page !== 'wpseo_titles' ) {
184 - $this->register_premium_upsell_admin_block();
185 - }
210 + $page = null;
211 +
212 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
213 + if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) {
214 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
215 + $page = sanitize_text_field( wp_unslash( $_GET['page'] ) );
186 216 }
217 +
218 + // Only renders Yoast SEO Premium upsells when the page is a Yoast SEO page.
219 + if ( $page !== null && WPSEO_Utils::is_yoast_seo_free_page( $page ) ) {
220 + $this->register_premium_upsell_admin_block();
221 + }
187 222 }
188 223 }
189 224
190 225 /**
191 226 * Loads the plugin suggestions.
227 + *
228 + * @return void
192 229 */
193 230 private function load_plugin_suggestions() {
194 231 $suggestions = new WPSEO_Suggested_Plugins( new WPSEO_Plugin_Availability(), Yoast_Notification_Center::get() );
195 232 $suggestions->register_hooks();
@@ -207,69 +244,23 @@
207 244 }
208 245 }
209 246
210 247 /**
211 - * Registers the promotion class for our GlotPress instance, then creates a notification with the i18n promo.
248 + * See if we should start our XML Sitemaps Admin class.
212 249 *
213 - * @link https://github.com/Yoast/i18n-module
250 + * @return void
214 251 */
215 - private function register_i18n_promo_class() {
216 - // BC, because an older version of the i18n-module didn't have this class.
217 - $i18n_module = new Yoast_I18n_WordPressOrg_v3(
218 - [
219 - 'textdomain' => 'wordpress-seo',
220 - 'plugin_name' => 'Yoast SEO',
221 - 'hook' => 'wpseo_admin_promo_footer',
222 - ],
223 - false
224 - );
225 -
226 - $message = $i18n_module->get_promo_message();
227 -
228 - if ( $message !== '' ) {
229 - $message .= $i18n_module->get_dismiss_i18n_message_button();
230 - }
231 -
232 - $notification_center = Yoast_Notification_Center::get();
233 -
234 - $notification = new Yoast_Notification(
235 - $message,
236 - [
237 - 'type' => Yoast_Notification::WARNING,
238 - 'id' => 'i18nModuleTranslationAssistance',
239 - ]
240 - );
241 -
242 - if ( $message ) {
243 - $notification_center->add_notification( $notification );
244 -
245 - return;
246 - }
247 -
248 - $notification_center->remove_notification( $notification );
249 - }
250 -
251 - /**
252 - * See if we should start our XML Sitemaps Admin class.
253 - */
254 252 private function load_xml_sitemaps_admin() {
255 - if ( WPSEO_Options::get( 'enable_xml_sitemap', false ) ) {
253 + if ( WPSEO_Options::get( 'enable_xml_sitemap', false, [ 'wpseo' ] ) ) {
256 254 new WPSEO_Sitemaps_Admin();
257 255 }
258 256 }
259 257
260 258 /**
261 - * Checks whether search engines are discouraged from indexing the site.
259 + * Shows deprecation warnings to the user if a plugin has registered a filter we have deprecated.
262 260 *
263 - * @return bool Whether search engines are discouraged from indexing the site.
261 + * @return void
264 262 */
265 - private function are_search_engines_discouraged() {
266 - return (string) get_option( 'blog_public' ) === '0';
267 - }
268 -
269 - /**
270 - * Shows deprecation warnings to the user if a plugin has registered a filter we have deprecated.
271 - */
272 263 public function show_hook_deprecation_warnings() {
273 264 global $wp_filter;
274 265
275 266 if ( wp_doing_ajax() ) {
@@ -314,9 +305,9 @@
314 305
315 306 // Determine which filters have been registered.
316 307 $deprecated_notices = array_intersect(
317 308 array_keys( $deprecated_filters ),
318 - array_keys( $wp_filter )
309 + array_keys( $wp_filter ),
319 310 );
320 311
321 312 // Show notice for each deprecated filter or action that has been registered.
322 313 foreach ( $deprecated_notices as $deprecated_filter ) {
@@ -324,9 +315,9 @@
324 315 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Only uses the hardcoded values from above.
325 316 _deprecated_hook(
326 317 $deprecated_filter,
327 318 'WPSEO ' . $deprecation_info['version'],
328 - $deprecation_info['alternative']
319 + $deprecation_info['alternative'],
329 320 );
330 321 // phpcs:enable
331 322 }
332 323 }
@@ -341,8 +332,10 @@
341 332 }
342 333
343 334 /**
344 335 * Shows a notice on the permalink settings page.
336 + *
337 + * @return void
345 338 */
346 339 public function permalink_settings_notice() {
347 340 global $pagenow;
348 341
@@ -353,68 +346,21 @@
353 346 sprintf(
354 347 /* translators: %1$s and %2$s expand to <em> items to emphasize the word in the middle. */
355 348 esc_html__( 'Changing your permalinks settings can seriously impact your search engine visibility. It should almost %1$s never %2$s be done on a live website.', 'wordpress-seo' ),
356 349 '<em>',
357 - '</em>'
350 + '</em>',
358 351 ),
359 352 esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/why-permalinks/' ) ),
360 353 // The link's content.
361 - esc_html__( 'Learn about why permalinks are important for SEO.', 'wordpress-seo' )
354 + esc_html__( 'Learn about why permalinks are important for SEO.', 'wordpress-seo' ),
362 355 );
363 356 }
364 357 }
365 358
366 359 /**
367 - * Determines whether and where the "search engines discouraged" admin notice should be displayed.
368 - *
369 - * @return bool Whether the "search engines discouraged" admin notice should be displayed.
370 - */
371 - private function should_display_search_engines_discouraged_notice() {
372 - $discouraged_pages = [
373 - 'index.php',
374 - 'plugins.php',
375 - 'update-core.php',
376 - ];
377 -
378 - return (
379 - $this->are_search_engines_discouraged()
380 - && WPSEO_Capability_Utils::current_user_can( 'manage_options' )
381 - && WPSEO_Options::get( 'ignore_search_engines_discouraged_notice', false ) === false
382 - && (
383 - $this->on_wpseo_admin_page()
384 - || in_array( $this->pagenow, $discouraged_pages, true )
385 - )
386 - );
387 - }
388 -
389 - /**
390 - * Displays an admin notice when WordPress is set to discourage search engines from indexing the site.
391 - *
392 - * @return void
393 - */
394 - public function search_engines_discouraged_notice() {
395 - if ( ! $this->should_display_search_engines_discouraged_notice() ) {
396 - return;
397 - }
398 -
399 - printf(
400 - '<div id="robotsmessage" class="notice notice-error"><p><strong>%1$s</strong> %2$s <button type="button" id="robotsmessage-dismiss-button" class="button-link hide-if-no-js" data-nonce="%3$s">%4$s</button></p></div>',
401 - esc_html__( 'Huge SEO Issue: You\'re blocking access to robots.', 'wordpress-seo' ),
402 - sprintf(
403 - /* translators: 1: Link start tag to the WordPress Reading Settings page, 2: Link closing tag. */
404 - esc_html__( 'If you want search engines to show this site in their results, you must %1$sgo to your Reading Settings%2$s and uncheck the box for Search Engine Visibility.', 'wordpress-seo' ),
405 - '<a href="' . esc_url( admin_url( 'options-reading.php' ) ) . '">',
406 - '</a>'
407 - ),
408 - esc_js( wp_create_nonce( 'wpseo-ignore' ) ),
409 - esc_html__( 'I don\'t want this site to show in the search results.', 'wordpress-seo' )
410 - );
411 - }
412 -
413 - /**
414 360 * Adds a custom Yoast section within the Classic Editor publish box.
415 361 *
416 - * @param \WP_Post $post The current post object.
362 + * @param WP_Post $post The current post object.
417 363 *
418 364 * @return void
419 365 */
420 366 public function add_publish_box_section( $post ) {
@@ -424,74 +370,10 @@
424 370 <?php
425 371 /**
426 372 * Fires after the post time/date setting in the Publish meta box.
427 373 *
428 - * @api \WP_Post The current post object.
374 + * @param WP_Post $post The current post object.
429 375 */
430 376 do_action( 'wpseo_publishbox_misc_actions', $post );
431 377 }
432 - }
433 -
434 - /* ********************* DEPRECATED METHODS ********************* */
435 -
436 - /**
437 - * Notify about the default tagline if the user hasn't changed it.
438 - *
439 - * @deprecated 13.2
440 - * @codeCoverageIgnore
441 - */
442 - public function tagline_notice() {
443 - _deprecated_function( __METHOD__, 'WPSEO 13.2' );
444 - }
445 -
446 - /**
447 - * Returns whether or not the site has the default tagline.
448 - *
449 - * @deprecated 13.2
450 - * @codeCoverageIgnore
451 - *
452 - * @return bool
453 - */
454 - public function has_default_tagline() {
455 - _deprecated_function( __METHOD__, 'WPSEO 13.2' );
456 -
457 - $blog_description = get_bloginfo( 'description' );
458 - $default_blog_description = 'Just another WordPress site';
459 -
460 - // We are using the WordPress internal translation.
461 - $translated_blog_description = __( 'Just another WordPress site', 'default' );
462 -
463 - return $translated_blog_description === $blog_description || $default_blog_description === $blog_description;
464 - }
465 -
466 - /**
467 - * Shows an alert when the permalink doesn't contain %postname%.
468 - *
469 - * @deprecated 13.2
470 - * @codeCoverageIgnore
471 - */
472 - public function permalink_notice() {
473 - _deprecated_function( __METHOD__, 'WPSEO 13.2' );
474 - }
475 -
476 - /**
477 - * Add an alert if the blog is not publicly visible.
478 - *
479 - * @deprecated 14.1
480 - * @codeCoverageIgnore
481 - */
482 - public function blog_public_notice() {
483 - _deprecated_function( __METHOD__, 'WPSEO 14.1' );
484 - }
485 -
486 - /**
487 - * Handles the notifiers for the dashboard page.
488 - *
489 - * @deprecated 14.1
490 - * @codeCoverageIgnore
491 - *
492 - * @return void
493 - */
494 - public function handle_notifications() {
495 - _deprecated_function( __METHOD__, 'WPSEO 14.1' );
496 378 }
497 379 }