Yoast SEO - Version 9.0

Version Description

Download this release

Release Info

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

Code changes from version 8.4 to 9.0

Files changed (174) hide show
  1. admin/ajax.php +1 -2
  2. admin/class-add-keyword-modal.php +5 -3
  3. admin/class-admin-asset-analysis-worker-location.php +3 -2
  4. admin/class-admin-asset-manager.php +5 -6
  5. admin/class-admin-asset-yoast-components-l10n.php +3 -2
  6. admin/class-admin-gutenberg-compatibility-notification.php +3 -3
  7. admin/class-admin-init.php +6 -4
  8. admin/class-admin-utils.php +3 -0
  9. admin/class-admin.php +24 -19
  10. admin/class-asset.php +15 -8
  11. admin/class-cornerstone.php +0 -94
  12. admin/class-customizer.php +7 -7
  13. admin/class-database-proxy.php +2 -2
  14. admin/class-expose-shortlinks.php +17 -14
  15. admin/class-gutenberg-compatibility.php +2 -2
  16. admin/class-help-center.php +3 -0
  17. admin/class-keyword-synonyms-modal.php +2 -2
  18. admin/class-meta-columns.php +2 -2
  19. admin/class-meta-storage.php +2 -1
  20. admin/class-meta-table-accessible.php +3 -0
  21. admin/class-multiple-keywords-modal.php +2 -2
  22. admin/class-paper-presenter.php +1 -1
  23. admin/class-plugin-availability.php +2 -1
  24. admin/class-premium-popup.php +2 -2
  25. admin/class-premium-upsell-admin-block.php +1 -1
  26. admin/class-primary-term-admin.php +1 -0
  27. admin/class-product-upsell-notice.php +1 -1
  28. admin/class-recalculate-scores.php +1 -1
  29. admin/class-social-admin.php +2 -1
  30. admin/class-yoast-form.php +151 -52
  31. admin/class-yoast-network-admin.php +7 -4
  32. admin/class-yoast-network-settings-api.php +3 -2
  33. admin/config-ui/class-configuration-options-adapter.php +19 -16
  34. admin/config-ui/class-configuration-page.php +18 -15
  35. admin/config-ui/components/class-component-suggestions.php +34 -6
  36. admin/config-ui/fields/class-field-google-search-console-intro.php +1 -1
  37. admin/config-ui/fields/class-field-success-message.php +2 -2
  38. admin/config-ui/fields/class-field-suggestions.php +5 -6
  39. admin/endpoints/class-endpoint-indexable.php +26 -16
  40. admin/filters/class-cornerstone-filter.php +19 -3
  41. admin/formatter/class-metabox-formatter.php +38 -37
  42. admin/google_search_console/class-gsc-marker.php +1 -1
  43. admin/google_search_console/class-gsc-modal.php +1 -1
  44. admin/import/class-import-settings.php +1 -1
  45. admin/links/class-link-installer.php +1 -1
  46. admin/links/class-link-reindex-dashboard.php +36 -33
  47. admin/links/class-link-table-accessible.php +3 -0
  48. admin/metabox/class-metabox-keyword-synonyms-config.php +2 -2
  49. admin/metabox/class-metabox-multiple-keywords-config.php +3 -3
  50. admin/metabox/class-metabox-section-react.php +1 -1
  51. admin/metabox/class-metabox.php +24 -4
  52. admin/notifiers/class-configuration-notifier.php +2 -1
  53. admin/notifiers/class-post-type-archive-notification-handler.php +3 -3
  54. admin/onpage/class-ryte-service.php +1 -1
  55. admin/pages/network.php +1 -0
  56. admin/services/class-indexable-post-provider.php +166 -50
  57. admin/services/class-indexable-provider.php +36 -0
  58. admin/services/class-indexable-term-provider.php +119 -55
  59. admin/services/class-indexable.php +53 -25
  60. admin/services/interface-indexable-provider.php +12 -1
  61. admin/statistics/class-statistics-service.php +1 -1
  62. admin/taxonomy/class-taxonomy-fields-presenter.php +22 -2
  63. admin/taxonomy/class-taxonomy-metabox.php +3 -3
  64. admin/taxonomy/class-taxonomy-social-fields.php +5 -0
  65. admin/taxonomy/class-taxonomy.php +3 -0
  66. admin/views/class-yoast-feature-toggle.php +105 -0
  67. admin/views/class-yoast-feature-toggles.php +179 -0
  68. admin/views/licenses.php +4 -4
  69. admin/views/sidebar.php +10 -10
  70. admin/views/tabs/dashboard/features.php +4 -101
  71. admin/views/tabs/metas/paper-content/breadcrumbs-content.php +1 -1
  72. admin/views/tabs/metas/paper-content/date-archives-settings.php +29 -29
  73. admin/views/tabs/network/features.php +65 -0
  74. admin/views/tabs/social/facebook.php +1 -1
  75. admin/views/tool-file-editor.php +1 -1
  76. admin/views/user-profile.php +2 -2
  77. admin/watchers/class-slug-change-watcher.php +1 -1
  78. css/dist/admin-global-840-rtl.min.css +0 -1
  79. css/dist/admin-global-840.min.css +0 -1
  80. css/dist/admin-global-900-rtl.min.css +1 -0
  81. css/dist/admin-global-900.min.css +1 -0
  82. css/dist/{adminbar-840-rtl.min.css → adminbar-900-rtl.min.css} +0 -0
  83. css/dist/{adminbar-840.min.css → adminbar-900.min.css} +0 -0
  84. css/dist/{alerts-840-rtl.min.css → alerts-900-rtl.min.css} +0 -0
  85. css/dist/{alerts-840.min.css → alerts-900.min.css} +0 -0
  86. css/dist/{dashboard-840-rtl.min.css → dashboard-900-rtl.min.css} +0 -0
  87. css/dist/{dashboard-840.min.css → dashboard-900.min.css} +0 -0
  88. css/dist/{edit-page-840-rtl.min.css → edit-page-900-rtl.min.css} +0 -0
  89. css/dist/{edit-page-840.min.css → edit-page-900.min.css} +0 -0
  90. css/dist/{featured-image-840-rtl.min.css → featured-image-900-rtl.min.css} +0 -0
  91. css/dist/{featured-image-840.min.css → featured-image-900.min.css} +0 -0
  92. css/dist/{filter-explanation-840-rtl.min.css → filter-explanation-900-rtl.min.css} +0 -0
  93. css/dist/{filter-explanation-840.min.css → filter-explanation-900.min.css} +0 -0
  94. css/dist/{inside-editor-840-rtl.min.css → inside-editor-900-rtl.min.css} +0 -0
  95. css/dist/{inside-editor-840.min.css → inside-editor-900.min.css} +0 -0
  96. css/dist/{metabox-840-rtl.min.css → metabox-900-rtl.min.css} +0 -0
  97. css/dist/{metabox-840.min.css → metabox-900.min.css} +0 -0
  98. css/dist/{metabox-primary-category-840-rtl.min.css → metabox-primary-category-900-rtl.min.css} +0 -0
  99. css/dist/{metabox-primary-category-840.min.css → metabox-primary-category-900.min.css} +0 -0
  100. css/dist/{search-appearance-840-rtl.min.css → search-appearance-900-rtl.min.css} +0 -0
  101. css/dist/{search-appearance-840.min.css → search-appearance-900.min.css} +0 -0
  102. css/dist/structured-data-blocks-840-rtl.min.css +0 -1
  103. css/dist/structured-data-blocks-840.min.css +0 -1
  104. css/dist/structured-data-blocks-900-rtl.min.css +1 -0
  105. css/dist/structured-data-blocks-900.min.css +1 -0
  106. css/dist/toggle-switch-840-rtl.min.css +0 -1
  107. css/dist/toggle-switch-840.min.css +0 -1
  108. css/dist/toggle-switch-900-rtl.min.css +1 -0
  109. css/dist/toggle-switch-900.min.css +1 -0
  110. css/dist/{wpseo-dismissible-840-rtl.min.css → wpseo-dismissible-900-rtl.min.css} +0 -0
  111. css/dist/{wpseo-dismissible-840.min.css → wpseo-dismissible-900.min.css} +0 -0
  112. css/dist/{yoast-components-840-rtl.min.css → yoast-components-900-rtl.min.css} +0 -0
  113. css/dist/{yoast-components-840.min.css → yoast-components-900.min.css} +0 -0
  114. css/dist/yoast-extensions-840-rtl.min.css +0 -1
  115. css/dist/yoast-extensions-840.min.css +0 -1
  116. css/dist/yoast-extensions-900-rtl.min.css +1 -0
  117. css/dist/yoast-extensions-900.min.css +1 -0
  118. css/dist/{yst_plugin_tools-840-rtl.min.css → yst_plugin_tools-900-rtl.min.css} +1 -1
  119. css/dist/{yst_plugin_tools-840.min.css → yst_plugin_tools-900.min.css} +1 -1
  120. css/dist/{yst_seo_score-840-rtl.min.css → yst_seo_score-900-rtl.min.css} +0 -0
  121. css/dist/{yst_seo_score-840.min.css → yst_seo_score-900.min.css} +0 -0
  122. deprecated/class-cornerstone.php +51 -0
  123. frontend/class-breadcrumbs.php +3 -3
  124. frontend/class-frontend.php +50 -42
  125. frontend/class-opengraph-image.php +118 -48
  126. frontend/class-opengraph.php +2 -0
  127. frontend/class-twitter.php +13 -19
  128. images/exclamation-triangle.svg +1 -0
  129. inc/class-upgrade.php +22 -1
  130. inc/class-wpseo-admin-bar-menu.php +7 -7
  131. inc/class-wpseo-content-images.php +16 -13
  132. inc/class-wpseo-custom-taxonomies.php +2 -2
  133. inc/class-wpseo-endpoint-factory.php +173 -0
  134. inc/class-wpseo-image-utils.php +2 -2
  135. inc/class-wpseo-meta.php +1 -13
  136. inc/class-wpseo-rank.php +1 -1
  137. inc/class-wpseo-replace-vars.php +1 -1
  138. inc/class-wpseo-shortlinker.php +30 -13
  139. inc/class-wpseo-utils.php +36 -36
  140. inc/class-wpseo-validator.php +72 -0
  141. inc/exceptions/class-invalid-argument-exception.php +153 -0
  142. inc/exceptions/class-invalid-indexable-exception.php +46 -0
  143. inc/exceptions/class-rest-request-exception.php +31 -0
  144. inc/indexables/class-indexable.php +124 -0
  145. inc/indexables/class-object-type.php +104 -0
  146. inc/indexables/class-post-indexable.php +101 -0
  147. inc/indexables/class-post-object-type.php +31 -0
  148. inc/indexables/class-term-indexable.php +124 -0
  149. inc/indexables/class-term-object-type.php +31 -0
  150. inc/indexables/validators/class-endpoint-validator.php +21 -0
  151. inc/indexables/validators/class-keyword-validator.php +29 -0
  152. inc/indexables/validators/class-link-validator.php +29 -0
  153. inc/indexables/validators/class-meta-values-validator.php +51 -0
  154. inc/indexables/validators/class-object-type-validator.php +66 -0
  155. inc/indexables/validators/class-opengraph-validator.php +35 -0
  156. inc/indexables/validators/class-robots-validator.php +44 -0
  157. inc/indexables/validators/class-twitter-validator.php +35 -0
  158. inc/options/class-wpseo-option-ms.php +15 -4
  159. inc/options/class-wpseo-option-social.php +29 -18
  160. inc/options/class-wpseo-option-titles.php +56 -73
  161. inc/options/class-wpseo-option-wpseo.php +121 -0
  162. inc/options/class-wpseo-option.php +80 -6
  163. inc/options/class-wpseo-options.php +10 -1
  164. inc/options/class-wpseo-taxonomy-meta.php +2 -2
  165. inc/sitemaps/class-post-type-sitemap-provider.php +12 -9
  166. inc/sitemaps/class-sitemap-image-parser.php +1 -1
  167. inc/sitemaps/class-sitemaps-admin.php +4 -6
  168. inc/sitemaps/class-sitemaps-cache.php +14 -4
  169. inc/sitemaps/class-sitemaps.php +7 -1
  170. inc/sitemaps/class-taxonomy-sitemap-provider.php +12 -9
  171. inc/structured-data-blocks/class-faq-block.php +2 -1
  172. inc/structured-data-blocks/class-how-to-block.php +2 -1
  173. inc/wpseo-non-ajax-functions.php +12 -4
  174. js/dist/analysis-840.min.js +0 -13
admin/ajax.php CHANGED
@@ -362,8 +362,7 @@ new WPSEO_Taxonomy_Columns();
362
  // Setting the notice for the recalculate the posts.
