Yoast SEO - Version 14.1

Version Description

Release Date: May 13th, 2020

Despite weeks and weeks of testing Yoast SEO 14.0, there were still some people running into issues. In Yoast SEO 14.1, were improving things to help stabilize the plugin. Read more about those changes in our release post!

Bugfixes:

  • Fixes a bug where the help text about Yoast Columns would be shown in the Help Tab on post overviews when there were no Yoast Columns. Additionally, the help text has been refined to only show information about columns that are actually shown. Props to glebkema.
  • Fixes a bug where an empty breadcrumb would be output when a taxonomy was set to have a post type archive in its breadcrumb when that post type didn't have an archive.
  • Fixes a bug where a part of the breadcrumb path was missing on search result pages.
  • Fixes a bug where an error would be thrown and indexing could not be completed due to posts or terms having themselves as a parent or grandparent.
  • Fixes a bug where the SEO data was unnecessarily being indexed when a non-public term or taxonomy was being saved.
  • Fixes a bug where the SEO data of an object would be indexed twice during the indexing process when it was an ancestor of another object in the same REST request.
  • Fixes a bug where huge log files would be generated if PHP was configured to also log the arguments in debug backtraces.
  • Fixes a bug where indexing would continue even though it had already indexed all objects.
  • Fixes a bug where term indexing would keep going on forever due to plugin conflicts.
  • Fixes a bug where primary terms of a custom taxonomy where not being reflected in the breadcrumb.
  • Fixes a bug where the URL in the schema breadcrumbs of search pages would be missing.
  • Fixes a bug where the wpseo_remove_reply_to_com filter was not working.
  • Fixes a bug where no metadata would be output on the frontend when the tables necessary for the indexables could not be created
  • Fixes a bug where the indexing notification would be shown on the WordPress updates page when updating themes or plugins.
  • Fixes a bug where the yoast index --network WP CLI command would throw an error when the database migrations for one or more subsites on a multisite environment had not been run yet.
  • Fixes a bug where no or incorrect breadcrumbs where shown for 404 pages, author archives and date archives. Props to amitsidhpura.

Enhancements:

  • Moves the text link counter notification from the SEO Dashboard to the WordPress' Site Health.
  • Makes the "You're blocking access to robots" notification site-wide.
  • Improves the copy for the "cannot fetch" response of the Ryte health check.
  • Removes the notification containing the message that you should check your post type archive settings when these are possibly reset to their defaults in Yoast SEO 7.7 or 7.8.
  • Reimplements the Advanced Settings tab in React.
  • Improves the ordering of items in XML sitemaps to match SQL standards. Props to rafaelbernard.
  • Improves the transition word assessment for Hungarian. Props to @Zsoru.
  • Adds the --reindex flag to the indexables WP CLI command to remove all existing indexables and then reindex all content.
  • Adds the wpseo_robots_array filter to enable the filtering of the robots array used for the robots meta tag output.
  • Adds the wpseo_shutdown_indexation_limit filter to enable the filtering of the number of objects that can remain unindexed. These remaining objects will automatically be indexed without needing any user interaction as a shutdown function.
  • Adds debug information to the error that is shown when Yoast SEO was unable to create the necessary database tables.
  • Optimizes finding attachments by URL. This addresses a primary cause of higher server load issues occurring since 14.0.
  • Adds a warning to the metabox that is shown when a user enters a focus keyphrase that contains more than 191 characters.
  • Makes the copy of the indexing setting in the advanced tab consistent between all contexts (post, page, category, etc.).
  • Adds the term_id for terms in the object that can be filtered with the wpseo_breadcrumb_links and wpseo_breadcrumb_single_link_info filters. Props to amitsidhpura.
  • Adds a time estimation to the indexing notification based on the amount of objects that need to be indexed.
  • Adds a button to the indexing notification to hide it for a week when more than 2500 objects need to be indexed.
  • Improves the notification that is shown when there were problems creating the necessary database tables.

Other

  • Deletes the unnecessarily created indexables of private taxonomies.
Download this release

Release Info

Developer Yoast
Plugin Icon 128x128 Yoast SEO
Version 14.1
Comparing to
See all releases

Code changes from version 14.0.4 to 14.1

Files changed (154) hide show
  1. admin/ajax.php +17 -1
  2. admin/class-admin-asset-dev-server-location.php +1 -1
  3. admin/class-admin-asset-manager.php +15 -15
  4. admin/class-admin-init.php +79 -119
  5. admin/class-admin.php +1 -8
  6. admin/class-gutenberg-compatibility.php +2 -2
  7. admin/class-yoast-columns.php +74 -10
  8. admin/class-yoast-form.php +6 -6
  9. admin/class-yoast-input-validation.php +1 -1
  10. admin/class-yoast-notification-center.php +1 -1
  11. admin/class-yoast-notification.php +2 -2
  12. admin/{class-yoast-alerts.php → class-yoast-notifications.php} +114 -44
  13. admin/formatter/class-metabox-formatter.php +3 -3
  14. admin/import/plugins/class-import-greg-high-performance-seo.php +0 -1
  15. admin/import/plugins/class-import-jetpack.php +0 -1
  16. admin/import/plugins/class-import-ultimate-seo.php +0 -1
  17. admin/links/class-link-table-accessible-notifier.php +0 -68
  18. admin/metabox/class-metabox.php +10 -22
  19. admin/notifiers/class-post-type-archive-notification-handler.php +0 -190
  20. admin/pages/tools.php +1 -2
  21. admin/roles/class-abstract-role-manager.php +4 -5
  22. admin/ryte/class-ryte.php +1 -1
  23. admin/services/class-indexable.php +0 -1
  24. admin/taxonomy/class-taxonomy-metabox.php +1 -12
  25. admin/taxonomy/class-taxonomy-settings-fields.php +9 -74
  26. admin/taxonomy/class-taxonomy.php +24 -12
  27. admin/views/{partial-alerts-errors.php → partial-notifications-errors.php} +5 -5
  28. admin/views/{partial-alerts-template.php → partial-notifications-template.php} +16 -16
  29. admin/views/{partial-alerts-warnings.php → partial-notifications-warnings.php} +7 -7
  30. admin/views/tabs/dashboard/dashboard.php +5 -5
  31. admin/views/tabs/metas/archives.php +2 -2
  32. admin/views/tabs/metas/breadcrumbs.php +1 -1
  33. admin/views/tabs/metas/general.php +1 -1
  34. admin/views/tabs/metas/media.php +1 -1
  35. admin/views/tabs/metas/paper-content/general-content.php +4 -4
  36. admin/views/tabs/metas/paper-content/media-content.php +12 -9
  37. admin/views/tabs/metas/paper-content/post-type-content.php +2 -2
  38. admin/views/tabs/metas/post-types.php +1 -1
  39. admin/views/tabs/metas/rss.php +1 -1
  40. admin/views/tabs/metas/taxonomies.php +2 -2
  41. config/dependency-injection/custom-loader.php +1 -1
  42. config/dependency-injection/loader-pass.php +1 -1
  43. css/dist/admin-global-1404-rtl.css +0 -1
  44. css/dist/admin-global-1404.css +0 -1
  45. css/dist/admin-global-1410-rtl.css +1 -0
  46. css/dist/admin-global-1410.css +1 -0
  47. css/dist/{adminbar-1404-rtl.css → adminbar-1410-rtl.css} +0 -0
  48. css/dist/{adminbar-1404.css → adminbar-1410.css} +0 -0
  49. css/dist/alerts-1404-rtl.css +0 -1
  50. css/dist/alerts-1404.css +0 -1
  51. css/dist/alerts-1410-rtl.css +1 -0
  52. css/dist/alerts-1410.css +1 -0
  53. css/dist/{dashboard-1404-rtl.css → dashboard-1410-rtl.css} +0 -0
  54. css/dist/{dashboard-1404.css → dashboard-1410.css} +0 -0
  55. css/dist/{edit-page-1404-rtl.css → edit-page-1410-rtl.css} +0 -0
  56. css/dist/{edit-page-1404.css → edit-page-1410.css} +0 -0
  57. css/dist/{featured-image-1404-rtl.css → featured-image-1410-rtl.css} +0 -0
  58. css/dist/{featured-image-1404.css → featured-image-1410.css} +0 -0
  59. css/dist/{filter-explanation-1404-rtl.css → filter-explanation-1410-rtl.css} +0 -0
  60. css/dist/{filter-explanation-1404.css → filter-explanation-1410.css} +0 -0
  61. css/dist/icons-1410-rtl.css +1 -0
  62. css/dist/icons-1410.css +1 -0
  63. css/dist/{inside-editor-1404-rtl.css → inside-editor-1410-rtl.css} +0 -0
  64. css/dist/{inside-editor-1404.css → inside-editor-1410.css} +0 -0
  65. css/dist/metabox-1404-rtl.css +0 -1
  66. css/dist/metabox-1404.css +0 -5
  67. css/dist/metabox-1410-rtl.css +1 -0
  68. css/dist/metabox-1410.css +3 -0
  69. css/dist/{metabox-primary-category-1404-rtl.css → metabox-primary-category-1410-rtl.css} +0 -0
  70. css/dist/{metabox-primary-category-1404.css → metabox-primary-category-1410.css} +0 -0
  71. css/dist/monorepo-1404-rtl.css +0 -1
  72. css/dist/monorepo-1404.css +0 -1
  73. css/dist/monorepo-1410-rtl.css +1 -0
  74. css/dist/monorepo-1410.css +1 -0
  75. css/dist/notifications-1410-rtl.css +1 -0
  76. css/dist/notifications-1410.css +1 -0
  77. css/dist/score_icon-1410-rtl.css +1 -0
  78. css/dist/score_icon-1410.css +1 -0
  79. css/dist/search-appearance-1404-rtl.css +0 -1
  80. css/dist/search-appearance-1404.css +0 -1
  81. css/dist/search-appearance-1410-rtl.css +1 -0
  82. css/dist/search-appearance-1410.css +1 -0
  83. css/dist/{structured-data-blocks-1404-rtl.css → structured-data-blocks-1410-rtl.css} +0 -0
  84. css/dist/{structured-data-blocks-1404.css → structured-data-blocks-1410.css} +0 -0
  85. css/dist/{toggle-switch-1404-rtl.css → toggle-switch-1410-rtl.css} +0 -0
  86. css/dist/{toggle-switch-1404.css → toggle-switch-1410.css} +0 -0
  87. css/dist/{wpseo-dismissible-1404-rtl.css → wpseo-dismissible-1410-rtl.css} +0 -0
  88. css/dist/{wpseo-dismissible-1404.css → wpseo-dismissible-1410.css} +0 -0
  89. css/dist/{yoast-components-1404-rtl.css → yoast-components-1410-rtl.css} +0 -0
  90. css/dist/{yoast-components-1404.css → yoast-components-1410.css} +0 -0
  91. css/dist/yoast-extensions-1404-rtl.css +0 -1
  92. css/dist/yoast-extensions-1404.css +0 -1
  93. css/dist/yoast-extensions-1410-rtl.css +1 -0
  94. css/dist/yoast-extensions-1410.css +1 -0
  95. css/dist/yst_plugin_tools-1404-rtl.css +0 -1
  96. css/dist/yst_plugin_tools-1404.css +0 -1
  97. css/dist/yst_plugin_tools-1410-rtl.css +1 -0
  98. css/dist/yst_plugin_tools-1410.css +1 -0
  99. css/dist/{yst_seo_score-1404-rtl.css → yst_seo_score-1410-rtl.css} +0 -0
  100. css/dist/{yst_seo_score-1404.css → yst_seo_score-1410.css} +0 -0
  101. css/src/admin-global.css +576 -0
  102. css/src/adminbar.css +83 -0
  103. css/src/alerts.css +43 -0
  104. css/src/dashboard.css +90 -0
  105. css/src/edit-page.css +11 -0
  106. css/src/featured-image.css +9 -0
  107. css/src/filter-explanation.css +6 -0
  108. css/src/icons.css +18 -0
  109. css/src/inside-editor.css +10 -0
  110. css/src/metabox-primary-category.css +49 -0
  111. css/src/metabox.css +679 -0
  112. css/src/notifications.css +270 -0
  113. css/src/score_icon.css +29 -0
  114. css/src/search-appearance.css +310 -0
  115. css/src/structured-data-blocks.css +142 -0
  116. css/src/toggle-switch.css +380 -0
  117. css/src/wpseo-dismissible.css +53 -0
  118. css/src/yoast-components.css +618 -0
  119. css/src/yoast-extensions.css +726 -0
  120. css/src/yst_plugin_tools.css +900 -0
  121. css/src/yst_seo_score.css +12 -0
  122. deprecated/admin/ajax/class-yoast-onpage-ajax.php +0 -1
  123. deprecated/admin/config-ui/fields/class-field-google-search-console-intro.php +7 -8
  124. deprecated/admin/links/class-link-compatibility-notifier.php +1 -1
  125. deprecated/admin/links/class-link-table-accessible-notifier.php +49 -0
  126. deprecated/admin/notifiers/class-post-type-archive-notification-handler.php +47 -0
  127. deprecated/admin/onpage/class-onpage-option.php +1 -2
  128. deprecated/admin/onpage/class-onpage.php +0 -1
  129. deprecated/frontend/class-opengraph.php +2 -2
  130. deprecated/frontend/class-primary-category.php +1 -1
  131. deprecated/frontend/class-twitter.php +1 -1
  132. deprecated/frontend/frontend.php +5 -4
  133. deprecated/frontend/schema/class-schema-author.php +2 -2
  134. deprecated/frontend/schema/class-schema-howto.php +2 -2
  135. deprecated/frontend/schema/class-schema-main-image.php +1 -1
  136. images/alert-error-icon.svg +1 -0
  137. images/alert-info-icon.svg +1 -0
  138. images/alert-success-icon.svg +1 -0
  139. images/alert-warning-icon.svg +1 -0
  140. inc/class-addon-manager.php +3 -4
  141. inc/class-upgrade.php +75 -0
  142. inc/class-wpseo-admin-bar-menu.php +10 -10
  143. inc/class-wpseo-meta.php +14 -7
  144. inc/class-wpseo-replace-vars.php +35 -9
  145. inc/class-wpseo-utils.php +61 -5
  146. inc/health-check-curl-version.php +3 -3
  147. inc/health-check-links-table-not-accessible.php +77 -0
  148. inc/health-check-postname-permalink.php +2 -2
  149. inc/health-check-ryte.php +21 -8
  150. inc/options/class-wpseo-option-wpseo.php +42 -20
  151. inc/sitemaps/class-author-sitemap-provider.php +1 -1
  152. inc/sitemaps/class-sitemaps-cache.php +2 -2
  153. inc/sitemaps/class-sitemaps.php +1 -1
  154. js/dist/analysis-1404.js +0 -14