363
  new Yoast_Dismissable_Notice_Ajax( 'recalculate', Yoast_Dismissable_Notice_Ajax::FOR_SITE );
364
 
365
- /********************** DEPRECATED METHODS **********************/
366
-
367
 
368
  /**
369
  * Removes stopword from the sample permalink that is generated in an AJAX request
362
  // Setting the notice for the recalculate the posts.
363
  new Yoast_Dismissable_Notice_Ajax( 'recalculate', Yoast_Dismissable_Notice_Ajax::FOR_SITE );
364
 
365
+ /* ********************* DEPRECATED FUNCTIONS ********************* */
 
366
 
367
  /**
368
  * Removes stopword from the sample permalink that is generated in an AJAX request
admin/class-add-keyword-modal.php CHANGED
@@ -18,7 +18,7 @@ class WPSEO_Add_Keyword_Modal {
18
  */
19
  public function get_translations() {
20
  return array(
21
- 'title' => __( 'Would you like to add more than one keyword?', 'wordpress-seo' ),
22
  'intro' => sprintf(
23
  /* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
24
  __( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
@@ -27,12 +27,14 @@ class WPSEO_Add_Keyword_Modal {
27
  'link' => WPSEO_Shortlinker::get( 'https://yoa.st/pe-premium-page' ),
28
  'other' => sprintf(
29
  /* translators: %s expands to 'Yoast SEO Premium'. */
30
- __( 'Other benefits of %s for you:', 'wordpress-seo' ), 'Yoast SEO Premium'
 
31
  ),
32
  'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/add-keywords-popup' ),
33
  'buy' => sprintf(
34
  /* translators: %s expands to 'Yoast SEO Premium'. */
35
- __( 'Get %s now!', 'wordpress-seo' ), 'Yoast SEO Premium'
 
36
  ),
37
  'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
38
  'a11yNotice.opensInNewTab' => __( '(Opens in a new browser tab)', 'wordpress-seo' ),
18
  */
19
  public function get_translations() {
20
  return array(
21
+ 'title' => __( 'Would you like to add more than one keyphrase?', 'wordpress-seo' ),
22
  'intro' => sprintf(
23
  /* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
24
  __( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
27
  'link' => WPSEO_Shortlinker::get( 'https://yoa.st/pe-premium-page' ),
28
  'other' => sprintf(
29
  /* translators: %s expands to 'Yoast SEO Premium'. */
30
+ __( 'Other benefits of %s for you:', 'wordpress-seo' ),
31
+ 'Yoast SEO Premium'
32
  ),
33
  'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/add-keywords-popup' ),
34
  'buy' => sprintf(
35
  /* translators: %s expands to 'Yoast SEO Premium'. */
36
+ __( 'Get %s', 'wordpress-seo' ),
37
+ 'Yoast SEO Premium'
38
  ),
39
  'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
40
  'a11yNotice.opensInNewTab' => __( '(Opens in a new browser tab)', 'wordpress-seo' ),
admin/class-admin-asset-analysis-worker-location.php CHANGED
@@ -33,10 +33,11 @@ final class WPSEO_Admin_Asset_Analysis_Worker_Location implements WPSEO_Admin_As
33
  }
34
 
35
  $this->asset_location = WPSEO_Admin_Asset_Manager::create_default_location();
36
- $this->asset = new WPSEO_Admin_Asset( array(
37
  'name' => $name,
38
  'src' => 'wp-seo-' . $name . '-' . $flat_version,
39
- ) );
 
40
  }
41
 
42
  /**
33
  }
34
 
35
  $this->asset_location = WPSEO_Admin_Asset_Manager::create_default_location();
36
+ $asset_arguments = array(
37
  'name' => $name,
38
  'src' => 'wp-seo-' . $name . '-' . $flat_version,
39
+ );
40
+ $this->asset = new WPSEO_Admin_Asset( $asset_arguments );
41
  }
42
 
43
  /**
admin/class-admin-asset-manager.php CHANGED
@@ -127,13 +127,12 @@ class WPSEO_Admin_Asset_Manager {
127
  */
128
  public function special_styles() {
129
  $flat_version = $this->flatten_version( WPSEO_VERSION );
130
-
131
- return array(
132
- 'inside-editor' => new WPSEO_Admin_Asset( array(
133
- 'name' => 'inside-editor',
134
- 'src' => 'inside-editor-' . $flat_version,
135
- ) ),
136
  );
 
 
137
  }
138
 
139
  /**
127
  */
128
  public function special_styles() {
129
  $flat_version = $this->flatten_version( WPSEO_VERSION );
130
+ $asset_args = array(
131
+ 'name' => 'inside-editor',
132
+ 'src' => 'inside-editor-' . $flat_version,
 
 
 
133
  );
134
+
135
+ return array( 'inside-editor' => new WPSEO_Admin_Asset( $asset_args ) );
136
  }
137
 
138
  /**
admin/class-admin-asset-yoast-components-l10n.php CHANGED
@@ -16,10 +16,11 @@ final class WPSEO_Admin_Asset_Yoast_Components_L10n {
16
  * @return void
17
  */
18
  public function localize_script( $script_handle ) {
19
- wp_localize_script( $script_handle, 'wpseoYoastJSL10n', array(
20
  'yoast-components' => $this->get_translations( 'yoast-components' ),
21
  'wordpress-seo' => $this->get_translations( 'wordpress-seojs' ),
22
- ) );
 
23
  }
24
 
25
  /**
16
  * @return void
17
  */
18
  public function localize_script( $script_handle ) {
19
+ $translations = array(
20
  'yoast-components' => $this->get_translations( 'yoast-components' ),
21
  'wordpress-seo' => $this->get_translations( 'wordpress-seojs' ),
22
+ );
23
+ wp_localize_script( $script_handle, 'wpseoYoastJSL10n', $translations );
24
  }
25
 
26
  /**
admin/class-admin-gutenberg-compatibility-notification.php CHANGED
@@ -68,7 +68,7 @@ class WPSEO_Admin_Gutenberg_Compatibility_Notification implements WPSEO_WordPres
68
  $level = $this->compatibility_checker->is_below_minimum() ? Yoast_Notification::ERROR : Yoast_Notification::WARNING;
69
 
70
  $message = sprintf(
71
- /* translators: %1$s expands to Yoast SEO, %2$s expands to the installed version, %3$s expands to Gutenberg */
72
  __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ),
73
  'Yoast SEO',
74
  $this->compatibility_checker->get_installed_version(),
@@ -78,8 +78,8 @@ class WPSEO_Admin_Gutenberg_Compatibility_Notification implements WPSEO_WordPres
78
  $notification = new Yoast_Notification(
79
  $message,
80
  array(
81
- 'id' => $this->notification_id,
82
- 'type' => $level,
83
  'priority' => 1,
84
  )
85
  );
68
  $level = $this->compatibility_checker->is_below_minimum() ? Yoast_Notification::ERROR : Yoast_Notification::WARNING;
69
 
70
  $message = sprintf(
71
+ /* translators: %1$s expands to Yoast SEO, %2$s expands to the installed version, %3$s expands to Gutenberg */
72
  __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ),
73
  'Yoast SEO',
74
  $this->compatibility_checker->get_installed_version(),
78
  $notification = new Yoast_Notification(
79
  $message,
80
  array(
81
+ 'id' => $this->notification_id,
82
+ 'type' => $level,
83
  'priority' => 1,
84
  )
85
  );
admin/class-admin-init.php CHANGED
@@ -109,10 +109,11 @@ class WPSEO_Admin_Init {
109
 
110
  $current_url = ( is_ssl() ? 'https://' : 'http://' );
111
  $current_url .= sanitize_text_field( $_SERVER['SERVER_NAME'] ) . sanitize_text_field( $_SERVER['REQUEST_URI'] );
112
- $customize_url = add_query_arg( array(
113
  'autofocus[control]' => 'blogdescription',
114
  'url' => urlencode( $current_url ),
115
- ), wp_customize_url() );
 
116
 
117
  $info_message = sprintf(
118
  /* translators: 1: link open tag; 2: link close tag. */
@@ -212,7 +213,7 @@ class WPSEO_Admin_Init {
212
 
213
  // We are checking against the WordPress internal translation.
214
  // @codingStandardsIgnoreLine
215
- $translated_blog_description = __( 'Just another WordPress site' );
216
 
217
  return $translated_blog_description === $blog_description || $default_blog_description === $blog_description;
218
  }
@@ -567,7 +568,8 @@ class WPSEO_Admin_Init {
567
  'textdomain' => 'wordpress-seo',
568
  'plugin_name' => 'Yoast SEO',
569
  'hook' => 'wpseo_admin_promo_footer',
570
- ), false
 
571
  );
572
 
573
  $message = $i18n_module->get_promo_message();
109
 
110
  $current_url = ( is_ssl() ? 'https://' : 'http://' );
111
  $current_url .= sanitize_text_field( $_SERVER['SERVER_NAME'] ) . sanitize_text_field( $_SERVER['REQUEST_URI'] );
112
+ $query_args = array(
113
  'autofocus[control]' => 'blogdescription',
114
  'url' => urlencode( $current_url ),
115
+ );
116
+ $customize_url = add_query_arg( $query_args, wp_customize_url() );
117
 
118
  $info_message = sprintf(
119
  /* translators: 1: link open tag; 2: link close tag. */
213
 
214
  // We are checking against the WordPress internal translation.
215
  // @codingStandardsIgnoreLine
216
+ $translated_blog_description = __( 'Just another WordPress site', 'default' );
217
 
218
  return $translated_blog_description === $blog_description || $default_blog_description === $blog_description;
219
  }
568
  'textdomain' => 'wordpress-seo',
569
  'plugin_name' => 'Yoast SEO',
570
  'hook' => 'wpseo_admin_promo_footer',
571
+ ),
572
+ false
573
  );
574
 
575
  $message = $i18n_module->get_promo_message();
admin/class-admin-utils.php CHANGED
@@ -67,10 +67,13 @@ class WPSEO_Admin_Utils {
67
  );
68
  }
69
 
 
 
70
  /**
71
  * Determines whether or not the user has an invalid version of PHP installed.
72
  *
73
  * @deprecated 8.1
 
74
  *
75
  * @return bool Whether or not PHP 5.2 or lower is installed.
76
  */
67
  );
68
  }
69
 
70
+ /* ********************* DEPRECATED METHODS ********************* */
71
+
72
  /**
73
  * Determines whether or not the user has an invalid version of PHP installed.
74
  *
75
  * @deprecated 8.1
76
+ * @codeCoverageIgnore
77
  *
78
  * @return bool Whether or not PHP 5.2 or lower is installed.
79
  */
admin/class-admin.php CHANGED
@@ -48,7 +48,7 @@ class WPSEO_Admin {
48
  );
49
 
50
  if ( WPSEO_Metabox::is_post_overview( $pagenow ) || WPSEO_Metabox::is_post_edit( $pagenow ) ) {
51
- $this->admin_features['primary_category'] = new WPSEO_Primary_Term_Admin();
52
  }
53
 