admin/ajax.php CHANGED
@@ -43,6 +43,23 @@ function wpseo_set_option() {
43
 
44
  add_action( 'wp_ajax_wpseo_set_option', 'wpseo_set_option' );
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
  * Since 3.2 Notifications are dismissed in the Notification Center.
48
  */
@@ -170,7 +187,6 @@ function wpseo_upsert_meta( $post_id, $new_meta_value, $orig_meta_value, $meta_k
170
  );
171
 
172
  return $upsert_results;
173
-
174
  }
175
 
176
  if ( $sanitized_new_meta_value === $orig_meta_value && $sanitized_new_meta_value !== $new_meta_value ) {
43
 
44
  add_action( 'wp_ajax_wpseo_set_option', 'wpseo_set_option' );
45
 
46
+ /**
47
+ * Sets an option in the database to hide the index warning for a week.
48
+ *
49
+ * This function is used in AJAX calls and dies on exit.
50
+ */
51
+ function wpseo_set_indexation_remind() {
52
+ if ( ! current_user_can( 'manage_options' ) ) {
53
+ die( '-1' );
54
+ }
55
+
56
+ check_ajax_referer( 'wpseo-indexation-remind' );
57
+
58
+ WPSEO_Options::set( 'indexation_warning_hide_until', ( time() + WEEK_IN_SECONDS ) );
59
+ die( '1' );
60
+ }
61
+ add_action( 'wp_ajax_wpseo_set_indexation_remind', 'wpseo_set_indexation_remind' );
62
+
63
  /**
64
  * Since 3.2 Notifications are dismissed in the Notification Center.
65
  */
187
  );
188
 
189
  return $upsert_results;
 
190
  }
191
 
192
  if ( $sanitized_new_meta_value === $orig_meta_value && $sanitized_new_meta_value !== $new_meta_value ) {
admin/class-admin-asset-dev-server-location.php CHANGED
@@ -58,7 +58,7 @@ final class WPSEO_Admin_Asset_Dev_Server_Location implements WPSEO_Admin_Asset_L
58
  return $this->get_default_url( $asset, $type );
59
  }
60
 
61
- $path = sprintf( '%s%s.js', $asset->get_src(), $asset->get_suffix() );
62
 
63
  return trailingslashit( $this->url ) . $path;
64
  }
58
  return $this->get_default_url( $asset, $type );
59
  }
60
 
61
+ $path = sprintf( 'js/dist/%s%s.js', $asset->get_src(), $asset->get_suffix() );
62
 
63
  return trailingslashit( $this->url ) . $path;
64
  }