54
  if ( filter_input( INPUT_GET, 'page' ) === 'wpseo_tools' && filter_input( INPUT_GET, 'tool' ) === null ) {
@@ -318,17 +318,6 @@ class WPSEO_Admin {
318
  $upsell->initialize();
319
  }
320
 
321
- /**
322
- * Initializes Whip to show a notice for outdated PHP versions.
323
- *
324
- * @deprecated 8.1
325
- *
326
- * @return void
327
- */
328
- public function check_php_version() {
329
- // Intentionally left empty.
330
- }
331
-
332
  /**
333
  * Whether we are on the admin dashboard page.
334
  *
@@ -346,9 +335,6 @@ class WPSEO_Admin {
346
  return;
347
  }
348
 
349
- $cornerstone = new WPSEO_Cornerstone();
350
- $cornerstone->register_hooks();
351
-
352
  $cornerstone_filter = new WPSEO_Cornerstone_Filter();
353
  $cornerstone_filter->register_hooks();
354
  }
@@ -408,13 +394,13 @@ class WPSEO_Admin {
408
  return $integrations;
409
  }
410
 
411
- /********************** DEPRECATED METHODS **********************/
412
 
413
- // @codeCoverageIgnoreStart
414
  /**
415
  * Register the menu item and its sub menu's.
416
  *
417
  * @deprecated 5.5
 
418
  */
419
  public function register_settings_page() {
420
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
@@ -424,6 +410,7 @@ class WPSEO_Admin {
424
  * Register the settings page for the Network settings.
425
  *
426
  * @deprecated 5.5
 
427
  */
428
  public function register_network_settings_page() {
429
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
@@ -433,6 +420,7 @@ class WPSEO_Admin {
433
  * Load the form for a WPSEO admin page.
434
  *
435
  * @deprecated 5.5
 
436
  */
437
  public function load_page() {
438
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
@@ -442,6 +430,7 @@ class WPSEO_Admin {
442
  * Loads the form for the network configuration page.
443
  *
444
  * @deprecated 5.5
 
445
  */
446
  public function network_config_page() {
447
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
@@ -451,6 +440,8 @@ class WPSEO_Admin {
451
  * Filters all advanced settings pages from the given pages.
452
  *
453
  * @deprecated 5.5
 
 
454
  * @param array $pages The pages to filter.
455
  */
456
  public function filter_settings_pages( array $pages ) {
@@ -461,6 +452,7 @@ class WPSEO_Admin {
461
  * Cleans stopwords out of the slug, if the slug hasn't been set yet.
462
  *
463
  * @deprecated 7.0
 
464
  *
465
  * @return void
466
  */
@@ -472,6 +464,7 @@ class WPSEO_Admin {
472
  * Filter the stopwords from the slug.
473
  *
474
  * @deprecated 7.0
 
475
  *
476
  * @return void
477
  */
@@ -483,13 +476,15 @@ class WPSEO_Admin {
483
  * Adds contextual help to the titles & metas page.
484
  *
485
  * @deprecated 5.6.0
 
486
  */
487
  public function title_metas_help_tab() {
488
  _deprecated_function( __METHOD__, '5.6.0' );
489
 
490
  $screen = get_current_screen();
491
 
492
- $screen->set_help_sidebar( '
 
493
  <p><strong>' . __( 'For more information:', 'wordpress-seo' ) . '</strong></p>
494
  <p><a target="_blank" href="https://yoast.com/wordpress-seo/#titles">' . __( 'Title optimization', 'wordpress-seo' ) . '</a></p>
495
  <p><a target="_blank" href="https://yoast.com/google-page-title/">' . __( 'Why Google won\'t display the right page title', 'wordpress-seo' ) . '</a></p>'
@@ -526,5 +521,15 @@ class WPSEO_Admin {
526
  );
527
  }
528
 
529
- // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
530
  }
48
  );
49
 
50
  if ( WPSEO_Metabox::is_post_overview( $pagenow ) || WPSEO_Metabox::is_post_edit( $pagenow ) ) {
51
+ $this->admin_features['primary_category'] = new WPSEO_Primary_Term_Admin();
52
  }
53
 
54
  if ( filter_input( INPUT_GET, 'page' ) === 'wpseo_tools' && filter_input( INPUT_GET, 'tool' ) === null ) {
318
  $upsell->initialize();
319
  }
320
 
 
 
 
 
 
 
 
 
 
 
 
321
  /**
322
  * Whether we are on the admin dashboard page.
323
  *
335
  return;
336
  }
337
 
 
 
 
338
  $cornerstone_filter = new WPSEO_Cornerstone_Filter();
339
  $cornerstone_filter->register_hooks();
340
  }
394
  return $integrations;
395
  }
396
 
397
+ /* ********************* DEPRECATED METHODS ********************* */
398
 
 
399
  /**
400
  * Register the menu item and its sub menu's.
401
  *
402
  * @deprecated 5.5
403
+ * @codeCoverageIgnore
404
  */
405
  public function register_settings_page() {
406
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
410
  * Register the settings page for the Network settings.
411
  *
412
  * @deprecated 5.5
413
+ * @codeCoverageIgnore
414
  */
415
  public function register_network_settings_page() {
416
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
420
  * Load the form for a WPSEO admin page.
421
  *
422
  * @deprecated 5.5
423
+ * @codeCoverageIgnore
424
  */
425
  public function load_page() {
426
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
430
  * Loads the form for the network configuration page.
431
  *
432
  * @deprecated 5.5
433
+ * @codeCoverageIgnore
434
  */
435
  public function network_config_page() {
436
  _deprecated_function( __METHOD__, 'WPSEO 5.5.0' );
440
  * Filters all advanced settings pages from the given pages.
441
  *
442
  * @deprecated 5.5
443
+ * @codeCoverageIgnore
444
+ *
445
  * @param array $pages The pages to filter.
446
  */
447
  public function filter_settings_pages( array $pages ) {
452
  * Cleans stopwords out of the slug, if the slug hasn't been set yet.
453
  *
454
  * @deprecated 7.0
455
+ * @codeCoverageIgnore
456
  *
457
  * @return void
458
  */
464
  * Filter the stopwords from the slug.
465
  *
466
  * @deprecated 7.0
467
+ * @codeCoverageIgnore
468
  *
469
  * @return void
470
  */
476
  * Adds contextual help to the titles & metas page.
477
  *
478
  * @deprecated 5.6.0
479
+ * @codeCoverageIgnore
480
  */
481
  public function title_metas_help_tab() {
482
  _deprecated_function( __METHOD__, '5.6.0' );
483
 
484
  $screen = get_current_screen();
485
 
486
+ $screen->set_help_sidebar(
487
+ '
488
  <p><strong>' . __( 'For more information:', 'wordpress-seo' ) . '</strong></p>
489
  <p><a target="_blank" href="https://yoast.com/wordpress-seo/#titles">' . __( 'Title optimization', 'wordpress-seo' ) . '</a></p>
490
  <p><a target="_blank" href="https://yoast.com/google-page-title/">' . __( 'Why Google won\'t display the right page title', 'wordpress-seo' ) . '</a></p>'
521
  );
522
  }
523
 
524
+ /**
525
+ * Initializes Whip to show a notice for outdated PHP versions.
526
+ *
527
+ * @deprecated 8.1
528
+ * @codeCoverageIgnore
529
+ *
530
+ * @return void
531
+ */
532
+ public function check_php_version() {
533
+ // Intentionally left empty.
534
+ }
535
  }
admin/class-asset.php CHANGED
@@ -65,6 +65,20 @@ class WPSEO_Admin_Asset {
65
  */
66
  protected $suffix;
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  /**
69
  * @param array $args The arguments for this asset.
70
  *
@@ -79,14 +93,7 @@ class WPSEO_Admin_Asset {
79
  throw new InvalidArgumentException( 'src is a required argument' );
80
  }
81
 
82
- $args = array_merge( array(
83
- 'deps' => array(),
84
- 'version' => WPSEO_VERSION,
85
- 'in_footer' => true,
86
- 'rtl' => true,
87
- 'media' => 'all',
88
- 'suffix' => WPSEO_CSSJS_SUFFIX,
89
- ), $args );
90
 
91
  $this->name = $args['name'];
92
  $this->src = $args['src'];
65
  */
66
  protected $suffix;
67
 
68
+ /**
69
+ * Default asset arguments.
70
+ *
71
+ * @var array
72
+ */
73
+ private $defaults = array(
74
+ 'deps' => array(),
75
+ 'version' => WPSEO_VERSION,
76
+ 'in_footer' => true,
77
+ 'rtl' => true,
78
+ 'media' => 'all',
79
+ 'suffix' => WPSEO_CSSJS_SUFFIX,
80
+ );
81
+
82
  /**
83
  * @param array $args The arguments for this asset.
84
  *
93
  throw new InvalidArgumentException( 'src is a required argument' );
94
  }
95
 
96
+ $args = array_merge( $this->defaults, $args );
 
 
 
 
 
 
 
97
 
98
  $this->name = $args['name'];
99
  $this->src = $args['src'];
admin/class-cornerstone.php DELETED
@@ -1,94 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin
6
- */
7
-
8
- /**
9
- * Represents the yoast cornerstone content.
10
- */
11
- class WPSEO_Cornerstone {
12
-
13
- const META_NAME = 'is_cornerstone';
14
-
15
- const FIELD_NAME = 'yoast_wpseo_is_cornerstone';
16
-
17
- /**
18
- * Registers the hooks.
19
- *
20
- * @return void
21
- */
22
- public function register_hooks() {
23
- global $pagenow;
24
-
25
- if ( ! $this->page_contains_cornerstone_content_field( $pagenow ) ) {
26
- return;
27
- }
28
-
29
- add_action( 'save_post', array( $this, 'save_meta_value' ) );
30
- add_filter( 'wpseo_cornerstone_post_types', array( 'WPSEO_Post_Type', 'filter_attachment_post_type' ) );
31
- }
32
-
33
- /**
34
- * Saves the meta value to the database.
35
- *
36
- * @param int $post_id The post id to save the meta value for.
37
- *
38
- * @return void
39
- */
40
- public function save_meta_value( $post_id ) {
41
- $is_cornerstone_content = $this->is_cornerstone_content();
42
-
43
- if ( $is_cornerstone_content ) {
44
- $this->update_meta( $post_id, $is_cornerstone_content );
45
-
46
- return;
47
- }
48
-
49
- $this->delete_meta( $post_id );
50
- }
51
-
52
- /**
53
- * Returns the result of the cornerstone content checkbox.
54
- *
55
- * @return bool True when checkbox is checked.
56
- */
57
- protected function is_cornerstone_content() {
58
- return filter_input( INPUT_POST, self::FIELD_NAME ) === 'true';
59
- }
60
-
61
- /**
62
- * Checks if the current page matches one of the pages that contains the cornerstone content field.
63
- *
64
- * @param string $page The page to check.
65
- *
66
- * @return bool True when the page contains the cornerstone content field.
67
- */
68
- protected function page_contains_cornerstone_content_field( $page ) {
69
- return WPSEO_Metabox::is_post_edit( $page );
70
- }
71
-
72
- /**
73
- * Updates the cornerstone content post meta with the given cornerstone content value.
74
- *
75
- * @param int $post_id The post id to save the meta value for.
76
- * @param bool $is_cornerstone_content Whether or not the post should be considered to be cornerstone content.
77
- *
78
- * @return void
79
- */
80
- protected function update_meta( $post_id, $is_cornerstone_content ) {
81
- WPSEO_Meta::set_value( self::META_NAME, $is_cornerstone_content, $post_id );
82
- }
83
-
84
- /**
85
- * Deletes the cornerstone content post meta for the given post id.
86
- *
87
- * @param int $post_id The post id to delete the cornerstone content meta value for..
88
- *
89
- * @return void
90
- */
91
- protected function delete_meta( $post_id ) {
92
- WPSEO_Meta::delete( self::META_NAME, $post_id );
93
- }
94
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/class-customizer.php CHANGED
@@ -48,14 +48,14 @@ class WPSEO_Customizer {
48
  * Add the breadcrumbs section to the customizer
49
  */
50
  private function breadcrumbs_section() {
51
- $this->wp_customize->add_section(
52
- 'wpseo_breadcrumbs_customizer_section', array(
53
- /* translators: %s is the name of the plugin */
54
- 'title' => sprintf( __( '%s Breadcrumbs', 'wordpress-seo' ), 'Yoast SEO' ),
55
- 'priority' => 999,
56
- 'active_callback' => array( $this, 'breadcrumbs_active_callback' ),
57
- )
58
  );
 
 
59
  }
60
 
61
  /**
48
  * Add the breadcrumbs section to the customizer
49
  */
50
  private function breadcrumbs_section() {
51
+ $section_args = array(
52
+ /* translators: %s is the name of the plugin */
53
+ 'title' => sprintf( __( '%s Breadcrumbs', 'wordpress-seo' ), 'Yoast SEO' ),
54
+ 'priority' => 999,
55
+ 'active_callback' => array( $this, 'breadcrumbs_active_callback' ),
 
 
56
  );
57
+
58
+ $this->wp_customize->add_section( 'wpseo_breadcrumbs_customizer_section', $section_args );
59
  }
60
 
61
  /**
admin/class-database-proxy.php CHANGED
@@ -179,8 +179,8 @@ class WPSEO_Database_Proxy {
179
  * @return bool True when creation is successful.
180
  */
181
  public function create_table( array $columns, array $indexes = array() ) {
182
- $create_table = sprintf( '
183
- CREATE TABLE IF NOT EXISTS %1$s ( %2$s ) %3$s',
184
  $this->get_table_name(),
185
  implode( ',', array_merge( $columns, $indexes ) ),
186
  $this->database->get_charset_collate()
179
  * @return bool True when creation is successful.
180
  */
181
  public function create_table( array $columns, array $indexes = array() ) {
182
+ $create_table = sprintf(
183
+ 'CREATE TABLE IF NOT EXISTS %1$s ( %2$s ) %3$s',
184
  $this->get_table_name(),
185
  implode( ',', array_merge( $columns, $indexes ) ),
186
  $this->database->get_charset_collate()
admin/class-expose-shortlinks.php CHANGED
@@ -14,23 +14,24 @@ class WPSEO_Expose_Shortlinks implements WPSEO_WordPress_Integration {
14
  * @var array Array containing the keys and shortlinks.
15
  */
16
  private $shortlinks = array(
17
- 'shortlinks.focus_keyword_info' => 'https://yoa.st/focus-keyword',
18
- 'shortlinks.snippet_preview_info' => 'https://yoa.st/snippet-preview',
19
- 'shortlinks.cornerstone_content_info' => 'https://yoa.st/1i9',
20
- 'shortlinks.upsell.sidebar.focus_keyword_synonyms_link' => 'https://yoa.st/textlink-synonyms-popup-sidebar',
21
- 'shortlinks.upsell.sidebar.focus_keyword_synonyms_button' => 'https://yoa.st/keyword-synonyms-popup-sidebar',
22
- 'shortlinks.upsell.sidebar.focus_keyword_additional_link' => 'https://yoa.st/textlink-keywords-popup-sidebar',
23
  'shortlinks.upsell.sidebar.focus_keyword_additional_button' => 'https://yoa.st/add-keywords-popup-sidebar',
24
- 'shortlinks.upsell.sidebar.additional_link' => 'https://yoa.st/textlink-keywords-sidebar',
25
- 'shortlinks.upsell.sidebar.additional_button' => 'https://yoa.st/add-keywords-sidebar',
26
- 'shortlinks.upsell.metabox.go_premium' => 'https://yoa.st/pe-premium-page',
27
- 'shortlinks.upsell.metabox.focus_keyword_synonyms_link' => 'https://yoa.st/textlink-synonyms-popup-metabox',
28
- 'shortlinks.upsell.metabox.focus_keyword_synonyms_button' => 'https://yoa.st/keyword-synonyms-popup',
29
- 'shortlinks.upsell.metabox.focus_keyword_additional_link' => 'https://yoa.st/textlink-keywords-popup-metabox',
30
  'shortlinks.upsell.metabox.focus_keyword_additional_button' => 'https://yoa.st/add-keywords-popup',
31
- 'shortlinks.upsell.metabox.additional_link' => 'https://yoa.st/textlink-keywords-metabox',
32
- 'shortlinks.upsell.metabox.additional_button' => 'https://yoa.st/add-keywords-metabox',
33
  'shortlinks.readability_analysis_info' => 'https://yoa.st/readability-analysis',
 
34
  );
35
 
36
  /**
@@ -54,6 +55,8 @@ class WPSEO_Expose_Shortlinks implements WPSEO_WordPress_Integration {
54
  $input[ $key ] = WPSEO_Shortlinker::get( $shortlink );
55
  }
56
 
 
 
57
  return $input;
58
  }
59
  }
14
  * @var array Array containing the keys and shortlinks.
15
  */
16
  private $shortlinks = array(
17
+ 'shortlinks.focus_keyword_info' => 'https://yoa.st/focus-keyword',
18
+ 'shortlinks.snippet_preview_info' => 'https://yoa.st/snippet-preview',
19
+ 'shortlinks.cornerstone_content_info' => 'https://yoa.st/1i9',
20
+ 'shortlinks.upsell.sidebar.focus_keyword_synonyms_link' => 'https://yoa.st/textlink-synonyms-popup-sidebar',
21
+ 'shortlinks.upsell.sidebar.focus_keyword_synonyms_button' => 'https://yoa.st/keyword-synonyms-popup-sidebar',
22
+ 'shortlinks.upsell.sidebar.focus_keyword_additional_link' => 'https://yoa.st/textlink-keywords-popup-sidebar',
23
  'shortlinks.upsell.sidebar.focus_keyword_additional_button' => 'https://yoa.st/add-keywords-popup-sidebar',
24
+ 'shortlinks.upsell.sidebar.additional_link' => 'https://yoa.st/textlink-keywords-sidebar',
25
+ 'shortlinks.upsell.sidebar.additional_button' => 'https://yoa.st/add-keywords-sidebar',
26
+ 'shortlinks.upsell.metabox.go_premium' => 'https://yoa.st/pe-premium-page',
27
+ 'shortlinks.upsell.metabox.focus_keyword_synonyms_link' => 'https://yoa.st/textlink-synonyms-popup-metabox',
28
+ 'shortlinks.upsell.metabox.focus_keyword_synonyms_button' => 'https://yoa.st/keyword-synonyms-popup',
29
+ 'shortlinks.upsell.metabox.focus_keyword_additional_link' => 'https://yoa.st/textlink-keywords-popup-metabox',
30
  'shortlinks.upsell.metabox.focus_keyword_additional_button' => 'https://yoa.st/add-keywords-popup',
31
+ 'shortlinks.upsell.metabox.additional_link' => 'https://yoa.st/textlink-keywords-metabox',
32
+ 'shortlinks.upsell.metabox.additional_button' => 'https://yoa.st/add-keywords-metabox',
33
  'shortlinks.readability_analysis_info' => 'https://yoa.st/readability-analysis',
34
+ 'shortlinks.activate_premium_info' => 'https://yoa.st/activate-subscription',
35
  );
36
 
37
  /**
55
  $input[ $key ] = WPSEO_Shortlinker::get( $shortlink );
56
  }
57
 
58
+ $input['default_query_params'] = WPSEO_Shortlinker::get_query_params();
59
+
60
  return $input;
61
  }
62
  }
admin/class-gutenberg-compatibility.php CHANGED
@@ -13,12 +13,12 @@ class WPSEO_Gutenberg_Compatibility {
13
  /**
14
  * The currently released version of Gutenberg.
15
  */
16
- const CURRENT_RELEASE = '3.9.0';
17
 
18
  /**
19
  * The minimally supported version of Gutenberg by the plugin.
20
  */
21
- const MINIMUM_SUPPORTED = '3.9.0';
22
 
23
  /**
24
  * @var string
13
  /**
14
  * The currently released version of Gutenberg.
15
  */
16
+ const CURRENT_RELEASE = '4.0.0';
17
 
18
  /**
19
  * The minimally supported version of Gutenberg by the plugin.
20
  */
21
+ const MINIMUM_SUPPORTED = '4.0.0';
22
 
23
  /**
24
  * @var string
admin/class-help-center.php CHANGED
@@ -266,10 +266,13 @@ class WPSEO_Help_Center {
266
  );
267
  }
268
 
 
 
269
  /**
270
  * Outputs the help center.
271
  *
272
  * @deprecated 5.6
 
273
  */
274
  public function output_help_center() {
275
  _deprecated_function( 'WPSEO_Help_Center::output_help_center', 'WPSEO 5.6.0', 'WPSEO_Help_Center::mount()' );
266
  );
267
  }
268
 
269
+ /* ********************* DEPRECATED METHODS ********************* */
270
+
271
  /**
272
  * Outputs the help center.
273
  *
274
  * @deprecated 5.6
275
+ * @codeCoverageIgnore
276
  */
277
  public function output_help_center() {
278
  _deprecated_function( 'WPSEO_Help_Center::output_help_center', 'WPSEO 5.6.0', 'WPSEO_Help_Center::mount()' );
admin/class-keyword-synonyms-modal.php CHANGED
@@ -18,7 +18,7 @@ class WPSEO_Keyword_Synonyms_Modal {
18
  */
19
  public function get_translations() {
20
  return array(
21
- 'title' => __( 'Would you like to add keyword synonyms?', 'wordpress-seo' ),
22
  'intro' => sprintf(
23
  /* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
24
  __( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
@@ -33,7 +33,7 @@ class WPSEO_Keyword_Synonyms_Modal {
33
  'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/keyword-synonyms-popup' ),
34
  'buy' => sprintf(
35
  /* translators: %s expands to 'Yoast SEO Premium'. */
36
- __( 'Get %s now!', 'wordpress-seo' ),
37
  'Yoast SEO Premium'
38
  ),
39
  'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
18
  */
19
  public function get_translations() {
20
  return array(
21
+ 'title' => __( 'Would you like to add keyphrase synonyms?', 'wordpress-seo' ),
22
  'intro' => sprintf(
23
  /* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
24
  __( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
33
  'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/keyword-synonyms-popup' ),
34
  'buy' => sprintf(
35
  /* translators: %s expands to 'Yoast SEO Premium'. */
36
+ __( 'Get %s', 'wordpress-seo' ),
37
  'Yoast SEO Premium'
38
  ),
39
  'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
admin/class-meta-columns.php CHANGED
@@ -129,7 +129,7 @@ class WPSEO_Meta_Columns {
129
 
130
  if ( '' === $focuskw_val ) {
131
  echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">',
132
- esc_html__( 'Focus keyword not set.', 'wordpress-seo' ),
133
  '</span>';
134
  return;
135
  }
@@ -613,7 +613,7 @@ class WPSEO_Meta_Columns {
613
 
614
  if ( WPSEO_Meta::get_value( 'focuskw', $post_id ) === '' ) {
615
  $rank = new WPSEO_Rank( WPSEO_Rank::NO_FOCUS );
616
- $title = __( 'Focus keyword not set.', 'wordpress-seo' );
617
 
618
  return $this->render_score_indicator( $rank, $title );
619
  }
129
 
130
  if ( '' === $focuskw_val ) {
131
  echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">',
132
+ esc_html__( 'Focus keyphrase not set.', 'wordpress-seo' ),
133
  '</span>';
134
  return;
135
  }
613
 
614
  if ( WPSEO_Meta::get_value( 'focuskw', $post_id ) === '' ) {
615
  $rank = new WPSEO_Rank( WPSEO_Rank::NO_FOCUS );
616
+ $title = __( 'Focus keyphrase not set.', 'wordpress-seo' );
617
 
618
  return $this->render_score_indicator( $rank, $title );
619
  }
admin/class-meta-storage.php CHANGED
@@ -86,7 +86,8 @@ class WPSEO_Meta_Storage implements WPSEO_Installable {
86
  public function update_incoming_link_count( array $post_ids, WPSEO_Link_Storage $storage ) {
87
  global $wpdb;
88
 
89
- $query = $wpdb->prepare( '
 
90
  SELECT COUNT( id ) AS incoming, target_post_id AS post_id
91
  FROM ' . $storage->get_table_name() . '
92
  WHERE target_post_id IN(' . implode( ',', array_fill( 0, count( $post_ids ), '%d' ) ) . ')
86
  public function update_incoming_link_count( array $post_ids, WPSEO_Link_Storage $storage ) {
87
  global $wpdb;
88
 
89
+ $query = $wpdb->prepare(
90
+ '
91
  SELECT COUNT( id ) AS incoming, target_post_id AS post_id
92
  FROM ' . $storage->get_table_name() . '
93
  WHERE target_post_id IN(' . implode( ',', array_fill( 0, count( $post_ids ), '%d' ) ) . ')
admin/class-meta-table-accessible.php CHANGED
@@ -90,10 +90,13 @@ class WPSEO_Meta_Table_Accessible {
90
  return 'wpseo_meta_table_inaccessible';
91
  }
92
 
 
 
93
  /**
94
  * Checks if the table exists if not, set the transient to indicate the inaccessible table.
95
  *
96
  * @deprecated 6.0
 
97
  *
98
  * @return bool True if table is accessible.
99
  */
90
  return 'wpseo_meta_table_inaccessible';
91
  }
92
 
93
+ /* ********************* DEPRECATED METHODS ********************* */
94
+
95
  /**
96
  * Checks if the table exists if not, set the transient to indicate the inaccessible table.
97
  *
98
  * @deprecated 6.0
99
+ * @codeCoverageIgnore
100
  *
101
  * @return bool True if table is accessible.
102
  */
admin/class-multiple-keywords-modal.php CHANGED
@@ -18,7 +18,7 @@ class WPSEO_Multiple_Keywords_Modal {
18
  */
19
  public function get_translations() {
20
  return array(
21
- 'title' => __( 'Would you like to add another keyword?', 'wordpress-seo' ),
22
  'intro' => sprintf(
23
  /* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
24
  __( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
@@ -33,7 +33,7 @@ class WPSEO_Multiple_Keywords_Modal {
33
  'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/add-keywords-popup' ),
34
  'buy' => sprintf(
35
  /* translators: %s expands to 'Yoast SEO Premium'. */
36
- __( 'Get %s now!', 'wordpress-seo' ),
37
  'Yoast SEO Premium'
38
  ),
39
  'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
18
  */
19
  public function get_translations() {
20
  return array(
21
+ 'title' => __( 'Would you like to add another keyphrase?', 'wordpress-seo' ),
22
  'intro' => sprintf(
23
  /* translators: %1$s expands to a 'Yoast SEO Premium' text linked to the yoast.com website. */
24
  __( 'Great news: you can, with %1$s!', 'wordpress-seo' ),
33
  'buylink' => WPSEO_Shortlinker::get( 'https://yoa.st/add-keywords-popup' ),
34
  'buy' => sprintf(
35
  /* translators: %s expands to 'Yoast SEO Premium'. */
36
+ __( 'Get %s', 'wordpress-seo' ),
37
  'Yoast SEO Premium'
38
  ),
39
  'small' => __( '1 year free updates and upgrades included!', 'wordpress-seo' ),
admin/class-paper-presenter.php CHANGED
@@ -55,7 +55,7 @@ class WPSEO_Paper_Presenter {
55
  extract( $this->get_view_variables(), EXTR_SKIP );
56
 
57
  ob_start();
58
- require WPSEO_PATH . 'admin/views/paper-collapsible.php' ;
59
  $rendered_output = ob_get_clean();
60
 
61
  return $rendered_output;
55
  extract( $this->get_view_variables(), EXTR_SKIP );
56
 
57
  ob_start();
58
+ require WPSEO_PATH . 'admin/views/paper-collapsible.php';
59
  $rendered_output = ob_get_clean();
60
 
61
  return $rendered_output;
admin/class-plugin-availability.php CHANGED
@@ -115,7 +115,8 @@ class WPSEO_Plugin_Availability {
115
  'title' => 'Yoast SEO AMP Glue',
116
  'description' => sprintf(
117
  /* translators: %1$s expands to Yoast SEO */
118
- __( 'Seamlessly integrate %1$s into your AMP pages!', 'wordpress-seo' ), 'Yoast SEO'
 
119
  ),
120
  'installed' => false,
121
  'slug' => 'glue-for-yoast-seo-amp/yoastseo-amp.php',
115
  'title' => 'Yoast SEO AMP Glue',
116
  'description' => sprintf(
117
  /* translators: %1$s expands to Yoast SEO */
118
+ __( 'Seamlessly integrate %1$s into your AMP pages!', 'wordpress-seo' ),
119
+ 'Yoast SEO'
120
  ),
121
  'installed' => false,
122
  'slug' => 'glue-for-yoast-seo-amp/yoastseo-amp.php',
admin/class-premium-popup.php CHANGED
@@ -77,7 +77,7 @@ class WPSEO_Premium_Popup {
77
  $assets_uri = trailingslashit( plugin_dir_url( WPSEO_FILE ) );
78
 
79
  /* translators: %s expands to Yoast SEO Premium */
80
- $cta_text = sprintf( __( 'Get %s now!', 'wordpress-seo' ), 'Yoast SEO Premium' );
81
  $classes = '';
82
  if ( $popup ) {
83
  $classes = ' hidden';
@@ -89,7 +89,7 @@ class WPSEO_Premium_Popup {
89
  <img class="alignright wpseo-premium-popup-icon" src="{$assets_uri}images/Yoast_SEO_Icon.svg" width="150" height="150" alt="Yoast SEO"/>
90
  <{$this->heading_level} id="wpseo-contact-support-popup-title" class="wpseo-premium-popup-title">{$this->title}</{$this->heading_level}>
91
  {$this->content}
92
- <a id="wpseo-{$this->identifier}-popup-button" class="button button-primary" href="{$this->url}" target="_blank" rel="noreferrer noopener">{$cta_text}</a><br/>
93
  <small>{$micro_copy}</small>
94
  </div>
95
  EO_POPUP;
77
  $assets_uri = trailingslashit( plugin_dir_url( WPSEO_FILE ) );
78
 
79
  /* translators: %s expands to Yoast SEO Premium */
80
+ $cta_text = sprintf( __( 'Get %s', 'wordpress-seo' ), 'Yoast SEO Premium' );
81
  $classes = '';
82
  if ( $popup ) {
83
  $classes = ' hidden';
89
  <img class="alignright wpseo-premium-popup-icon" src="{$assets_uri}images/Yoast_SEO_Icon.svg" width="150" height="150" alt="Yoast SEO"/>
90
  <{$this->heading_level} id="wpseo-contact-support-popup-title" class="wpseo-premium-popup-title">{$this->title}</{$this->heading_level}>
91
  {$this->content}
92
+ <a id="wpseo-{$this->identifier}-popup-button" class="yoast-button-upsell" href="{$this->url}" target="_blank" rel="noreferrer noopener">{$cta_text}</a><br/>
93
  <small>{$micro_copy}</small>
94
  </div>
95
  EO_POPUP;
admin/class-premium-upsell-admin-block.php CHANGED
@@ -44,7 +44,7 @@ class WPSEO_Premium_Upsell_Admin_Block {
44
  $url = WPSEO_Shortlinker::get( 'https://yoa.st/17h' );
45
 
46
  $arguments = array(
47
- '<strong>' . esc_html__( 'Multiple keywords', 'wordpress-seo' ) . '</strong>: ' . esc_html__( 'Increase your SEO reach', 'wordpress-seo' ),
48
  '<strong>' . esc_html__( 'No more dead links', 'wordpress-seo' ) . '</strong>: ' . esc_html__( 'Easy redirect manager', 'wordpress-seo' ),
49
  '<strong>' . esc_html__( 'Superfast internal linking suggestions', 'wordpress-seo' ) . '</strong>',
50
  '<strong>' . esc_html__( 'Social media preview', 'wordpress-seo' ) . '</strong>: ' . esc_html__( 'Facebook & Twitter', 'wordpress-seo' ),
44
  $url = WPSEO_Shortlinker::get( 'https://yoa.st/17h' );
45
 
46
  $arguments = array(
47
+ '<strong>' . esc_html__( 'Multiple keyphrases', 'wordpress-seo' ) . '</strong>: ' . esc_html__( 'Increase your SEO reach', 'wordpress-seo' ),
48
  '<strong>' . esc_html__( 'No more dead links', 'wordpress-seo' ) . '</strong>: ' . esc_html__( 'Easy redirect manager', 'wordpress-seo' ),
49
  '<strong>' . esc_html__( 'Superfast internal linking suggestions', 'wordpress-seo' ) . '</strong>',
50
  '<strong>' . esc_html__( 'Social media preview', 'wordpress-seo' ) . '</strong>: ' . esc_html__( 'Facebook & Twitter', 'wordpress-seo' ),
admin/class-primary-term-admin.php CHANGED
@@ -9,6 +9,7 @@
9
  * Adds the UI to change the primary term for a post.
10
  */
11
  class WPSEO_Primary_Term_Admin {
 
12
  /**
13
  * Constructor.
14
  */
9
  * Adds the UI to change the primary term for a post.
10
  */
11
  class WPSEO_Primary_Term_Admin {
12
+
13
  /**
14
  * Constructor.
15
  */
admin/class-product-upsell-notice.php CHANGED
@@ -117,7 +117,7 @@ class WPSEO_Product_Upsell_Notice {
117
  if ( $features->is_free() ) {
118
  return sprintf(
119
  /* translators: %1$s expands anchor to premium plugin page, %2$s expands to </a> */
120
- __( 'By the way, did you know we also have a %1$sPremium plugin%2$s? It offers advanced features, like a redirect manager and support for multiple keywords. It also comes with 24/7 personal support.', 'wordpress-seo' ),
121
  "<a href='" . WPSEO_Shortlinker::get( 'https://yoa.st/premium-notification' ) . "'>",
122
  '</a>'
123
  );
117
  if ( $features->is_free() ) {
118
  return sprintf(
119
  /* translators: %1$s expands anchor to premium plugin page, %2$s expands to </a> */
120
+ __( 'By the way, did you know we also have a %1$sPremium plugin%2$s? It offers advanced features, like a redirect manager and support for multiple keyphrases. It also comes with 24/7 personal support.', 'wordpress-seo' ),
121
  "<a href='" . WPSEO_Shortlinker::get( 'https://yoa.st/premium-notification' ) . "'>",
122
  '</a>'
123
  );
admin/class-recalculate-scores.php CHANGED
@@ -44,7 +44,7 @@ class WPSEO_Recalculate_Scores {
44
 
45
  ?>
46
  <div id="wpseo_recalculate" class="hidden">
47
- <p><?php esc_html_e( 'Recalculating SEO scores for all pieces of content with a focus keyword.', 'wordpress-seo' ); ?></p>
48
 
49
  <div id="wpseo_progressbar"></div>
50
  <p><?php echo $progress; ?></p>
44
 
45
  ?>
46
  <div id="wpseo_recalculate" class="hidden">
47
+ <p><?php esc_html_e( 'Recalculating SEO scores for all pieces of content with a focus keyphrase.', 'wordpress-seo' ); ?></p>
48
 
49
  <div id="wpseo_progressbar"></div>
50
  <p><?php echo $progress; ?></p>
admin/class-social-admin.php CHANGED
@@ -33,7 +33,7 @@ class WPSEO_Social_Admin extends WPSEO_Metabox {
33
  $description_text = __( 'If you don\'t want to use the meta description for sharing the post on %s but want another description there, write it here.', 'wordpress-seo' );
34
 
35
  /* translators: %s expands to the social network's name. */
36
- $image_text = __( 'If you want to override the image used on %s for this post, upload / choose an image or add the URL here.', 'wordpress-seo' );
37
 
38
  /* translators: %1$s expands to the social network, %2$s to the recommended image size. */
39
  $image_size_text = __( 'The recommended image size for %1$s is %2$s pixels.', 'wordpress-seo' );
@@ -136,6 +136,7 @@ class WPSEO_Social_Admin extends WPSEO_Metabox {
136
  $medium . '-title',
137
  $medium . '-description',
138
  $medium . '-image',
 
139
  );
140
 
141
  $tab_content = $this->get_premium_notice( $medium );
33
  $description_text = __( 'If you don\'t want to use the meta description for sharing the post on %s but want another description there, write it here.', 'wordpress-seo' );
34
 
35
  /* translators: %s expands to the social network's name. */
36
+ $image_text = __( 'If you want to override the image used on %s for this post, upload / choose an image here.', 'wordpress-seo' );
37
 
38
  /* translators: %1$s expands to the social network, %2$s to the recommended image size. */
39
  $image_size_text = __( 'The recommended image size for %1$s is %2$s pixels.', 'wordpress-seo' );
136
  $medium . '-title',
137
  $medium . '-description',
138
  $medium . '-image',
139
+ $medium . '-image-id',
140
  );
141
 
142
  $tab_content = $this->get_premium_notice( $medium );
admin/class-yoast-form.php CHANGED
@@ -28,7 +28,15 @@ class Yoast_Form {
28
  * @var array
29
  * @since 2.0
30
  */
31
- public $options;
 
 
 
 
 
 
 
 
32
 
33
  /**
34
  * Get the singleton instance of this class
@@ -102,7 +110,16 @@ class Yoast_Form {
102
  */
103
  public function set_option( $option_name ) {
104
  $this->option_name = $option_name;
105
- $this->options = $this->get_option();
 
 
 
 
 
 
 
 
 
106
  }
107
 
108
  /**
@@ -120,22 +137,6 @@ class Yoast_Form {
120
  }
121
  }
122
 
123
- /**
124
- * Retrieve options based on whether we're on multisite or not.
125
- *
126
- * @since 1.2.4
127
- * @since 2.0 Moved to this class.
128
- *
129
- * @return array
130
- */
131
- public function get_option() {
132
- if ( is_network_admin() ) {
133
- return get_site_option( $this->option_name );
134
- }
135
-
136
- return get_option( $this->option_name );
137
- }
138
-
139
  /**
140
  * Generates the footer for admin pages
141
  *
@@ -206,12 +207,13 @@ class Yoast_Form {
206
  * @param array $attr HTML attributes set.
207
  */
208
  public function label( $text, $attr ) {
209
- $attr = wp_parse_args( $attr, array(
210
- 'class' => 'checkbox',
211
- 'close' => true,
212
- 'for' => '',
213
- )
214
  );
 
 
215
  echo "<label class='" . esc_attr( $attr['class'] ) . "' for='" . esc_attr( $attr['for'] ) . "'>$text";
216
  if ( $attr['close'] ) {
217
  echo '</label>';
@@ -227,11 +229,11 @@ class Yoast_Form {
227
  * @param array $attr HTML attributes set.
228
  */
229
  public function legend( $text, $attr ) {
230
- $attr = wp_parse_args( $attr, array(
231
- 'id' => '',
232
- 'class' => '',
233
- )
234
  );
 
235
 
236
  $id = ( '' === $attr['id'] ) ? '' : ' id="' . esc_attr( $attr['id'] ) . '"';
237
  echo '<legend class="yoast-form-legend ' . esc_attr( $attr['class'] ) . '"' . $id . '>' . $text . '</legend>';
@@ -266,7 +268,7 @@ class Yoast_Form {
266
  $class = 'double';
267
  }
268
 
269
- echo '<input class="checkbox ', esc_attr( $class ), '" type="checkbox" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="on"', checked( $this->options[ $var ], 'on', false ), '/>';
270
 
271
  if ( ! empty( $label ) ) {
272
  $this->label( $label, array( 'for' => $var ) );
@@ -317,7 +319,7 @@ class Yoast_Form {
317
  echo "<div class='switch-container$help_class'>",
318
  "<span class='switch-light-visual-label'>{$label}</span>" . $help,
319
  '<label class="', $class, '"><b class="switch-yoast-seo-jaws-a11y">&nbsp;</b>',
320
- '<input type="checkbox" aria-labelledby="', $aria_labelledby, '" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="on"', checked( $this->options[ $var ], 'on', false ), '/>',
321
  "<b class='label-text screen-reader-text' id='{$aria_labelledby}'>{$label}</b>",
322
  '<span aria-hidden="true">
323
  <span>', esc_html( $off_button ) ,'</span>
@@ -343,11 +345,13 @@ class Yoast_Form {
343
  'class' => $attr,
344
  );
345
  }
346
- $attr = wp_parse_args( $attr, array(
 
347
  'placeholder' => '',
348
  'class' => '',
349
- ) );
350
- $val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
 
351
 
352
  $this->label(
353
  $label . ':',
@@ -356,7 +360,7 @@ class Yoast_Form {
356
  'class' => 'textinput',
357
  )
358
  );
359
- echo '<input class="textinput ' . esc_attr( $attr['class'] ) . ' " placeholder="' . esc_attr( $attr['placeholder'] ) . '" type="text" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="', esc_attr( $val ), '"/>', '<br class="clear" />';
360
  }
361
 
362
  /**
@@ -374,12 +378,14 @@ class Yoast_Form {
374
  'class' => $attr,
375
  );
376
  }
377
- $attr = wp_parse_args( $attr, array(
 
378
  'cols' => '',
379
  'rows' => '',
380
  'class' => '',
381
- ) );
382
- $val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
 
383
 
384
  $this->label(
385
  $label . ':',
@@ -388,7 +394,7 @@ class Yoast_Form {
388
  'class' => 'textinput',
389
  )
390
  );
391
- echo '<textarea cols="' . esc_attr( $attr['cols'] ) . '" rows="' . esc_attr( $attr['rows'] ) . '" class="textinput ' . esc_attr( $attr['class'] ) . '" id="' . esc_attr( $var ) . '" name="' . esc_attr( $this->option_name ) . '[' . esc_attr( $var ) . ']">' . esc_textarea( $val ) . '</textarea><br class="clear" />';
392
  }
393
 
394
  /**
@@ -417,11 +423,11 @@ class Yoast_Form {
417
  *
418
  * @since 2.0
419
  *
420
- * @param string $field_name The variable within the option to create the select for.
421
  * @param string $label The label to show for the variable.
422
  * @param array $select_options The select options to choose from.
423
  */
424
- public function select( $field_name, $label, array $select_options ) {
425
 
426
  if ( empty( $select_options ) ) {
427
  return;
@@ -430,16 +436,19 @@ class Yoast_Form {
430
  $this->label(
431
  $label . ':',
432
  array(
433
- 'for' => $field_name,
434
  'class' => 'select',
435
  )
436
  );
437
 
438
- $select_name = esc_attr( $this->option_name ) . '[' . esc_attr( $field_name ) . ']';
439
- $active_option = ( isset( $this->options[ $field_name ] ) ) ? $this->options[ $field_name ] : '';
440
 
441
- $select = new Yoast_Input_Select( $field_name, $select_name, $select_options, $active_option );
442
  $select->add_attribute( 'class', 'select' );
 
 
 
443
  $select->output_html();
444
 
445
  echo '<br class="clear"/>';
@@ -467,7 +476,7 @@ class Yoast_Form {
467
  'class' => 'select',
468
  )
469
  );
470
- echo '<input type="file" value="' . esc_attr( $val ) . '" class="textinput" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" id="' . $var_esc . '"/>';
471
 
472
  // Need to save separate array items in hidden inputs, because empty file inputs type will be deleted by settings API.
473
  if ( ! empty( $this->options[ $var ] ) ) {
@@ -492,6 +501,11 @@ class Yoast_Form {
492
  $val = $this->options[ $var ];
493
  }
494
 
 
 
 
 
 
495
  $var_esc = esc_attr( $var );
496
 
497
  $this->label(
@@ -501,8 +515,39 @@ class Yoast_Form {
501
  'class' => 'select',
502
  )
503
  );
504
- echo '<input class="textinput" id="wpseo_', $var_esc, '" type="text" size="36" name="', esc_attr( $this->option_name ), '[', $var_esc, ']" value="', esc_attr( $val ), '" />';
505
- echo '<input id="wpseo_', $var_esc, '_button" class="wpseo_image_upload_button button" type="button" value="', esc_attr__( 'Upload Image', 'wordpress-seo' ), '" />';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  echo '<br class="clear"/>';
507
  }
508
 
@@ -530,17 +575,18 @@ class Yoast_Form {
530
 
531
  if ( is_string( $legend ) && '' !== $legend ) {
532
 
533
- $legend_attr = wp_parse_args( $legend_attr, array(
534
  'id' => '',
535
  'class' => 'radiogroup',
536
- ) );
 
537
 
538
  $this->legend( $legend, $legend_attr );
539
  }
540
 
541
  foreach ( $values as $key => $value ) {
542
  $key_esc = esc_attr( $key );
543
- echo '<input type="radio" class="radio" id="' . $var_esc . '-' . $key_esc . '" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" value="' . $key_esc . '" ' . checked( $this->options[ $var ], $key_esc, false ) . ' />';
544
  $this->label(
545
  $value,
546
  array(
@@ -583,8 +629,9 @@ class Yoast_Form {
583
  $var_esc = esc_attr( $var );
584
 
585
  printf( '<div class="%s">', esc_attr( 'switch-container' . $help_class ) );
586
- echo '<fieldset id="', $var_esc, '" class="fieldset-switch-toggle"><legend>', $label, '</legend>', $help,
587
- '<div class="switch-toggle switch-candy switch-yoast-seo">';
 
588
 
589
  foreach ( $values as $key => $value ) {
590
  $screen_reader_text = '';
@@ -598,7 +645,7 @@ class Yoast_Form {
598
 
599
  $key_esc = esc_attr( $key );
600
  $for = $var_esc . '-' . $key_esc;
601
- echo '<input type="radio" id="' . $for . '" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" value="' . $key_esc . '" ' . checked( $this->options[ $var ], $key_esc, false ) . ' />',
602
  '<label for="', $for, '">', esc_html( $value ), $screen_reader_text_html,'</label>';
603
  }
604
 
@@ -653,4 +700,56 @@ class Yoast_Form {
653
 
654
  $this->toggle_switch( $var, $show_hide_switch, $label, $help );
655
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  }
28
  * @var array
29
  * @since 2.0
30
  */
31
+ public $options = array();
32
+
33
+ /**
34
+ * Option instance.
35
+ *
36
+ * @since 8.4
37
+ * @var WPSEO_Option|null
38
+ */
39
+ protected $option_instance = null;
40
 
41
  /**
42
  * Get the singleton instance of this class
110
  */
111
  public function set_option( $option_name ) {
112
  $this->option_name = $option_name;
113
+
114
+ $this->options = WPSEO_Options::get_option( $option_name );
115
+ if ( $this->options === null ) {
116
+ $this->options = (array) get_option( $option_name, array() );
117
+ }
118
+
119
+ $this->option_instance = WPSEO_Options::get_option_instance( $option_name );
120
+ if ( ! $this->option_instance ) {
121
+ $this->option_instance = null;
122
+ }
123
  }
124
 
125
  /**
137
  }
138
  }
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  /**
141
  * Generates the footer for admin pages
142
  *
207
  * @param array $attr HTML attributes set.
208
  */
209
  public function label( $text, $attr ) {
210
+ $defaults = array(
211
+ 'class' => 'checkbox',
212
+ 'close' => true,
213
+ 'for' => '',
 
214
  );
215
+ $attr = wp_parse_args( $attr, $defaults );
216
+
217
  echo "<label class='" . esc_attr( $attr['class'] ) . "' for='" . esc_attr( $attr['for'] ) . "'>$text";
218
  if ( $attr['close'] ) {
219
  echo '</label>';
229
  * @param array $attr HTML attributes set.
230
  */
231
  public function legend( $text, $attr ) {
232
+ $defaults = array(
233
+ 'id' => '',
234
+ 'class' => '',
 
235
  );
236
+ $attr = wp_parse_args( $attr, $defaults );
237
 
238
  $id = ( '' === $attr['id'] ) ? '' : ' id="' . esc_attr( $attr['id'] ) . '"';
239
  echo '<legend class="yoast-form-legend ' . esc_attr( $attr['class'] ) . '"' . $id . '>' . $text . '</legend>';
268
  $class = 'double';
269
  }
270
 
271
+ echo '<input class="checkbox ', esc_attr( $class ), '" type="checkbox" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="on"', checked( $this->options[ $var ], 'on', false ), disabled( $this->is_control_disabled( $var ), true, false ), '/>';
272
 
273
  if ( ! empty( $label ) ) {
274
  $this->label( $label, array( 'for' => $var ) );
319
  echo "<div class='switch-container$help_class'>",
320
  "<span class='switch-light-visual-label'>{$label}</span>" . $help,
321
  '<label class="', $class, '"><b class="switch-yoast-seo-jaws-a11y">&nbsp;</b>',
322
+ '<input type="checkbox" aria-labelledby="', $aria_labelledby, '" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="on"', checked( $this->options[ $var ], 'on', false ), disabled( $this->is_control_disabled( $var ), true, false ), '/>',
323
  "<b class='label-text screen-reader-text' id='{$aria_labelledby}'>{$label}</b>",
324
  '<span aria-hidden="true">
325
  <span>', esc_html( $off_button ) ,'</span>
345
  'class' => $attr,
346
  );
347
  }
348
+
349
+ $defaults = array(
350
  'placeholder' => '',
351
  'class' => '',
352
+ );
353
+ $attr = wp_parse_args( $attr, $defaults );
354
+ $val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
355
 
356
  $this->label(
357
  $label . ':',
360
  'class' => 'textinput',
361
  )
362
  );
363
+ echo '<input class="textinput ' . esc_attr( $attr['class'] ) . ' " placeholder="' . esc_attr( $attr['placeholder'] ) . '" type="text" id="', esc_attr( $var ), '" name="', esc_attr( $this->option_name ), '[', esc_attr( $var ), ']" value="', esc_attr( $val ), '"', disabled( $this->is_control_disabled( $var ), true, false ), '/>', '<br class="clear" />';
364
  }
365
 
366
  /**
378
  'class' => $attr,
379
  );
380
  }
381
+
382
+ $defaults = array(
383
  'cols' => '',
384
  'rows' => '',
385
  'class' => '',
386
+ );
387
+ $attr = wp_parse_args( $attr, $defaults );
388
+ $val = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
389
 
390
  $this->label(
391
  $label . ':',
394
  'class' => 'textinput',
395
  )
396
  );
397
+ echo '<textarea cols="' . esc_attr( $attr['cols'] ) . '" rows="' . esc_attr( $attr['rows'] ) . '" class="textinput ' . esc_attr( $attr['class'] ) . '" id="' . esc_attr( $var ) . '" name="' . esc_attr( $this->option_name ) . '[' . esc_attr( $var ) . ']"', disabled( $this->is_control_disabled( $var ), true, false ), '>' . esc_textarea( $val ) . '</textarea><br class="clear" />';
398
  }
399
 
400
  /**
423
  *
424
  * @since 2.0
425
  *
426
+ * @param string $var The variable within the option to create the select for.
427
  * @param string $label The label to show for the variable.
428
  * @param array $select_options The select options to choose from.
429
  */
430
+ public function select( $var, $label, array $select_options ) {
431
 
432
  if ( empty( $select_options ) ) {
433
  return;
436
  $this->label(
437
  $label . ':',
438
  array(
439
+ 'for' => $var,
440
  'class' => 'select',
441
  )
442
  );
443
 
444
+ $select_name = esc_attr( $this->option_name ) . '[' . esc_attr( $var ) . ']';
445
+ $active_option = ( isset( $this->options[ $var ] ) ) ? $this->options[ $var ] : '';
446
 
447
+ $select = new Yoast_Input_Select( $var, $select_name, $select_options, $active_option );
448
  $select->add_attribute( 'class', 'select' );
449
+ if ( $this->is_control_disabled( $var ) ) {
450
+ $select->add_attribute( 'disabled', 'disabled' );
451
+ }
452
  $select->output_html();
453
 
454
  echo '<br class="clear"/>';
476
  'class' => 'select',
477
  )
478
  );
479
+ echo '<input type="file" value="' . esc_attr( $val ) . '" class="textinput" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" id="' . $var_esc . '"', disabled( $this->is_control_disabled( $var ), true, false ), '/>';
480
 
481
  // Need to save separate array items in hidden inputs, because empty file inputs type will be deleted by settings API.
482
  if ( ! empty( $this->options[ $var ] ) ) {
501
  $val = $this->options[ $var ];
502
  }
503
 
504
+ $id_value = '';
505
+ if ( isset( $this->options[ $var . '_id' ] ) ) {
506
+ $id_value = $this->options[ $var . '_id' ];
507
+ }
508
+
509
  $var_esc = esc_attr( $var );
510
 
511
  $this->label(
515
  'class' => 'select',
516
  )
517
  );
518
+
519
+ $id_field_id = 'wpseo_' . $var_esc . '_id';
520
+
521
+ echo '<span>';
522
+ echo '<input',
523
+ ' class="textinput"',
524
+ ' id="wpseo_', $var_esc, '"',
525
+ ' type="text" size="36"',
526
+ ' name="', esc_attr( $this->option_name ), '[', $var_esc, ']"',
527
+ ' value="', esc_attr( $val ), '"',
528
+ ' readonly="readonly"',
529
+ ' /> ';
530
+ echo '<input',
531
+ ' id="wpseo_', $var_esc, '_button"',
532
+ ' class="wpseo_image_upload_button button"',
533
+ ' type="button"',
534
+ ' value="', esc_attr__( 'Upload Image', 'wordpress-seo' ), '"',
535
+ ' data-target-id="', esc_attr( $id_field_id ), '"',
536
+ disabled( $this->is_control_disabled( $var ), true, false ),
537
+ ' /> ';
538
+ echo '<input',
539
+ ' class="wpseo_image_remove_button button"',
540
+ ' type="button"',
541
+ ' value="', esc_attr__( 'Clear Image', 'wordpress-seo' ), '"',
542
+ disabled( $this->is_control_disabled( $var ), true, false ),
543
+ ' />';
544
+ echo '<input',
545
+ ' type="hidden"',
546
+ ' id="', esc_attr( $id_field_id ), '"',
547
+ ' name="', esc_attr( $this->option_name ), '[', $var_esc, '_id]"',
548
+ ' value="', esc_attr( $id_value ), '"',
549
+ ' />';
550
+ echo '</span>';
551
  echo '<br class="clear"/>';
552
  }
553
 
575
 
576
  if ( is_string( $legend ) && '' !== $legend ) {
577
 
578
+ $defaults = array(
579
  'id' => '',
580
  'class' => 'radiogroup',
581
+ );
582
+ $legend_attr = wp_parse_args( $legend_attr, $defaults );
583
 
584
  $this->legend( $legend, $legend_attr );
585
  }
586
 
587
  foreach ( $values as $key => $value ) {
588
  $key_esc = esc_attr( $key );
589
+ echo '<input type="radio" class="radio" id="' . $var_esc . '-' . $key_esc . '" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" value="' . $key_esc . '" ' . checked( $this->options[ $var ], $key_esc, false ) . disabled( $this->is_control_disabled( $var ), true, false ) . ' />';
590
  $this->label(
591
  $value,
592
  array(
629
  $var_esc = esc_attr( $var );
630
 
631
  printf( '<div class="%s">', esc_attr( 'switch-container' . $help_class ) );
632
+ echo '<fieldset id="', $var_esc, '" class="fieldset-switch-toggle"><legend>', $label, '</legend>', $help;
633
+ echo $this->get_disabled_note( $var );
634
+ echo '<div class="switch-toggle switch-candy switch-yoast-seo">';
635
 
636
  foreach ( $values as $key => $value ) {
637
  $screen_reader_text = '';
645
 
646
  $key_esc = esc_attr( $key );
647
  $for = $var_esc . '-' . $key_esc;
648
+ echo '<input type="radio" id="' . $for . '" name="' . esc_attr( $this->option_name ) . '[' . $var_esc . ']" value="' . $key_esc . '" ' . checked( $this->options[ $var ], $key_esc, false ) . disabled( $this->is_control_disabled( $var ), true, false ) . ' />',
649
  '<label for="', $for, '">', esc_html( $value ), $screen_reader_text_html,'</label>';
650
  }
651
 
700
 
701
  $this->toggle_switch( $var, $show_hide_switch, $label, $help );
702
  }
703
+
704
+ /**
705
+ * Checks whether a given control should be disabled.
706
+ *
707
+ * @param string $var The variable within the option to check whether its control should be disabled.
708
+ *
709
+ * @return bool True if control should be disabled, false otherwise.
710
+ */
711
+ protected function is_control_disabled( $var ) {
712
+ if ( $this->option_instance === null ) {
713
+ return false;
714
+ }
715
+
716
+ return $this->option_instance->is_disabled( $var );
717
+ }
718
+
719
+ /**
720
+ * Gets the explanation note to print if a given control is disabled.
721
+ *
722
+ * @param string $var The variable within the option to print a disabled note for.
723
+ *
724
+ * @return string Explanation note HTML string, or empty string if no note necessary.
725
+ */
726
+ protected function get_disabled_note( $var ) {
727
+ if ( ! $this->is_control_disabled( $var ) ) {
728
+ return '';
729
+ }
730
+
731
+ return '<p class="disabled-note">' . esc_html__( 'This feature has been disabled by the network admin.', 'wordpress-seo' ) . '</p>';
732
+ }
733
+
734
+ /* ********************* DEPRECATED METHODS ********************* */
735
+
736
+ /**
737
+ * Retrieve options based on whether we're on multisite or not.
738
+ *
739
+ * @since 1.2.4
740
+ * @since 2.0 Moved to this class.
741
+ * @deprecated 8.4
742
+ * @codeCoverageIgnore
743
+ *
744
+ * @return array The option's value.
745
+ */
746
+ public function get_option() {
747
+ _deprecated_function( __METHOD__, 'WPSEO 8.4' );
748
+
749
+ if ( is_network_admin() ) {
750
+ return get_site_option( $this->option_name );
751
+ }
752
+
753
+ return get_option( $this->option_name );
754
+ }
755
  }
admin/class-yoast-network-admin.php CHANGED
@@ -181,14 +181,17 @@ class Yoast_Network_Admin implements WPSEO_WordPress_Integration, WPSEO_WordPres
181
  $asset_manager = new WPSEO_Admin_Asset_Manager();
182
  $asset_manager->enqueue_script( 'network-admin-script' );
183
 
184
- wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'network-admin-script', 'wpseoNetworkAdminGlobalL10n', array(
185
-
186
  /* translators: %s: success message */
187
  'success_prefix' => __( 'Success: %s', 'wordpress-seo' ),
188
-
189
  /* translators: %s: error message */
190
  'error_prefix' => __( 'Error: %s', 'wordpress-seo' ),
191
- ) );
 
 
 
 
 
192
  }
193
 
194
  /**
181
  $asset_manager = new WPSEO_Admin_Asset_Manager();
182
  $asset_manager->enqueue_script( 'network-admin-script' );
183
 
184
+ $translations = array(
 
185
  /* translators: %s: success message */
186
  'success_prefix' => __( 'Success: %s', 'wordpress-seo' ),
 
187
  /* translators: %s: error message */
188
  'error_prefix' => __( 'Error: %s', 'wordpress-seo' ),
189
+ );
190
+ wp_localize_script(
191
+ WPSEO_Admin_Asset_Manager::PREFIX . 'network-admin-script',
192
+ 'wpseoNetworkAdminGlobalL10n',
193
+ $translations
194
+ );
195
  }
196
 
197
  /**
admin/class-yoast-network-settings-api.php CHANGED
@@ -41,10 +41,11 @@ class Yoast_Network_Settings_API {
41
  */
42
  public function register_setting( $option_group, $option_name, $args = array() ) {
43
 
44
- $args = wp_parse_args( $args, array(
45
  'group' => $option_group,
46
  'sanitize_callback' => null,
47
- ) );
 
48
 
49
  if ( ! isset( $this->whitelist_options[ $option_group ] ) ) {
50
  $this->whitelist_options[ $option_group ] = array();
41
  */
42
  public function register_setting( $option_group, $option_name, $args = array() ) {
43
 
44
+ $defaults = array(
45
  'group' => $option_group,
46
  'sanitize_callback' => null,
47
+ );
48
+ $args = wp_parse_args( $args, $defaults );
49
 
50
  if ( ! isset( $this->whitelist_options[ $option_group ] ) ) {
51
  $this->whitelist_options[ $option_group ] = array();
admin/config-ui/class-configuration-options-adapter.php CHANGED
@@ -57,22 +57,6 @@ class WPSEO_Configuration_Options_Adapter {
57
  $this->add_lookup( $class_name, self::OPTION_TYPE_YOAST, $key );
58
  }
59
 
60
- /**
61
- * Add a lookup for a Yoast option
62
- *
63
- * @param string $class_name Class to bind to the lookup.
64
- * @param string $option Option group to use.
65
- * @param string $key Key in the option group to bind to.
66
- *
67
- * @deprecated 7.0
68
- *
69
- * @throws InvalidArgumentException Thrown when invalid input is provided.
70
- */
71
- public function add_yoast_lookup( $class_name, $option, $key ) {
72
- _deprecated_function( __METHOD__, 'WPSEO 7.0', 'WPSEO_Configuration_Options_Adapter::add_option_lookup' );
73
- $this->add_option_lookup( $class_name, $key );
74
- }
75
-
76
  /**
77
  * Add a lookup for a custom implementation
78
  *
@@ -196,4 +180,23 @@ class WPSEO_Configuration_Options_Adapter {
196
 
197
  return $this->lookup[ $class_name ]['option'];
198
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  }
57
  $this->add_lookup( $class_name, self::OPTION_TYPE_YOAST, $key );
58
  }
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  /**
61
  * Add a lookup for a custom implementation
62
  *
180
 
181
  return $this->lookup[ $class_name ]['option'];
182
  }
183
+
184
+ /* ********************* DEPRECATED METHODS ********************* */
185
+
186
+ /**
187
+ * Add a lookup for a Yoast option
188
+ *
189
+ * @deprecated 7.0
190
+ * @codeCoverageIgnore
191
+ *
192
+ * @param string $class_name Class to bind to the lookup.
193
+ * @param string $option Option group to use.
194
+ * @param string $key Key in the option group to bind to.
195
+ *
196
+ * @throws InvalidArgumentException Thrown when invalid input is provided.
197
+ */
198
+ public function add_yoast_lookup( $class_name, $option, $key ) {
199
+ _deprecated_function( __METHOD__, 'WPSEO 7.0', 'WPSEO_Configuration_Options_Adapter::add_option_lookup' );
200
+ $this->add_option_lookup( $class_name, $key );
201
+ }
202
  }
admin/config-ui/class-configuration-page.php CHANGED
@@ -190,21 +190,6 @@ class WPSEO_Configuration_Page {
190
  return ( filter_input( INPUT_GET, 'page' ) === self::PAGE_IDENTIFIER );
191
  }
192
 
193
- /**
194
- * Returns the translations necessary for the configuration wizard.
195
- *
196
- * @deprecated 4.9
197
- *
198
- * @returns array The translations for the configuration wizard.
199
- */
200
- public function get_translations() {
201
- _deprecated_function( __METHOD__, 'WPSEO 4.9', 'WPSEO_' );
202
-
203
- $translations = new WPSEO_Configuration_Translations( WPSEO_Utils::get_user_locale() );
204
-
205
- return $translations->retrieve();
206
- }
207
-
208
  /**
209
  * Adds a notification to the notification center.
210
  */
@@ -265,4 +250,22 @@ class WPSEO_Configuration_Page {
265
  private function remove_notification_option() {
266
  WPSEO_Options::set( 'show_onboarding_notice', false );
267
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  }
190
  return ( filter_input( INPUT_GET, 'page' ) === self::PAGE_IDENTIFIER );
191
  }
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  /**
194
  * Adds a notification to the notification center.
195
  */
250
  private function remove_notification_option() {
251
  WPSEO_Options::set( 'show_onboarding_notice', false );
252
  }
253
+
254
+ /* ********************* DEPRECATED METHODS ********************* */
255
+
256
+ /**
257
+ * Returns the translations necessary for the configuration wizard.
258
+ *
259
+ * @deprecated 4.9
260
+ * @codeCoverageIgnore
261
+ *
262
+ * @returns array The translations for the configuration wizard.
263
+ */
264
+ public function get_translations() {
265
+ _deprecated_function( __METHOD__, 'WPSEO 4.9', 'WPSEO_' );
266
+
267
+ $translations = new WPSEO_Configuration_Translations( WPSEO_Utils::get_user_locale() );
268
+
269
+ return $translations->retrieve();
270
+ }
271
  }
admin/config-ui/components/class-component-suggestions.php CHANGED
@@ -33,13 +33,20 @@ class WPSEO_Config_Component_Suggestions implements WPSEO_Config_Component {
33
  /* translators: %s resolves to Yoast SEO Premium */
34
  sprintf( __( 'Outrank the competition with %s', 'wordpress-seo' ), 'Yoast SEO Premium' ),
35
  /* translators: %1$s resolves to Yoast SEO Premium */
36
- sprintf( __( 'Do you want to outrank your competition? %1$s gives you awesome additional features that\'ll help you to set up your SEO strategy like a professional. Use the multiple focus keywords functionality, the redirect manager and our internal linking tool. %1$s will also give you access to premium support.', 'wordpress-seo' ), 'Yoast SEO Premium' ),
37
  array(
38
  'label' => __( 'Upgrade to Premium', 'wordpress-seo' ),
39
  'type' => 'primary',
40
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/wizard-suggestion-premium' ),
41
  ),
42
- WPSEO_Shortlinker::get( 'https://yoa.st/video-yoast-seo-premium' )
 
 
 
 
 
 
 
43
  );
44
  }
45
 
@@ -60,7 +67,14 @@ class WPSEO_Config_Component_Suggestions implements WPSEO_Config_Component {
60
  'type' => 'link',
61
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/2up' ),
62
  ),
63
- WPSEO_Shortlinker::get( 'https://yoa.st/2v0' )
 
 
 
 
 
 
 
64
  );
65
 
66
  $field->add_suggestion(
@@ -73,13 +87,20 @@ class WPSEO_Config_Component_Suggestions implements WPSEO_Config_Component {
73
  'type' => 'link',
74
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/wizard-suggestion-plugin-course' ),
75
  ),
76
- WPSEO_Shortlinker::get( 'https://yoa.st/video-plugin-course' )
 
 
 
 
 
 
 
77
  );
78
 
79
  // When we are running in Yoast SEO Premium and don't have Local SEO installed, show Local SEO as suggestion.
80
  if ( WPSEO_Utils::is_yoast_seo_premium() && ! defined( 'WPSEO_LOCAL_FILE' ) ) {
81
  $field->add_suggestion(
82
- sprintf( __( 'Attract more customers near you', 'wordpress-seo' ), 'Yoast SEO', 'Yoast SEO plugin training' ),
83
  /* translators: %1$s resolves to Local SEO */
84
  sprintf( __( 'If you want to outrank the competition in a specific town or region, check out our %1$s plugin! You’ll be able to easily insert Google maps, opening hours, contact information and a store locator. Besides that %1$s helps you to improve the usability of your contact page.', 'wordpress-seo' ), 'Local SEO' ),
85
  array(
@@ -87,7 +108,14 @@ class WPSEO_Config_Component_Suggestions implements WPSEO_Config_Component {
87
  'type' => 'link',
88
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/wizard-suggestion-localseo' ),
89
  ),
90
- WPSEO_Shortlinker::get( 'https://yoa.st/video-localseo' )
 
 
 
 
 
 
 
91
  );
92
  }
93
 
33
  /* translators: %s resolves to Yoast SEO Premium */
34
  sprintf( __( 'Outrank the competition with %s', 'wordpress-seo' ), 'Yoast SEO Premium' ),
35
  /* translators: %1$s resolves to Yoast SEO Premium */
36
+ sprintf( __( 'Do you want to outrank your competition? %1$s gives you awesome additional features that\'ll help you to set up your SEO strategy like a professional. Add synonyms and related keywords, use our Premium SEO analysis, the redirect manager and our internal linking tool. %1$s will also give you access to premium support.', 'wordpress-seo' ), 'Yoast SEO Premium' ),
37
  array(
38
  'label' => __( 'Upgrade to Premium', 'wordpress-seo' ),
39
  'type' => 'primary',
40
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/wizard-suggestion-premium' ),
41
  ),
42
+ array(
43
+ 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/video-yoast-seo-premium' ),
44
+ 'title' => sprintf(
45
+ /* translators: %1$s expands to Yoast SEO Premium. */
46
+ __( '%1$s video', 'wordpress-seo' ),
47
+ 'Yoast SEO Premium'
48
+ ),
49
+ )
50
  );
51
  }
52
 
67
  'type' => 'link',
68
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/2up' ),
69
  ),
70
+ array(
71
+ 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/2v0' ),
72
+ 'title' => sprintf(
73
+ /* translators: %1$s expands to Basic SEO training. */
74
+ __( '%1$s video', 'wordpress-seo' ),
75
+ 'Basic SEO training'
76
+ ),
77
+ )
78
  );
79
 
80
  $field->add_suggestion(
87
  'type' => 'link',
88
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/wizard-suggestion-plugin-course' ),
89
  ),
90
+ array(
91
+ 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/video-plugin-course' ),
92
+ 'title' => sprintf(
93
+ /* translators: %1$s expands to Yoast SEO plugin training. */
94
+ __( '%1$s video', 'wordpress-seo' ),
95
+ 'Yoast SEO plugin training'
96
+ ),
97
+ )
98
  );
99
 
100
  // When we are running in Yoast SEO Premium and don't have Local SEO installed, show Local SEO as suggestion.
101
  if ( WPSEO_Utils::is_yoast_seo_premium() && ! defined( 'WPSEO_LOCAL_FILE' ) ) {
102
  $field->add_suggestion(
103
+ __( 'Attract more customers near you', 'wordpress-seo' ),
104
  /* translators: %1$s resolves to Local SEO */
105
  sprintf( __( 'If you want to outrank the competition in a specific town or region, check out our %1$s plugin! You’ll be able to easily insert Google maps, opening hours, contact information and a store locator. Besides that %1$s helps you to improve the usability of your contact page.', 'wordpress-seo' ), 'Local SEO' ),
106
  array(
108
  'type' => 'link',
109
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/wizard-suggestion-localseo' ),
110
  ),
111
+ array(
112
+ 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/video-localseo' ),
113
+ 'title' => sprintf(
114
+ /* translators: %1$s expands to Local SEO. */
115
+ __( '%1$s video', 'wordpress-seo' ),
116
+ 'Local SEO'
117
+ ),
118
+ )
119
  );
120
  }
121
 
admin/config-ui/fields/class-field-google-search-console-intro.php CHANGED
@@ -26,7 +26,7 @@ class WPSEO_Config_Field_Google_Search_Console_Intro extends WPSEO_Config_Field
26
  'wordpress-seo'
27
  ),
28
  'Yoast SEO',
29
- '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1ex' ) ) . '">',
30
  '</a>'
31
  );
32
 
26
  'wordpress-seo'
27
  ),
28
  'Yoast SEO',
29
+ '<a href="' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1ex' ) ) . '" target="_blank">',
30
  '</a>'
31
  );
32
 
admin/config-ui/fields/class-field-success-message.php CHANGED
@@ -18,7 +18,7 @@ class WPSEO_Config_Field_Success_Message extends WPSEO_Config_Field {
18
 
19
  $success_message = sprintf(
20
  /* translators: %1$s expands to Yoast SEO. */
21
- __( '%1$s will now take care of all the needed technical optimization of your site. To really improve your site\'s performance in the search results, it\'s important to start creating content that ranks well for keywords you care about. Check out this video in which we explain how to use the %1$s metabox when you edit posts or pages.', 'wordpress-seo' ),
22
  'Yoast SEO'
23
  );
24
 
@@ -27,7 +27,7 @@ class WPSEO_Config_Field_Success_Message extends WPSEO_Config_Field {
27
  $this->set_property( 'video', array(
28
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/metabox-screencast' ),
29
  'title' => sprintf(
30
- /* translators: %1$s expands to Yoast SEO. */
31
  __( '%1$s video tutorial', 'wordpress-seo' ),
32
  'Yoast SEO'
33
  ),
18
 
19
  $success_message = sprintf(
20
  /* translators: %1$s expands to Yoast SEO. */
21
+ __( '%1$s will now take care of all the needed technical optimization of your site. To really improve your site\'s performance in the search results, it\'s important to start creating content that ranks well for keyphrases you care about. Check out this video in which we explain how to use the %1$s metabox when you edit posts or pages.', 'wordpress-seo' ),
22
  'Yoast SEO'
23
  );
24
 
27
  $this->set_property( 'video', array(
28
  'url' => WPSEO_Shortlinker::get( 'https://yoa.st/metabox-screencast' ),
29
  'title' => sprintf(
30
+ /* translators: %1$s expands to Yoast SEO. */
31
  __( '%1$s video tutorial', 'wordpress-seo' ),
32
  'Yoast SEO'
33
  ),
admin/config-ui/fields/class-field-suggestions.php CHANGED
@@ -22,12 +22,12 @@ class WPSEO_Config_Field_Suggestions extends WPSEO_Config_Field {
22
  /**
23
  * Adds a suggestion to the properties
24
  *
25
- * @param string $title The title of the choice.
26
- * @param string $copy The text explaining the choice.
27
- * @param array $button The button details.
28
- * @param null|string $video The video accompanying the choice.
29
  */
30
- public function add_suggestion( $title, $copy, $button, $video = null ) {
31
  $suggestion = array(
32
  'title' => $title,
33
  'copy' => $copy,
@@ -41,4 +41,3 @@ class WPSEO_Config_Field_Suggestions extends WPSEO_Config_Field {
41
  $this->properties['suggestions'][] = $suggestion;
42
  }
43
  }
44
-
22
  /**
23
  * Adds a suggestion to the properties
24
  *
25
+ * @param string $title The title of the choice.
26
+ * @param string $copy The text explaining the choice.
27
+ * @param array $button The button details.
28
+ * @param array $video URL and title of the video accompanying the choice.
29
  */
30
+ public function add_suggestion( $title, $copy, $button, array $video = array() ) {
31
  $suggestion = array(
32
  'title' => $title,
33
  'copy' => $copy,
41
  $this->properties['suggestions'][] = $suggestion;
42
  }
43
  }
 
admin/endpoints/class-endpoint-indexable.php CHANGED
@@ -10,13 +10,15 @@
10
  */
11
  class WPSEO_Endpoint_Indexable implements WPSEO_Endpoint, WPSEO_Endpoint_Storable {
12
 
13
- const REST_NAMESPACE = 'yoast/v1';
14
- const ENDPOINT_SINGULAR = 'indexables/(?P<object_type>.*)/(?P<object_id>\d+)';
15
 
16
  const CAPABILITY_RETRIEVE = 'manage_options';
17
- const CAPABILITY_STORE = 'manage_options';
18
 
19
- /** @var WPSEO_Indexable_Service */
 
 
20
  private $service;
21
 
22
  /**
@@ -34,18 +36,26 @@ class WPSEO_Endpoint_Indexable implements WPSEO_Endpoint, WPSEO_Endpoint_Storabl
34
  * @return void
35
  */
36
  public function register() {
37
- // Register fetch config.
38
- register_rest_route( self::REST_NAMESPACE, self::ENDPOINT_SINGULAR, array(
39
- 'methods' => 'GET',
40
- 'callback' => array(
41
- $this->service,
42
- 'get_indexable',
43
- ),
44
- 'permission_callback' => array(
45
- $this,
46
- 'can_retrieve_data',
47
- ),
48
- ) );
 
 
 
 
 
 
 
 
49
  }
50
 
51
  /**
10
  */
11
  class WPSEO_Endpoint_Indexable implements WPSEO_Endpoint, WPSEO_Endpoint_Storable {
12
 
13
+ const REST_NAMESPACE = 'yoast/v1';
14
+ const ENDPOINT_SINGULAR = 'indexables/(?P<object_type>\w+)/(?P<object_id>\d+)';
15
 
16
  const CAPABILITY_RETRIEVE = 'manage_options';
17
+ const CAPABILITY_STORE = 'manage_options';
18
 
19
+ /**
20
+ * @var WPSEO_Indexable_Service The indexable service.
21
+ */
22
  private $service;
23
 
24
  /**
36
  * @return void
37
  */
38
  public function register() {
39
+ $endpoints = array();
40
+
41
+ $endpoints[] = new WPSEO_Endpoint_Factory(
42
+ self::REST_NAMESPACE,
43
+ self::ENDPOINT_SINGULAR,
44
+ array( $this->service, 'get_indexable' ),
45
+ array( $this, 'can_retrieve_data' )
46
+ );
47
+
48
+ $endpoints[] = new WPSEO_Endpoint_Factory(
49
+ self::REST_NAMESPACE,
50
+ self::ENDPOINT_SINGULAR,
51
+ array( $this->service, 'patch_indexable' ),
52
+ array( $this, 'can_store_data' ),
53
+ 'PATCH'
54
+ );
55
+
56
+ foreach ( $endpoints as $endpoint ) {
57
+ $endpoint->register();
58
+ }
59
  }
60
 
61
  /**
admin/filters/class-cornerstone-filter.php CHANGED
@@ -10,10 +10,26 @@
10
  */
11
  class WPSEO_Cornerstone_Filter extends WPSEO_Abstract_Post_Filter {
12