admin/class-admin-asset-manager.php CHANGED
@@ -14,18 +14,18 @@
14
  class WPSEO_Admin_Asset_Manager {
15
 
16
  /**
17
- * Class that manages the assets' location.
18
  *
19
- * @var WPSEO_Admin_Asset_Location
20
  */
21
- protected $asset_location;
22
 
23
  /**
24
- * Prefix for naming the assets.
25
  *
26
- * @var string
27
  */
28
- const PREFIX = 'yoast-seo-';
29
 
30
  /**
31
  * Prefix for naming the assets.
@@ -578,7 +578,11 @@ class WPSEO_Admin_Asset_Manager {
578
  'src' => 'wpseo-dismissible-' . $flat_version,
579
  ],
580
  [
581
- 'name' => 'alerts',
 
 
 
 
582
  'src' => 'alerts-' . $flat_version,
583
  ],
584
  [
@@ -643,14 +647,10 @@ class WPSEO_Admin_Asset_Manager {
643
  'name' => 'search-appearance',
644
  'src' => 'search-appearance-' . $flat_version,
645
  ],
646
-
647
- /*
648
- * Temporarily commented out to prevent unwanted monorepo styles seeping through.
649
- * [
650
- * 'name' => 'monorepo',
651
- * 'src' => 'monorepo-' . $flat_version,
652
- * ],
653
- */
654
  [
655
  'name' => 'structured-data-blocks',
656
  'src' => 'structured-data-blocks-' . $flat_version,
14
  class WPSEO_Admin_Asset_Manager {
15
 
16
  /**
17
+ * Prefix for naming the assets.
18
  *
19
+ * @var string
20
  */
21
+ const PREFIX = 'yoast-seo-';
22
 
23
  /**
24
+ * Class that manages the assets' location.
25
  *
26
+ * @var WPSEO_Admin_Asset_Location
27
  */
28
+ protected $asset_location;
29
 
30
  /**
31
  * Prefix for naming the assets.
578
  'src' => 'wpseo-dismissible-' . $flat_version,
579
  ],
580
  [
581
+ 'name' => 'notifications',
582
+ 'src' => 'notifications-' . $flat_version,
583
+ ],
584
+ [
585
+ 'name' => 'alert',
586
  'src' => 'alerts-' . $flat_version,
587
  ],
588
  [
647
  'name' => 'search-appearance',
648
  'src' => 'search-appearance-' . $flat_version,
649
  ],
650
+ [
651
+ 'name' => 'monorepo',
652
+ 'src' => 'monorepo-' . $flat_version,
653
+ ],
 
 
 
 
654
  [
655
  'name' => 'structured-data-blocks',
656
  'src' => 'structured-data-blocks-' . $flat_version,
admin/class-admin-init.php CHANGED
@@ -35,40 +35,33 @@ class WPSEO_Admin_Init {
35
  $this->asset_manager = new WPSEO_Admin_Asset_Manager();
36
 
37
  add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_dismissible' ] );
38
- add_action( 'admin_init', [ $this, 'blog_public_notice' ], 15 );
39
  add_action( 'admin_init', [ $this, 'yoast_plugin_suggestions_notification' ], 15 );
40
- add_action( 'admin_init', [ $this, 'recalculate_notice' ], 15 );
41
  add_action( 'admin_init', [ $this, 'unsupported_php_notice' ], 15 );
42
  add_action( 'admin_init', [ $this->asset_manager, 'register_assets' ] );
43
  add_action( 'admin_init', [ $this, 'show_hook_deprecation_warnings' ] );
44
  add_action( 'admin_init', [ 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ] );
45
- add_action( 'admin_init', [ $this, 'handle_notifications' ], 15 );
46
  add_action( 'admin_notices', [ $this, 'permalink_settings_notice' ] );
47
 
 
 
 
 
 
 
 
48
  $health_checks = [
49
  new WPSEO_Health_Check_Page_Comments(),
50
  new WPSEO_Health_Check_Ryte(),
51
  new WPSEO_Health_Check_Default_Tagline(),
52
  new WPSEO_Health_Check_Postname_Permalink(),
53
  new WPSEO_Health_Check_Curl_Version(),
 
54
  ];
55
 
56
  foreach ( $health_checks as $health_check ) {
57
  $health_check->register_test();
58
  }
59
 
60
- $listeners = [];
61
- $listeners[] = new WPSEO_Post_Type_Archive_Notification_Handler();
62
-
63
- /**
64
- * Listener interface classes.
65
- *
66
- * @var WPSEO_Listener $listener
67
- */
68
- foreach ( $listeners as $listener ) {
69
- $listener->listen();
70
- }
71
-
72
  $this->load_meta_boxes();
73
  $this->load_taxonomy_class();
74
  $this->load_admin_page_class();
@@ -77,26 +70,6 @@ class WPSEO_Admin_Init {
77
  $this->load_plugin_suggestions();
78
  }
79
 
80
- /**
81
- * Handles the notifiers for the dashboard page.
82
- *
83
- * @return void
84
- */
85
- public function handle_notifications() {
86
- /**
87
- * Notification handlers.
88
- *
89
- * @var WPSEO_Notification_Handler[] $handlers
90
- */
91
- $handlers = [];
92
- $handlers[] = new WPSEO_Post_Type_Archive_Notification_Handler();
93
-
94
- $notification_center = Yoast_Notification_Center::get();
95
- foreach ( $handlers as $handler ) {
96
- $handler->handle( $notification_center );
97
- }
98
- }
99
-
100
  /**
101
  * Enqueue our styling for dismissible yoast notifications.
102
  */
@@ -104,37 +77,6 @@ class WPSEO_Admin_Init {
104
  $this->asset_manager->enqueue_style( 'dismissible' );
105
  }
106
 
107
- /**
108
- * Add an alert if the blog is not publicly visible.
109
- */
110
- public function blog_public_notice() {
111
-
112
- $info_message = '<strong>' . __( 'Huge SEO Issue: You\'re blocking access to robots.', 'wordpress-seo' ) . '</strong> ';
113
- $info_message .= sprintf(
114
- /* translators: %1$s resolves to the opening tag of the link to the reading settings, %1$s resolves to the closing tag for the link */
115
- __( 'You must %1$sgo to your Reading Settings%2$s and uncheck the box for Search Engine Visibility.', 'wordpress-seo' ),
116
- '<a href="' . esc_url( admin_url( 'options-reading.php' ) ) . '">',
117
- '</a>'
118
- );
119
-
120
- $notification_options = [
121
- 'type' => Yoast_Notification::ERROR,
122
- 'id' => 'wpseo-dismiss-blog-public-notice',
123
- 'priority' => 1.0,
124
- 'capabilities' => 'wpseo_manage_options',
125
- ];
126
-
127
- $notification = new Yoast_Notification( $info_message, $notification_options );
128
-
129
- $notification_center = Yoast_Notification_Center::get();
130
- if ( ! $this->is_blog_public() ) {
131
- $notification_center->add_notification( $notification );
132
- }
133
- else {
134
- $notification_center->remove_notification( $notification );
135
- }
136
- }
137
-
138
  /**
139
  * Determines whether a suggested plugins notification needs to be displayed.
140
  *
@@ -188,44 +130,6 @@ class WPSEO_Admin_Init {
188
  );
189
  }
190
 
191
- /**
192
- * Shows the notice for recalculating the post. the Notice will only be shown if the user hasn't dismissed it before.
193
- */
194
- public function recalculate_notice() {
195
- // Just a return, because we want to temporary disable this notice (#3998 and #4532).
196
- return;
197
-
198
- if ( filter_input( INPUT_GET, 'recalculate' ) === '1' ) {
199
- update_option( 'wpseo_dismiss_recalculate', '1' );
200
-
201
- return;
202
- }
203
-
204
- if ( ! WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ) {
205
- return;
206
- }
207
-
208
- if ( $this->is_site_notice_dismissed( 'wpseo_dismiss_recalculate' ) ) {
209
- return;
210
- }
211
-
212
- Yoast_Notification_Center::get()->add_notification(
213
- new Yoast_Notification(
214
- sprintf(
215
- /* translators: 1: is a link to 'admin_url / admin.php?page=wpseo_tools&recalculate=1' 2: closing link tag */
216
- __( 'We\'ve updated our SEO score algorithm. %1$sRecalculate the SEO scores%2$s for all posts and pages.', 'wordpress-seo' ),
217
- '<a href="' . admin_url( 'admin.php?page=wpseo_tools&recalculate=1' ) . '">',
218
- '</a>'
219
- ),
220
- [
221
- 'type' => 'updated yoast-dismissible',
222
- 'id' => 'wpseo-dismiss-recalculate',
223
- 'nonce' => wp_create_nonce( 'wpseo-dismiss-recalculate' ),
224
- ]
225
- )
226
- );
227
- }
228
-
229
  /**
230
  * Creates an unsupported PHP version notification in the notification center.
231
  *
@@ -259,17 +163,6 @@ class WPSEO_Admin_Init {
259
  return (float) $wp_version_latest;
260
  }
261
 
262
- /**
263
- * Check if the user has dismissed the given notice (by $notice_name).
264
- *
265
- * @param string $notice_name The name of the notice that might be dismissed.
266
- *
267
- * @return bool
268
- */
269
- private function is_site_notice_dismissed( $notice_name ) {
270
- return get_option( $notice_name, true ) === '1';
271
- }
272
-
273
  /**
274
  * Helper to verify if the user is currently visiting one of our admin pages.
275
  *
@@ -416,12 +309,12 @@ class WPSEO_Admin_Init {
416
  }
417
 
418
  /**
419
- * Check if the site is set to be publicly visible.
420
  *
421
- * @return bool
422
  */
423
- private function is_blog_public() {
424
- return (string) get_option( 'blog_public' ) === '1';
425
  }
426
 
427
  /**
@@ -513,6 +406,51 @@ class WPSEO_Admin_Init {
513
  }
514
  }
515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  /* ********************* DEPRECATED METHODS ********************* */
517
 
518
  /**
@@ -613,4 +551,26 @@ class WPSEO_Admin_Init {
613
  public function permalink_notice() {
614
  _deprecated_function( __METHOD__, 'WPSEO 13.2' );
615
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
616
  }
35
  $this->asset_manager = new WPSEO_Admin_Asset_Manager();
36
 
37
  add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_dismissible' ] );
 
38
  add_action( 'admin_init', [ $this, 'yoast_plugin_suggestions_notification' ], 15 );
 
39
  add_action( 'admin_init', [ $this, 'unsupported_php_notice' ], 15 );
40
  add_action( 'admin_init', [ $this->asset_manager, 'register_assets' ] );
41
  add_action( 'admin_init', [ $this, 'show_hook_deprecation_warnings' ] );
42
  add_action( 'admin_init', [ 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ] );
 
43
  add_action( 'admin_notices', [ $this, 'permalink_settings_notice' ] );
44
 
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_Default_Tagline(),
56
  new WPSEO_Health_Check_Postname_Permalink(),
57
  new WPSEO_Health_Check_Curl_Version(),
58
+ new WPSEO_Health_Check_Link_Table_Not_Accessible,
59
  ];
60
 
61
  foreach ( $health_checks as $health_check ) {
62
  $health_check->register_test();
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  $this->load_meta_boxes();
66
  $this->load_taxonomy_class();
67
  $this->load_admin_page_class();
70
  $this->load_plugin_suggestions();
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  /**
74
  * Enqueue our styling for dismissible yoast notifications.
75
  */
77
  $this->asset_manager->enqueue_style( 'dismissible' );
78
  }
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  /**
81
  * Determines whether a suggested plugins notification needs to be displayed.
82
  *
130
  );
131
  }
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  /**
134
  * Creates an unsupported PHP version notification in the notification center.
135
  *
163
  return (float) $wp_version_latest;
164
  }
165
 
 
 
 
 
 
 
 
 
 
 
 
166
  /**
167
  * Helper to verify if the user is currently visiting one of our admin pages.
168
  *
309
  }
310
 
311
  /**
312
+ * Checks whether search engines are discouraged from indexing the site.
313
  *
314
+ * @return bool Whether search engines are discouraged from indexing the site.
315
  */
316
+ private function are_search_engines_discouraged() {
317
+ return (string) get_option( 'blog_public' ) === '0';
318
  }
319
 
320
  /**
406
  }
407
  }
408
 
409
+ /**
410
+ * Determines whether and where the "search engines discouraged" admin notice should be displayed.
411
+ *
412
+ * @return bool Whether the "search engines discouraged" admin notice should be displayed.
413
+ */
414
+ private function should_display_search_engines_discouraged_notice() {
415
+ return (
416
+ $this->are_search_engines_discouraged()
417
+ && WPSEO_Capability_Utils::current_user_can( 'manage_options' )
418
+ && WPSEO_Options::get( 'ignore_search_engines_discouraged_notice', false ) === false
419
+ && (
420
+ $this->on_wpseo_admin_page()
421
+ || in_array( $this->pagenow, [
422
+ 'index.php',
423
+ 'plugins.php',
424
+ 'update-core.php',
425
+ ], true )
426
+ )
427
+ );
428
+ }
429
+
430
+ /**
431
+ * Displays an admin notice when WordPress is set to discourage search engines from indexing the site.
432
+ *
433
+ * @return void
434
+ */
435
+ public function search_engines_discouraged_notice() {
436
+ if ( ! $this->should_display_search_engines_discouraged_notice() ) {
437
+ return;
438
+ }
439
+
440
+ printf(
441
+ '<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>',
442
+ esc_html__( 'Huge SEO Issue: You\'re blocking access to robots.', 'wordpress-seo' ),
443
+ sprintf(
444
+ /* translators: 1: Link start tag to the WordPress Reading Settings page, 2: Link closing tag. */
445
+ 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' ),
446
+ '<a href="' . esc_url( admin_url( 'options-reading.php' ) ) . '">',
447
+ '</a>'
448
+ ),
449
+ esc_js( wp_create_nonce( 'wpseo-ignore' ) ),
450
+ esc_html__( 'I don\'t want this site to show in the search results.', 'wordpress-seo' )
451
+ );
452
+ }
453
+
454
  /* ********************* DEPRECATED METHODS ********************* */
455
 
456
  /**
551
  public function permalink_notice() {
552
  _deprecated_function( __METHOD__, 'WPSEO 13.2' );
553
  }
554
+
555
+ /**
556
+ * Add an alert if the blog is not publicly visible.
557
+ *
558
+ * @deprecated 14.1
559
+ * @codeCoverageIgnore
560
+ */
561
+ public function blog_public_notice() {
562
+ _deprecated_function( __METHOD__, 'WPSEO 14.1' );
563
+ }
564
+
565
+ /**
566
+ * Handles the notifiers for the dashboard page.
567
+ *
568
+ * @deprecated 14.1
569
+ * @codeCoverageIgnore
570
+ *
571
+ * @return void
572
+ */
573
+ public function handle_notifications() {
574
+ _deprecated_function( __METHOD__, 'WPSEO 14.1' );
575
+ }
576
  }
admin/class-admin.php CHANGED
@@ -308,7 +308,7 @@ class WPSEO_Admin {
308
  */
309
  private function localize_admin_global_script() {
310
  return [
311
- 'isRtl' => is_rtl(),
312
  'variable_warning' => sprintf(
313
  /* translators: %1$s: '%%term_title%%' variable used in titles and meta's template that's not compatible with the given template, %2$s: expands to 'HelpScout beacon' */
314
  __( 'Warning: the variable %1$s cannot be used in this template. See the %2$s for more info.', 'wordpress-seo' ),
@@ -379,15 +379,12 @@ class WPSEO_Admin {
379
  protected function initialize_seo_links() {
380
  $integrations = [];
381
 
382
- $link_table_accessible_notifier = new WPSEO_Link_Table_Accessible_Notifier();
383
-
384
  if ( ! WPSEO_Options::get( 'enable_text_link_counter' ) ) {
385
  return $integrations;
386
  }
387
 
388
  $integrations[] = new WPSEO_Link_Cleanup_Transient();
389
 
390
- // When the table doesn't exists, just add the notification and return early.
391
  if ( ! WPSEO_Link_Table_Accessible::is_accessible() ) {
392
  WPSEO_Link_Table_Accessible::cleanup();
393
  }
@@ -397,13 +394,9 @@ class WPSEO_Admin {
397
  }
398
 
399
  if ( ! WPSEO_Link_Table_Accessible::is_accessible() || ! WPSEO_Meta_Table_Accessible::is_accessible() ) {
400
- $link_table_accessible_notifier->add_notification();
401
-
402
  return $integrations;
403
  }
404
 
405
- $link_table_accessible_notifier->remove_notification();
406
-
407
  $integrations[] = new WPSEO_Link_Columns( new WPSEO_Meta_Storage() );
408
  $integrations[] = new WPSEO_Link_Reindex_Dashboard();
409
  $integrations[] = new WPSEO_Link_Notifier();
308
  */
309
  private function localize_admin_global_script() {
310
  return [
311
+ 'isRtl' => is_rtl(),
312
  'variable_warning' => sprintf(
313
  /* translators: %1$s: '%%term_title%%' variable used in titles and meta's template that's not compatible with the given template, %2$s: expands to 'HelpScout beacon' */
314
  __( 'Warning: the variable %1$s cannot be used in this template. See the %2$s for more info.', 'wordpress-seo' ),
379
  protected function initialize_seo_links() {
380
  $integrations = [];
381
 
 
 
382
  if ( ! WPSEO_Options::get( 'enable_text_link_counter' ) ) {
383
  return $integrations;
384
  }
385
 
386
  $integrations[] = new WPSEO_Link_Cleanup_Transient();
387
 
 
388
  if ( ! WPSEO_Link_Table_Accessible::is_accessible() ) {
389
  WPSEO_Link_Table_Accessible::cleanup();
390
  }
394
  }
395
 
396
  if ( ! WPSEO_Link_Table_Accessible::is_accessible() || ! WPSEO_Meta_Table_Accessible::is_accessible() ) {
 
 
397
  return $integrations;
398
  }
399
 
 
 
400
  $integrations[] = new WPSEO_Link_Columns( new WPSEO_Meta_Storage() );
401
  $integrations[] = new WPSEO_Link_Reindex_Dashboard();
402
  $integrations[] = new WPSEO_Link_Notifier();
admin/class-gutenberg-compatibility.php CHANGED
@@ -15,14 +15,14 @@ class WPSEO_Gutenberg_Compatibility {
15
  *
16
  * @var string
17
  */
18
- const CURRENT_RELEASE = '7.9.1';
19
 
20
  /**
21
  * The minimally supported version of Gutenberg by the plugin.
22
  *
23
  * @var string
24
  */
25
- const MINIMUM_SUPPORTED = '7.9.1';
26
 
27
  /**
28
  * Holds the current version.
15
  *
16
  * @var string
17
  */
18
+ const CURRENT_RELEASE = '8.0.0';
19
 
20
  /**
21
  * The minimally supported version of Gutenberg by the plugin.
22
  *
23
  * @var string
24
  */
25
+ const MINIMUM_SUPPORTED = '8.0.0';
26
 
27
  /**
28
  * Holds the current version.
admin/class-yoast-columns.php CHANGED
@@ -21,24 +21,88 @@ class WPSEO_Yoast_Columns implements WPSEO_WordPress_Integration {
21
  * Adds the help tab to the help center for current screen.
22
  */
23
  public function add_help_tab() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  $screen = get_current_screen();
25
  $screen->add_help_tab(
26
  [
27
  /* translators: %s expands to Yoast */
28
  'title' => sprintf( __( '%s Columns', 'wordpress-seo' ), 'Yoast' ),
29
  'id' => 'yst-columns',
30
- 'content' => sprintf(
31
- /* translators: %1$s: Yoast SEO, %2$s: Link to article about content analysis, %3$s: Anchor closing, %4$s: Link to article about text links, %5$s: Emphasis open tag, %6$s: Emphasis close tag */
32
- '<p>' . __( '%1$s adds several columns to this page. We\'ve written an article about %2$show to use the SEO score and Readability score%3$s. The links columns show the number of articles on this site linking %5$sto%6$s this article and the number of URLs linked %5$sfrom%6$s this article. Learn more about %4$show to use these features to improve your internal linking%3$s, which greatly enhances your SEO.', 'wordpress-seo' ) . '</p>',
33
- 'Yoast SEO',
34
- '<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/16p' ) . '">',
35
- '</a>',
36
- '<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/16q' ) . '">',
37
- '<em>',
38
- '</em>'
39
- ),
40
  'priority' => 15,
41
  ]
42
  );
43
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
21
  * Adds the help tab to the help center for current screen.
22
  */
23
  public function add_help_tab() {
24
+ $link_columns_present = $this->display_links();
25
+ $meta_columns_present = $this->display_meta_columns();
26
+ if ( ! ( $link_columns_present || $meta_columns_present ) ) {
27
+ return;
28
+ }
29
+
30
+ $help_tab_content = sprintf(
31
+ /* translators: %1$s: Yoast SEO */
32
+ __( '%1$s adds several columns to this page.', 'wordpress-seo' ),
33
+ 'Yoast SEO'
34
+ );
35
+
36
+ if ( $meta_columns_present ) {
37
+ $help_tab_content .= ' ' . sprintf(
38
+ /* translators: %1$s: Link to article about content analysis, %2$s: Anchor closing */
39
+ __( 'We\'ve written an article about %1$show to use the SEO score and Readability score%2$s.', 'wordpress-seo' ),
40
+ '<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/16p' ) . '">',
41
+ '</a>'
42
+ );
43
+ }
44
+
45
+ if ( $link_columns_present ) {
46
+ $help_tab_content .= ' ' . sprintf(
47
+ /* translators: %1$s: Link to article about text links, %2$s: Anchor closing tag, %3$s: Emphasis open tag, %4$s: Emphasis close tag */
48
+ __( 'The links columns show the number of articles on this site linking %3$sto%4$s this article and the number of URLs linked %3$sfrom%4$s this article. Learn more about %1$show to use these features to improve your internal linking%2$s, which greatly enhances your SEO.', 'wordpress-seo' ),
49
+ '<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/16p' ) . '">',
50
+ '</a>',
51
+ '<em>',
52
+ '</em>'
53
+ );
54
+ };
55
+
56
  $screen = get_current_screen();
57
  $screen->add_help_tab(
58
  [
59
  /* translators: %s expands to Yoast */
60
  'title' => sprintf( __( '%s Columns', 'wordpress-seo' ), 'Yoast' ),
61
  'id' => 'yst-columns',
62
+ 'content' => '<p>' . $help_tab_content . '</p>',
 
 
 
 
 
 
 
 
 
63
  'priority' => 15,
64
  ]
65
  );
66
  }
67
+
68
+ /**
69
+ * Retrieves the post type from the $_GET variable.
70
+ *
71
+ * @return string The current post type.
72
+ */
73
+ private function get_current_post_type() {
74
+ return filter_input( INPUT_GET, 'post_type' );
75
+ }
76
+
77
+ /**
78
+ * Whether or not we are showing link columns on this overview page.
79
+ * This depends on the post being accessible or not.
80
+ *
81
+ * @return bool Whether or not the linking columns are shown
82
+ */
83
+ private function display_links() {
84
+ $current_post_type = sanitize_text_field( $this->get_current_post_type() );
85
+
86
+ if ( empty( $current_post_type ) ) {
87
+ return false;
88
+ }
89
+
90
+ return WPSEO_Post_Type::is_post_type_accessible( $current_post_type );
91
+ }
92
+
93
+ /**
94
+ * Wraps the WPSEO_Metabox check to determine whether the metabox should be displayed either by
95
+ * choice of the admin or because the post type is not a public post type.
96
+ *
97
+ * @return bool Whether or not the meta box (and associated columns etc) should be hidden.
98
+ */
99
+ private function display_meta_columns() {
100
+ $current_post_type = sanitize_text_field( $this->get_current_post_type() );
101
+
102
+ if ( empty( $current_post_type ) ) {
103
+ return false;
104
+ }
105
+
106
+ return WPSEO_Utils::is_metabox_active( $current_post_type, 'post_type' );
107
+ }
108
  }
admin/class-yoast-form.php CHANGED
@@ -338,8 +338,8 @@ class Yoast_Form {
338
  '<label class="', $class, '"><b class="switch-yoast-seo-jaws-a11y">&nbsp;</b>',
339
  '<input type="checkbox" aria-labelledby="', esc_attr( $var . '-label' ), '" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="on"', checked( $val, 'on', false ), disabled( $this->is_control_disabled( $var ), true, false ), '/>',
340
  '<span aria-hidden="true">
341
- <span>', esc_html( $off_button ) ,'</span>
342
- <span>', esc_html( $on_button ) ,'</span>
343
  <a></a>
344
  </span>
345
  </label><div class="clear"></div></div>';
@@ -364,12 +364,12 @@ class Yoast_Form {
364
  ];
365
  }
366
 
367
- $defaults = [
368
  'placeholder' => '',
369
  'class' => '',
370
  ];
371
- $attr = wp_parse_args( $attr, $defaults );
372
- $val = $this->get_field_value( $var, '' );
373
  if ( isset( $attr['type'] ) && $attr['type'] === 'url' ) {
374
  $val = urldecode( $val );
375
  $type = 'url';
@@ -696,7 +696,7 @@ class Yoast_Form {
696
  $key_esc = esc_attr( $key );
697
  $for = $var_esc . '-' . $key_esc;
698
  echo '<input type="radio" id="' . $for . '" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" value="' . $key_esc . '" ' . checked( $val, $key_esc, false ) . disabled( $this->is_control_disabled( $var ), true, false ) . ' />',
699
- '<label for="', $for, '">', esc_html( $value ), $screen_reader_text_html,'</label>';
700
  }
701
 
702
  echo '<a></a></div></fieldset><div class="clear"></div></div>' . PHP_EOL . PHP_EOL;
338
  '<label class="', $class, '"><b class="switch-yoast-seo-jaws-a11y">&nbsp;</b>',
339
  '<input type="checkbox" aria-labelledby="', esc_attr( $var . '-label' ), '" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="on"', checked( $val, 'on', false ), disabled( $this->is_control_disabled( $var ), true, false ), '/>',
340
  '<span aria-hidden="true">
341
+ <span>', esc_html( $off_button ), '</span>
342
+ <span>', esc_html( $on_button ), '</span>
343
  <a></a>
344
  </span>
345
  </label><div class="clear"></div></div>';
364
  ];
365
  }
366
 
367
+ $defaults = [
368
  'placeholder' => '',
369
  'class' => '',
370
  ];
371
+ $attr = wp_parse_args( $attr, $defaults );
372
+ $val = $this->get_field_value( $var, '' );
373
  if ( isset( $attr['type'] ) && $attr['type'] === 'url' ) {
374
  $val = urldecode( $val );
375
  $type = 'url';
696
  $key_esc = esc_attr( $key );
697
  $for = $var_esc . '-' . $key_esc;
698
  echo '<input type="radio" id="' . $for . '" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" value="' . $key_esc . '" ' . checked( $val, $key_esc, false ) . disabled( $this->is_control_disabled( $var ), true, false ) . ' />',
699
+ '<label for="', $for, '">', esc_html( $value ), $screen_reader_text_html, '</label>';
700
  }
701
 
702
  echo '<a></a></div></fieldset><div class="clear"></div></div>' . PHP_EOL . PHP_EOL;
admin/class-yoast-input-validation.php CHANGED
@@ -55,7 +55,7 @@ class Yoast_Input_Validation {
55
  foreach ( $errors as $error ) {
56
  // For now, filter the admin title only in the Yoast SEO settings pages.
57
  if ( self::is_yoast_option_group_name( $error['setting'] ) && $error['code'] !== 'settings_updated' ) {
58
- $error_count++;
59
  }
60
  }
61
 
55
  foreach ( $errors as $error ) {
56
  // For now, filter the admin title only in the Yoast SEO settings pages.
57
  if ( self::is_yoast_option_group_name( $error['setting'] ) && $error['code'] !== 'settings_updated' ) {
58
+ ++$error_count;
59
  }
60
  }
61
 
admin/class-yoast-notification-center.php CHANGED
@@ -424,7 +424,7 @@ class Yoast_Notification_Center {
424
  }
425
 
426
  if ( $notification->is_persistent() && $resolve ) {
427
- $this->resolved++;
428
  $this->clear_dismissal( $notification );
429
  }
430
 
424
  }
425
 
426
  if ( $notification->is_persistent() && $resolve ) {
427
+ ++$this->resolved;
428
  $this->clear_dismissal( $notification );
429
  }
430
 
admin/class-yoast-notification.php CHANGED
@@ -320,10 +320,10 @@ class Yoast_Notification {
320
 
321
  // Default notification classes.
322
  $classes = [
323
- 'yoast-alert',
324
  ];
325
 
326
- // Maintain WordPress visualisation of alerts when they are not persistent.
327
  if ( ! $this->is_persistent() ) {
328
  $classes[] = 'notice';
329
  $classes[] = $this->get_type();
320
 
321
  // Default notification classes.
322
  $classes = [
323
+ 'yoast-notification',
324
  ];
325
 
326
+ // Maintain WordPress visualisation of notifications when they are not persistent.
327
  if ( ! $this->is_persistent() ) {
328
  $classes[] = 'notice';
329
  $classes[] = $this->get_type();
admin/{class-yoast-alerts.php → class-yoast-notifications.php} RENAMED
@@ -6,9 +6,9 @@
6
  */
7
 
8
  /**
9
- * Class Yoast_Alerts.
10
  */
11
- class Yoast_Alerts {
12
 
13
  /**
14
  * Holds the admin page's ID.
@@ -67,7 +67,7 @@ class Yoast_Alerts {
67
  private static $dismissed_warnings = [];
68
 
69
  /**
70
- * Yoast_Alerts constructor.
71
  */
72
  public function __construct() {
73
 
@@ -84,12 +84,12 @@ class Yoast_Alerts {
84
  add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
85
  }
86
 
87
- // Needed for adminbar and Alerts page.
88
- add_action( 'admin_init', [ __CLASS__, 'collect_alerts' ], 99 );
89
 
90
  // Add AJAX hooks.
91
- add_action( 'wp_ajax_yoast_dismiss_alert', [ $this, 'ajax_dismiss_alert' ] );
92
- add_action( 'wp_ajax_yoast_restore_alert', [ $this, 'ajax_restore_alert' ] );
93
  }
94
 
95
  /**
@@ -98,13 +98,25 @@ class Yoast_Alerts {
98
  public function enqueue_assets() {
99
 
100
  $asset_manager = new WPSEO_Admin_Asset_Manager();
101
- $asset_manager->enqueue_style( 'alerts' );
102
  }
103
 
104
  /**
105
- * Handle ajax request to dismiss an alert.
 
 
 
 
 
106
  */
107
  public function ajax_dismiss_alert() {
 
 
 
 
 
 
 
108
 
109
  $notification = $this->get_notification_from_ajax_request();
110
  if ( $notification ) {
@@ -118,9 +130,22 @@ class Yoast_Alerts {
118
  }
119
 
120
  /**
121
- * Handle ajax request to restore an alert.
 
 
 
 
 
 
122
  */
123
  public function ajax_restore_alert() {
 
 
 
 
 
 
 
124
 
125
  $notification = $this->get_notification_from_ajax_request();
126
  if ( $notification ) {
@@ -136,7 +161,7 @@ class Yoast_Alerts {
136
  /**
137
  * Create AJAX response data.
138
  *
139
- * @param string $type Alert type.
140
  */
141
  private function output_ajax_response( $type ) {
142
 
@@ -145,7 +170,7 @@ class Yoast_Alerts {
145
  echo WPSEO_Utils::format_json_encode(
146
  [
147
  'html' => $html,
148
- 'total' => self::get_active_alert_count(),
149
  ]
150
  );
151
  // phpcs:enable -- Reason: WPSEO_Utils::format_json_encode is safe.
@@ -154,7 +179,7 @@ class Yoast_Alerts {
154
  /**
155
  * Get the HTML to return in the AJAX request.
156
  *
157
- * @param string $type Alert type.
158
  *
159
  * @return bool|string
160
  */
@@ -171,18 +196,18 @@ class Yoast_Alerts {
171
  break;
172
  }
173
 
174
- // Re-collect alerts.
175
- self::collect_alerts();
176
 
177
  /**
178
  * Stops PHPStorm from nagging about this variable being unused. The variable is used in the view.
179
  *
180
  * @noinspection PhpUnusedLocalVariableInspection
181
  */
182
- $alerts_data = self::get_template_variables();
183
 
184
  ob_start();
185
- include WPSEO_PATH . 'admin/views/partial-alerts-' . $view . '.php';
186
  $html = ob_get_clean();
187
 
188
  return $html;
@@ -202,36 +227,21 @@ class Yoast_Alerts {
202
  }
203
 
204
  /**
205
- * Show the alerts overview page.
206
- */
207
- public static function show_overview_page() {
208
-
209
- /**
210
- * Stops PHPStorm from nagging about this variable being unused. The variable is used in the view.
211
- *
212
- * @noinspection PhpUnusedLocalVariableInspection
213
- */
214
- $alerts_data = self::get_template_variables();
215
-
216
- include WPSEO_PATH . 'admin/views/alerts-dashboard.php';
217
- }
218
-
219
- /**
220
- * Collect the alerts and group them together.
221
  */
222
- public static function collect_alerts() {
223
 
224
  $notification_center = Yoast_Notification_Center::get();
225
 
226
  $notifications = $notification_center->get_sorted_notifications();
227
  self::$notification_count = count( $notifications );
228
 
229
- self::$errors = array_filter( $notifications, [ __CLASS__, 'filter_error_alerts' ] );
230
- self::$dismissed_errors = array_filter( self::$errors, [ __CLASS__, 'filter_dismissed_alerts' ] );
231
  self::$active_errors = array_diff( self::$errors, self::$dismissed_errors );
232
 
233
- self::$warnings = array_filter( $notifications, [ __CLASS__, 'filter_warning_alerts' ] );
234
- self::$dismissed_warnings = array_filter( self::$warnings, [ __CLASS__, 'filter_dismissed_alerts' ] );
235
  self::$active_warnings = array_diff( self::$warnings, self::$dismissed_warnings );
236
  }
237
 
@@ -245,7 +255,7 @@ class Yoast_Alerts {
245
  return [
246
  'metrics' => [
247
  'total' => self::$notification_count,
248
- 'active' => self::get_active_alert_count(),
249
  'errors' => count( self::$errors ),
250
  'warnings' => count( self::$warnings ),
251
  ],
@@ -261,15 +271,43 @@ class Yoast_Alerts {
261
  }
262
 
263
  /**
264
- * Get the number of active alerts.
 
265
  *
266
  * @return int
 
 
 
267
  */
268
- public static function get_active_alert_count() {
 
 
 
 
 
 
 
 
 
 
269
 
270
  return ( count( self::$active_errors ) + count( self::$active_warnings ) );
271
  }
272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  /**
274
  * Filter out any non-errors.
275
  *
@@ -277,11 +315,27 @@ class Yoast_Alerts {
277
  *
278
  * @return bool
279
  */
280
- private static function filter_error_alerts( Yoast_Notification $notification ) {
281
 
282
  return $notification->get_type() === 'error';
283
  }
284
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  /**
286
  * Filter out any non-warnings.
287
  *
@@ -289,11 +343,25 @@ class Yoast_Alerts {
289
  *
290
  * @return bool
291
  */
292
- private static function filter_warning_alerts( Yoast_Notification $notification ) {
293
 
294
  return $notification->get_type() !== 'error';
295
  }
296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  /**
298
  * Filter out any dismissed notifications.
299
  *
@@ -301,8 +369,10 @@ class Yoast_Alerts {
301
  *
302
  * @return bool
303
  */
304
- private static function filter_dismissed_alerts( Yoast_Notification $notification ) {
305
 
306
  return Yoast_Notification_Center::is_notification_dismissed( $notification );
307
  }
308
  }
 
 
6
  */
7
 
8
  /**
9
+ * Class Yoast_Notifications.
10
  */
11
+ class Yoast_Notifications {
12
 
13
  /**
14
  * Holds the admin page's ID.
67
  private static $dismissed_warnings = [];
68
 
69
  /**
70
+ * Yoast_Notifications constructor.
71
  */
72
  public function __construct() {
73
 
84
  add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
85
  }
86
 
87
+ // Needed for adminbar and Notifications page.
88
+ add_action( 'admin_init', [ __CLASS__, 'collect_notifications' ], 99 );
89
 
90
  // Add AJAX hooks.
91
+ add_action( 'wp_ajax_yoast_dismiss_notification', [ $this, 'ajax_dismiss_notification' ] );
92
+ add_action( 'wp_ajax_yoast_restore_notification', [ $this, 'ajax_restore_notification' ] );
93
  }
94
 
95
  /**
98
  public function enqueue_assets() {
99
 
100
  $asset_manager = new WPSEO_Admin_Asset_Manager();
101
+ $asset_manager->enqueue_style( 'notifications' );
102
  }
103
 
104
  /**
105
+ * Deprecated: Handle ajax request to dismiss a alert.
106
+ * Renamed to ajax_dismiss_notification
107
+ *
108
+ * @deprecated 14.0
109
+ *
110
+ * @codeCoverageIgnore
111
  */
112
  public function ajax_dismiss_alert() {
113
+ _deprecated_function( __METHOD__, 'WPSEO 14.0' );
114
+ }
115
+
116
+ /**
117
+ * Handle ajax request to dismiss a notification.
118
+ */
119
+ public function ajax_dismiss_notification() {
120
 
121
  $notification = $this->get_notification_from_ajax_request();
122
  if ( $notification ) {
130
  }
131
 
132
  /**
133
+ * Deprecated: Handle ajax request to restore a notification.
134
+ * Renamed to ajax_restore_notification
135
+ *
136
+ * @return void
137
+ * @deprecated 14.0
138
+ *
139
+ * @codeCoverageIgnore
140
  */
141
  public function ajax_restore_alert() {
142
+ _deprecated_function( __METHOD__, 'WPSEO 14.0' );
143
+ }
144
+
145
+ /**
146
+ * Handle ajax request to restore a notification.
147
+ */
148
+ public function ajax_restore_notification() {
149
 
150
  $notification = $this->get_notification_from_ajax_request();
151
  if ( $notification ) {
161
  /**
162
  * Create AJAX response data.
163
  *
164
+ * @param string $type Notification type.
165
  */
166
  private function output_ajax_response( $type ) {
167
 
170
  echo WPSEO_Utils::format_json_encode(
171
  [
172
  'html' => $html,
173
+ 'total' => self::get_active_notification_count(),
174
  ]
175
  );
176
  // phpcs:enable -- Reason: WPSEO_Utils::format_json_encode is safe.
179
  /**
180
  * Get the HTML to return in the AJAX request.
181
  *
182
+ * @param string $type Notification type.
183
  *
184
  * @return bool|string
185
  */
196
  break;
197
  }
198
 
199
+ // Re-collect notifications.
200
+ self::collect_notifications();
201
 
202
  /**
203
  * Stops PHPStorm from nagging about this variable being unused. The variable is used in the view.
204
  *
205
  * @noinspection PhpUnusedLocalVariableInspection
206
  */
207
+ $notifications_data = self::get_template_variables();
208
 
209
  ob_start();
210
+ include WPSEO_PATH . 'admin/views/partial-notifications-' . $view . '.php';
211
  $html = ob_get_clean();
212
 
213
  return $html;
227
  }
228
 
229
  /**
230
+ * Collect the notifications and group them together.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  */
232
+ public static function collect_notifications() {
233
 
234
  $notification_center = Yoast_Notification_Center::get();
235
 
236
  $notifications = $notification_center->get_sorted_notifications();
237
  self::$notification_count = count( $notifications );
238
 
239
+ self::$errors = array_filter( $notifications, [ __CLASS__, 'filter_error_notifications' ] );
240
+ self::$dismissed_errors = array_filter( self::$errors, [ __CLASS__, 'filter_dismissed_notifications' ] );
241
  self::$active_errors = array_diff( self::$errors, self::$dismissed_errors );
242
 
243
+ self::$warnings = array_filter( $notifications, [ __CLASS__, 'filter_warning_notifications' ] );
244
+ self::$dismissed_warnings = array_filter( self::$warnings, [ __CLASS__, 'filter_dismissed_notifications' ] );
245
  self::$active_warnings = array_diff( self::$warnings, self::$dismissed_warnings );
246
  }
247
 
255
  return [
256
  'metrics' => [
257
  'total' => self::$notification_count,
258
+ 'active' => self::get_active_notification_count(),
259
  'errors' => count( self::$errors ),
260
  'warnings' => count( self::$warnings ),
261
  ],
271
  }
272
 
273
  /**
274
+ * Deprecated: Get the number of active notifications.
275
+ * Renamed to get_active_notification_count
276
  *
277
  * @return int
278
+ * @deprecated 14.0
279
+ *
280
+ * @codeCoverageIgnore
281
  */
282
+ public function get_active_alert_count() {
283
+ _deprecated_function( __METHOD__, 'WPSEO 14.0' );
284
+ return 0;
285
+ }
286
+
287
+ /**
288
+ * Get the number of active notifications.
289
+ *
290
+ * @return int
291
+ */
292
+ public static function get_active_notification_count() {
293
 
294
  return ( count( self::$active_errors ) + count( self::$active_warnings ) );
295
  }
296
 
297
+ /**
298
+ * Deprecated: Filter out any non-errors. Renamed to filter_error_notifications
299
+ *
300
+ * @param Yoast_Notification $notification $notification Notification to test.
301
+ * @return bool
302
+ * @deprecated 14.0
303
+ *
304
+ * @codeCoverageIgnore
305
+ */
306
+ public function filter_error_alerts( Yoast_Notification $notification ) {
307
+ _deprecated_function( __METHOD__, 'WPSEO 14.0' );
308
+ return false;
309
+ }
310
+
311
  /**
312
  * Filter out any non-errors.
313
  *
315
  *
316
  * @return bool
317
  */
318
+ private static function filter_error_notifications( Yoast_Notification $notification ) {
319
 
320
  return $notification->get_type() === 'error';
321
  }
322
 
323
+
324
+ /**
325
+ * Deprecated: Filter out any non-warnings. Renamed to filter_warning_notifications
326
+ *
327
+ * @param Yoast_Notification $notification $notification Notification to test.
328
+ * @return bool
329
+ * @deprecated 14.0
330
+ *
331
+ * @codeCoverageIgnore
332
+ */
333
+ public function filter_warning_alerts( Yoast_Notification $notification ) {
334
+ _deprecated_function( __METHOD__, 'WPSEO 14.0' );
335
+ return false;
336
+ }
337
+
338
+
339
  /**
340
  * Filter out any non-warnings.
341
  *
343
  *
344
  * @return bool
345
  */
346
+ private static function filter_warning_notifications( Yoast_Notification $notification ) {
347
 
348
  return $notification->get_type() !== 'error';
349
  }
350
 
351
+ /**
352
+ * Deprecated: Filter out any dismissed notifications. Renamed to filter_dismissed_alerts.
353
+ *
354
+ * @param Yoast_Notification $notification Notification to test.
355
+ * @return bool
356
+ * @deprecated 14.0
357
+ *
358
+ * @codeCoverageIgnore
359
+ */
360
+ public function filter_dismissed_alerts( Yoast_Notification $notification ) {
361
+ _deprecated_function( __METHOD__, 'WPSEO 14.0' );
362
+ return false;
363
+ }
364
+
365
  /**
366
  * Filter out any dismissed notifications.
367
  *
369
  *
370
  * @return bool
371
  */
372
+ private static function filter_dismissed_notifications( Yoast_Notification $notification ) {
373
 
374
  return Yoast_Notification_Center::is_notification_dismissed( $notification );
375
  }
376
  }
377
+
378
+ class_alias( Yoast_Notifications::class, 'Yoast_Alerts' );
admin/formatter/class-metabox-formatter.php CHANGED
@@ -148,14 +148,14 @@ class WPSEO_Metabox_Formatter {
148
  }
149
 
150
  /**
151
- * Returns a link to the settings page, if the user has the right capabilities.
152
  * Returns an empty string otherwise.
153
  *
154
- * @return string The settings link.
155
  */
156
  private function get_settings_link() {
157
  if ( current_user_can( 'manage_options' ) ) {
158
- return admin_url( 'options-general.php' );
159
  }
160
 
161
  return '';
148
  }
149
 
150
  /**
151
+ * Returns a link to the General Settings page, if the user has the right capabilities.
152
  * Returns an empty string otherwise.
153
  *
154
+ * @return string The General Settings link.
155
  */
156
  private function get_settings_link() {
157
  if ( current_user_can( 'manage_options' ) ) {
158
+ return esc_url( admin_url( 'options-general.php' ) );
159
  }
160
 
161
  return '';
admin/import/plugins/class-import-greg-high-performance-seo.php CHANGED
@@ -39,5 +39,4 @@ class WPSEO_Import_Greg_SEO extends WPSEO_Plugin_Importer {
39
  'new_key' => 'title',
40
  ],
41
  ];
42
-
43
  }
39
  'new_key' => 'title',
40
  ],
41
  ];
 
42
  }
admin/import/plugins/class-import-jetpack.php CHANGED
@@ -37,5 +37,4 @@ class WPSEO_Import_Jetpack_SEO extends WPSEO_Plugin_Importer {
37
  'new_key' => 'metadesc',
38
  ],
39
  ];
40
-
41
  }
37
  'new_key' => 'metadesc',
38
  ],
39
  ];
 
40
  }
admin/import/plugins/class-import-ultimate-seo.php CHANGED
@@ -61,5 +61,4 @@ class WPSEO_Import_Ultimate_SEO extends WPSEO_Plugin_Importer {
61
  'convert' => [ 'on' => 1 ],
62
  ],
63
  ];
64
-
65
  }
61
  'convert' => [ 'on' => 1 ],
62
  ],
63
  ];
 
64
  }
admin/links/class-link-table-accessible-notifier.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin\Links
6
- */
7
-
8
- /**
9
- * Represents the notice when the table is not accessible.
10
- */
11
- class WPSEO_Link_Table_Accessible_Notifier {
12
-
13
- /**
14
- * Notification id.
15
- *
16
- * @var string
17
- */
18
- const NOTIFICATION_ID = 'wpseo-links-table-not-accessible';
19
-
20
- /**
21
- * Adds the notification to the notification center.
22
- */
23
- public function add_notification() {
24
- Yoast_Notification_Center::get()->add_notification( $this->get_notification() );
25
- }
26
-
27
- /**
28
- * Removes the notification from the notification center.
29
- */
30
- public function remove_notification() {
31
- Yoast_Notification_Center::get()->remove_notification( $this->get_notification() );
32
- }
33
-
34
- /**
35
- * Returns the notification when the table is not accessible.
36
- *
37
- * @return Yoast_Notification The notification.
38
- */
39
- protected function get_notification() {
40
- return new Yoast_Notification(
41
- sprintf(
42
- /* translators: %1$s: Yoast SEO. %2$s: Version number of Yoast SEO. %3$s: strong opening tag, %4$s: strong closing tag */
43
- esc_html__( 'The %3$sText link counter%4$s feature (introduced in %1$s %2$s) is currently disabled.', 'wordpress-seo' ),
44
- 'Yoast SEO',
45
- '5.0',
46
- '<strong>',
47
- '</strong>'
48
- ) . ' ' .
49
- sprintf(
50
- /* translators: %1$s: Yoast SEO. */
51
- esc_html__( 'For this feature to work, %1$s needs to create a table in your database. We were unable to create this table automatically.', 'wordpress-seo' ),
52
- 'Yoast SEO'
53
- ) . '<br><br>' .
54
- sprintf(
55
- /* translators: %1$s: link to knowledge base article about solving table issue. %2$s: is anchor closing. */
56
- esc_html__( 'Please read the following %1$sknowledge base article%2$s to find out how to resolve this problem.', 'wordpress-seo' ),
57
- '<a href="' . WPSEO_Shortlinker::get( 'https://yoa.st/15o' ) . '">',
58
- '</a>'
59
- ),
60
- [
61
- 'type' => Yoast_Notification::WARNING,
62
- 'id' => self::NOTIFICATION_ID,
63
- 'capabilities' => 'wpseo_manage_options',
64
- 'priority' => 0.8,
65
- ]
66
- );
67
- }
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/metabox/class-metabox.php CHANGED
@@ -5,6 +5,8 @@
5
  * @package WPSEO\Admin
6
  */
7
 
 
 
8
  /**
9
  * This class generates the metabox on the edit post / page as well as contains all page analysis functionality.
10
  */
@@ -115,22 +117,20 @@ class WPSEO_Metabox extends WPSEO_Meta {
115
 
116
  /**
117
  * Renders the content for the internet explorer metabox.
 
 
118
  */
119
  public function render_internet_explorer_notice() {
120
- echo '<div class="yoast-alert-box yoast-alert-box__warning">';
121
- echo '<span class="icon">';
122
- echo '<svg xmlns="http://www.w3.org/2000/svg" fill="#674E00" height="14px" width="14px" viewBox="0 0 576 512" role="img" aria-hidden="true" focusable="false"><path d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></svg>';
123
- echo '</span>';
124
- echo '<div style="float: left">';
125
- printf(
126
- /* translators: 1: link to Firefox website; 2: link to Chrome website; 3: link to Edge website; 4: link close tag. */
127
  esc_html__( 'The browser you are currently using is unfortunately rather dated. Since we strive to give you the best experience possible, we no longer support this browser. Instead, please use %1$sFirefox%4$s, %2$sChrome%4$s or %3$sMicrosoft Edge%4$s.', 'wordpress-seo' ),
128
  '<a href="https://www.mozilla.org/firefox/new/">',
129
- '<a href="https://www.google.com/intl/nl/chrome/">',
130
  '<a href="https://www.microsoft.com/windows/microsoft-edge">',
131
  '</a>'
132
  );
133
- echo '</div></div>';
 
134
  }
135
 
136
  /**
@@ -141,7 +141,6 @@ class WPSEO_Metabox extends WPSEO_Meta {
141
  */
142
  public static function translate_meta_boxes() {
143
  WPSEO_Meta::$meta_fields['general']['title']['title'] = __( 'SEO title', 'wordpress-seo' );
144
-
145
  WPSEO_Meta::$meta_fields['general']['metadesc']['title'] = __( 'Meta description', 'wordpress-seo' );
146
 
147
  /* translators: %s expands to the post type name. */
@@ -391,18 +390,7 @@ class WPSEO_Metabox extends WPSEO_Meta {
391
  $html_after = '';
392
 
393
  if ( WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta' ) === false ) {
394
- $advanced_collapsible = new WPSEO_Paper_Presenter(
395
- __( 'Advanced', 'wordpress-seo' ),
396
- null,
397
- [
398
- 'collapsible' => true,
399
- 'class' => 'metabox wpseo-form wpseo-collapsible-container',
400
- 'content' => $this->get_tab_content( 'advanced' ),
401
- 'paper_id' => 'collapsible-advanced-settings',
402
- ]
403
- );
404
-
405
- $html_after = '<div class="wpseo_content_wrapper">' . $advanced_collapsible->get_output() . '</div>';
406
  }
407
 
408
  /**
5
  * @package WPSEO\Admin
6
  */
7
 
8
+ use Yoast\WP\SEO\Presenters\Admin\Alert_Presenter;
9
+
10
  /**
11
  * This class generates the metabox on the edit post / page as well as contains all page analysis functionality.
12
  */
117
 
118
  /**
119
  * Renders the content for the internet explorer metabox.
120
+ *
121
+ * @return void
122
  */
123
  public function render_internet_explorer_notice() {
124
+ $content = sprintf(
125
+ /* translators: 1: Link start tag to the Firefox website, 2: Link start tag to the Chrome website, 3: Link start tag to the Edge website, 4: Link closing tag. */
 
 
 
 
 
126
  esc_html__( 'The browser you are currently using is unfortunately rather dated. Since we strive to give you the best experience possible, we no longer support this browser. Instead, please use %1$sFirefox%4$s, %2$sChrome%4$s or %3$sMicrosoft Edge%4$s.', 'wordpress-seo' ),
127
  '<a href="https://www.mozilla.org/firefox/new/">',
128
+ '<a href="https://www.google.com/chrome/">',
129
  '<a href="https://www.microsoft.com/windows/microsoft-edge">',
130
  '</a>'
131
  );
132
+
133
+ echo new Alert_Presenter( $content );
134
  }
135
 
136
  /**
141
  */
142
  public static function translate_meta_boxes() {
143
  WPSEO_Meta::$meta_fields['general']['title']['title'] = __( 'SEO title', 'wordpress-seo' );
 
144
  WPSEO_Meta::$meta_fields['general']['metadesc']['title'] = __( 'Meta description', 'wordpress-seo' );
145
 
146
  /* translators: %s expands to the post type name. */
390
  $html_after = '';
391
 
392
  if ( WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta' ) === false ) {
393
+ $html_after = $this->get_tab_content( 'advanced' );
 
 
 
 
 
 
 
 
 
 
 
394
  }
395
 
396
  /**
admin/notifiers/class-post-type-archive-notification-handler.php DELETED
@@ -1,190 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin\Notifiers
6
- */
7
-
8
- /**
9
- * Represents the logic for showing the post type archive notification.
10
- */
11
- class WPSEO_Post_Type_Archive_Notification_Handler extends WPSEO_Dismissible_Notification {
12
-
13
- /**
14
- * Defaults for the title option.
15
- *
16
- * @var array
17
- */
18
- protected $option_defaults = [];
19
-
20
- /**
21
- * Sets the notification identifier.
22
- *
23
- * @codeCoverageIgnore
24
- *
25
- * @return void
26
- */
27
- public function __construct() {
28
- $this->notification_identifier = 'post-type-archive-notification';
29
- }
30
-
31
- /**
32
- * Checks if the notice should be shown.
33
- *
34
- * @return bool True when applicable.
35
- */
36
- protected function is_applicable() {
37
- if ( $this->is_notice_dismissed() ) {
38
- return false;
39
- }
40
-
41
- if ( $this->is_new_install() ) {
42
- return false;
43
- }
44
-
45
- return $this->get_post_types() !== [];
46
- }
47
-
48
- /**
49
- * Returns the notification.
50
- *
51
- * @return Yoast_Notification The notification for the notification center.
52
- *
53
- * @codeCoverageIgnore
54
- */
55
- protected function get_notification() {
56
- $post_types = $this->get_post_types();
57
-
58
- $message = esc_html__(
59
- 'We\'ve recently improved the functionality of the Search Appearance settings. Unfortunately, we\'ve discovered that for some edge-cases, saving the settings for specific post type archives might have gone wrong.',
60
- 'wordpress-seo'
61
- );
62
- $message .= PHP_EOL . PHP_EOL;
63
- $message .= sprintf(
64
- /* translators: %1$s is the archive template link start tag, %2$s is the link closing tag, %3$s is a comma separated string with content types. */
65
- _n(
66
- 'Please check the %1$sarchive template%2$s for the following content type: %3$s.',
67
- 'Please check the %1$sarchive templates%2$s for the following content types: %3$s.',
68
- count( $post_types ),
69
- 'wordpress-seo'
70
- ),
71
- '<a href="' . esc_url( admin_url( 'admin.php?page=wpseo_titles#top#post-types' ) ) . '">',
72
- '</a>',
73
- implode( ', ', $post_types )
74
- );
75
- $message .= PHP_EOL . PHP_EOL;
76
- $message .= '<a class="button" href="' . admin_url( '?page=' . WPSEO_Admin::PAGE_IDENTIFIER . '&yoast_dismiss=' . $this->notification_identifier ) . '">' . __( 'Remove this message', 'wordpress-seo' ) . '</a>';
77
-
78
- $notification_options = [
79
- 'type' => Yoast_Notification::WARNING,
80
- 'id' => 'wpseo-' . $this->notification_identifier,
81
- 'priority' => 1.0,
82
- 'capabilities' => 'wpseo_manage_options',
83
- ];
84
-
85
- return new Yoast_Notification( $message, $notification_options );
86
- }
87
-
88
- /**
89
- * Checks if the first activation is done before the release of 7.9.
90
- *
91
- * @return bool True when the install is 'new'.
92
- *
93
- * @codeCoverageIgnore
94
- */
95
- protected function is_new_install() {
96
- return WPSEO_Options::get( 'first_activated_on' ) >= strtotime( '2018-07-24' );
97
- }
98
-
99
- /**
100
- * Returns all the post types which might have wrong archive settings.
101
- *
102
- * @return array The post types.
103
- *
104
- * @codeCoverageIgnore
105
- */
106
- protected function get_post_types() {
107
- static $post_types;
108
-
109
- if ( $post_types === null ) {
110
- $this->option_defaults = WPSEO_Option_Titles::get_instance()->get_defaults();
111
-
112
- $post_types = get_post_types( [ 'public' => true ] );
113
- $post_types = WPSEO_Post_Type::filter_attachment_post_type( $post_types );
114
- $post_types = $this->filter_woocommerce_product_type( $post_types );
115
- $post_types = array_filter( $post_types, [ $this, 'has_custom_archive_slug' ] );
116
- $post_types = array_filter( $post_types, [ $this, 'has_default_templates_set' ] );
117
- }
118
-
119
- return $post_types;
120
- }
121
-
122
- /**
123
- * Filters the WooCommerce product, when Woocommerce is active.
124
- *
125
- * @param array $post_types The post types to filter.
126
- *
127
- * @return array The filtere post types.
128
- *
129
- * @codeCoverageIgnore
130
- */
131
- protected function filter_woocommerce_product_type( $post_types ) {
132
- if ( WPSEO_Utils::is_woocommerce_active() ) {
133
- unset( $post_types['product'] );
134
- }
135
-
136
- return $post_types;
137
- }
138
-
139
- /**
140
- * Checks if the archive slug for the post type is overridden.
141
- *
142
- * @param string $post_type_name The post type's name.
143
- *
144
- * @return bool True when the archive slug is overridden.
145
- *
146
- * @codeCoverageIgnore
147
- */
148
- protected function has_custom_archive_slug( $post_type_name ) {
149
- $post_type = get_post_type_object( $post_type_name );
150
- if ( $post_type === null || ! WPSEO_Post_Type::has_archive( $post_type ) ) {
151
- return false;
152
- }
153
-
154
- // When the archive value is not TRUE it will be a custom archive slug.
155
- return ( $post_type->has_archive !== true );
156
- }
157
-
158
- /**
159
- * Checks if the default templates are set for given post type.
160
- *
161
- * @param string $post_type_name The post type name.
162
- *
163
- * @return bool True when the default templates are set.
164
- *
165
- * @codeCoverageIgnore
166
- */
167
- protected function has_default_templates_set( $post_type_name ) {
168
- $title_option_name = 'title-ptarchive-' . $post_type_name;
169
- $metadesc_option_name = 'metadesc-ptarchive-' . $post_type_name;
170
-
171
- return ( $this->is_equal_to_default( $title_option_name ) && $this->is_equal_to_default( $metadesc_option_name ) );
172
- }
173
-
174
- /**
175
- * Checks if value for given option name is equal to the default value.
176
- *
177
- * @param string $option_name The option name to check.
178
- *
179
- * @return bool True when the option value is equal to the default value.
180
- *
181
- * @codeCoverageIgnore
182
- */
183
- protected function is_equal_to_default( $option_name ) {
184
- if ( ! isset( $this->option_defaults[ $option_name ] ) ) {
185
- return false;
186
- }
187
-
188
- return ( WPSEO_Options::get( $option_name ) === $this->option_defaults[ $option_name ] );
189
- }
190
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/pages/tools.php CHANGED
@@ -54,7 +54,7 @@ if ( $tool_page === '' ) {
54
  $attr = ( ! empty( $tool['attr'] ) ) ? $tool['attr'] : '';
55
 
56
  echo '<li>';
57
- echo '<strong><a href="', esc_url( $href ), '" ', esc_attr( $attr ) , '>', esc_html( $tool['title'] ), '</a></strong><br/>';
58
  echo esc_html( $tool['desc'] );
59
  echo '</li>';
60
  }
@@ -67,7 +67,6 @@ if ( $tool_page === '' ) {
67
  echo '</ul>';
68
 
69
  echo '<input type="hidden" id="wpseo_recalculate_nonce" name="wpseo_recalculate_nonce" value="' . esc_attr( wp_create_nonce( 'wpseo_recalculate' ) ) . '" />';
70
-
71
  }
72
  else {
73
  echo '<a href="', esc_url( admin_url( 'admin.php?page=wpseo_tools' ) ), '">', esc_html__( '&laquo; Back to Tools page', 'wordpress-seo' ), '</a>';
54
  $attr = ( ! empty( $tool['attr'] ) ) ? $tool['attr'] : '';
55
 
56
  echo '<li>';
57
+ echo '<strong><a href="', esc_url( $href ), '" ', esc_attr( $attr ), '>', esc_html( $tool['title'] ), '</a></strong><br/>';
58
  echo esc_html( $tool['desc'] );
59
  echo '</li>';
60
  }
67
  echo '</ul>';
68
 
69
  echo '<input type="hidden" id="wpseo_recalculate_nonce" name="wpseo_recalculate_nonce" value="' . esc_attr( wp_create_nonce( 'wpseo_recalculate' ) ) . '" />';
 
70
  }
71
  else {
72
  echo '<a href="', esc_url( admin_url( 'admin.php?page=wpseo_tools' ) ), '">', esc_html__( '&laquo; Back to Tools page', 'wordpress-seo' ), '</a>';
admin/roles/class-abstract-role-manager.php CHANGED
@@ -27,11 +27,10 @@ abstract class WPSEO_Abstract_Role_Manager implements WPSEO_Role_Manager {
27
  * @return void
28
  */
29
  public function register( $role, $display_name, $template = null ) {
30
- $this->roles[ $role ] =
31
- (object) [
32
- 'display_name' => $display_name,
33
- 'template' => $template,
34
- ];
35
  }
36
 
37
  /**
27
  * @return void
28
  */
29
  public function register( $role, $display_name, $template = null ) {
30
+ $this->roles[ $role ] = (object) [
31
+ 'display_name' => $display_name,
32
+ 'template' => $template,
33
+ ];
 
34
  }
35
 
36
  /**
admin/ryte/class-ryte.php CHANGED
@@ -13,7 +13,7 @@ class WPSEO_Ryte implements WPSEO_WordPress_Integration {
13
  /**
14
  * Is the request started by pressing the fetch button.
15
  *
16
- * @var boolean
17
  */
18
  private $is_manual_request = false;
19
 
13
  /**
14
  * Is the request started by pressing the fetch button.
15
  *
16
+ * @var bool
17
  */
18
  private $is_manual_request = false;
19
 
admin/services/class-indexable.php CHANGED
@@ -72,7 +72,6 @@ class WPSEO_Indexable_Service {
72
 
73
  if ( $object_type === 'term' ) {
74
  return new WPSEO_Indexable_Service_Term_Provider();
75
-
76
  }
77
 
78
  throw WPSEO_Invalid_Argument_Exception::invalid_callable_parameter( $object_type, 'provider' );
72
 
73
  if ( $object_type === 'term' ) {
74
  return new WPSEO_Indexable_Service_Term_Provider();
 
75
  }
76
 
77
  throw WPSEO_Invalid_Argument_Exception::invalid_callable_parameter( $object_type, 'provider' );
admin/taxonomy/class-taxonomy-metabox.php CHANGED
@@ -135,18 +135,7 @@ class WPSEO_Taxonomy_Metabox {
135
  if ( WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta' ) === false ) {
136
  $taxonomy_settings_fields = new WPSEO_Taxonomy_Settings_Fields( $this->term );
137
 
138
- $advanced_collapsible = new WPSEO_Paper_Presenter(
139
- __( 'Advanced', 'wordpress-seo' ),
140
- null,
141
- [
142
- 'collapsible' => true,
143
- 'class' => 'metabox wpseo-form wpseo-collapsible-container',
144
- 'content' => $this->taxonomy_tab_content->html( $taxonomy_settings_fields->get() ),
145
- 'paper_id' => 'collapsible-advanced-settings',
146
- ]
147
- );
148
-
149
- $html_after = '<div class="wpseo_content_wrapper">' . $advanced_collapsible->get_output() . '</div>';
150
  }
151
 
152
  return new WPSEO_Metabox_Section_React(
135
  if ( WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta' ) === false ) {
136
  $taxonomy_settings_fields = new WPSEO_Taxonomy_Settings_Fields( $this->term );
137
 
138
+ $html_after = $this->taxonomy_tab_content->html( $taxonomy_settings_fields->get() );
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
  return new WPSEO_Metabox_Section_React(
admin/taxonomy/class-taxonomy-settings-fields.php CHANGED
@@ -9,14 +9,6 @@
9
  * This class parses all the values for the general tab in the Yoast SEO settings metabox.
10
  */
11
  class WPSEO_Taxonomy_Settings_Fields extends WPSEO_Taxonomy_Fields {
12
-
13
- /**
14
- * Options array for the no-index options, including translated labels.
15
- *
16
- * @var array
17
- */
18
- private $no_index_options = [];
19
-
20
  /**
21
  * The WPSEO_Taxonomy_Settings_Fields class constructor.
22
  *
@@ -24,7 +16,6 @@ class WPSEO_Taxonomy_Settings_Fields extends WPSEO_Taxonomy_Fields {
24
  */
25
  public function __construct( $term ) {
26
  parent::__construct( $term );
27
- $this->translate_meta_options();
28
  }
29
 
30
  /**
@@ -33,83 +24,27 @@ class WPSEO_Taxonomy_Settings_Fields extends WPSEO_Taxonomy_Fields {
33
  * @return array Fields to be used on the General tab.
34
  */
35
  public function get() {
36
- $labels = $this->get_taxonomy_labels();
37
  $fields = [
38
  'noindex' => $this->get_field_config(
39
- /* translators: %s = taxonomy name. */
40
- esc_html( sprintf( __( 'Allow search engines to show this %s in search results?', 'wordpress-seo' ), $labels->singular_name ) ),
41
  '',
42