Yoast SEO - Version 17.8

Version Description

Release Date: December 14th, 2021

Yoast SEO 17.8 is out now and ready for you to download. In this release, we fix a number of bugs and added a few enhancements for you to enjoy! Read more about what's new in Yoast SEO 17.8 in our release post in English or our release post in Spanish!

Enhancements:

  • Improves the user direction in the configuration workout.
  • Adds a sleep interval to the WP CLI index command to limit server load while this command is running. Props to roborourke.

Bugfixes:

  • Fixes a bug where on small screens the advanced setting's search engine follow checkbox would have a misplaced center.
  • Fixes a bug where the styling of the introduction dialog in Elementor would be broken due to changes in Elementor.
  • Fixes a bug where the reading time functionality for languages other than English would incorrectly output English reading speed values.
  • Fixes a bug where certain text strings in the Google, Facebook and Twitter previews would not be translated.
  • Fixes a bug where the state of indexation was not persisted when switching between workouts and the workouts page.
  • Fixes a bug where the Workouts page wouldn't display translations.

Other:

  • Fixes some styling issues in the configuration workout.
  • Prevents SEO managers from changing the site description in the configuration workout.
  • Optimizes and compresses several .png images to reduce their size. Props to lowwebtech.
Download this release

Release Info

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

Code changes from version 17.7.1 to 17.8

Files changed (135) hide show
  1. admin/class-admin-asset-manager.php +15 -1
  2. admin/class-admin.php +18 -12
  3. admin/class-config.php +0 -1
  4. admin/class-expose-shortlinks.php +1 -0
  5. admin/class-gutenberg-compatibility.php +2 -2
  6. admin/class-plugin-conflict.php +11 -89
  7. admin/class-yoast-dashboard-widget.php +22 -4
  8. admin/class-yoast-plugin-conflict.php +36 -30
  9. admin/config-ui/class-configuration-components.php +0 -79
  10. admin/config-ui/class-configuration-endpoint.php +0 -102
  11. admin/config-ui/class-configuration-options-adapter.php +0 -205
  12. admin/config-ui/class-configuration-page.php +0 -250
  13. admin/config-ui/class-configuration-service.php +0 -182
  14. admin/config-ui/class-configuration-storage.php +0 -205
  15. admin/config-ui/class-configuration-structure.php +0 -123
  16. admin/config-ui/class-configuration-translations.php +0 -64
  17. admin/config-ui/components/class-component-mailchimp-signup.php +0 -86
  18. admin/config-ui/components/class-component-suggestions.php +0 -119
  19. admin/config-ui/components/interface-component.php +0 -42
  20. admin/config-ui/factories/class-factory-post-type.php +0 -76
  21. admin/config-ui/fields/class-field-choice-post-type.php +0 -87
  22. admin/config-ui/fields/class-field-choice.php +0 -42
  23. admin/config-ui/fields/class-field-company-info-missing.php +0 -28
  24. admin/config-ui/fields/class-field-company-logo.php +0 -32
  25. admin/config-ui/fields/class-field-company-name.php +0 -33
  26. admin/config-ui/fields/class-field-company-or-person.php +0 -35
  27. admin/config-ui/fields/class-field-environment.php +0 -91
  28. admin/config-ui/fields/class-field-mailchimp-signup.php +0 -65
  29. admin/config-ui/fields/class-field-multiple-authors.php +0 -86
  30. admin/config-ui/fields/class-field-person.php +0 -32
  31. admin/config-ui/fields/class-field-post-type-visibility.php +0 -25
  32. admin/config-ui/fields/class-field-profile-url-facebook.php +0 -33
  33. admin/config-ui/fields/class-field-profile-url-instagram.php +0 -33
  34. admin/config-ui/fields/class-field-profile-url-linkedin.php +0 -33
  35. admin/config-ui/fields/class-field-profile-url-myspace.php +0 -33
  36. admin/config-ui/fields/class-field-profile-url-pinterest.php +0 -33
  37. admin/config-ui/fields/class-field-profile-url-twitter.php +0 -32
  38. admin/config-ui/fields/class-field-profile-url-wikipedia.php +0 -35
  39. admin/config-ui/fields/class-field-profile-url-youtube.php +0 -33
  40. admin/config-ui/fields/class-field-separator.php +0 -43
  41. admin/config-ui/fields/class-field-site-name.php +0 -60
  42. admin/config-ui/fields/class-field-site-type.php +0 -39
  43. admin/config-ui/fields/class-field-success-message.php +0 -38
  44. admin/config-ui/fields/class-field-suggestions.php +0 -43
  45. admin/config-ui/fields/class-field-title-intro.php +0 -25
  46. admin/config-ui/fields/class-field-tracking-intro.php +0 -25
  47. admin/config-ui/fields/class-field-tracking.php +0 -66
  48. admin/config-ui/fields/class-field.php +0 -157
  49. admin/formatter/class-metabox-formatter.php +16 -2
  50. admin/formatter/class-term-metabox-formatter.php +1 -0
  51. admin/menu/class-menu.php +0 -4
  52. admin/metabox/class-metabox.php +5 -0
  53. admin/notifiers/class-configuration-notifier.php +0 -176
  54. admin/tracking/class-tracking-settings-data.php +6 -0
  55. admin/views/class-yoast-integration-toggles.php +37 -0
  56. admin/views/sidebar.php +1 -8
  57. admin/views/tabs/metas/paper-content/integrations/wincher.php +126 -0
  58. css/dist/admin-global-1771-rtl.css +0 -1
  59. css/dist/admin-global-1771.css +0 -1
  60. css/dist/admin-global-1780-rtl.css +1 -0
  61. css/dist/admin-global-1780.css +1 -0
  62. css/dist/{adminbar-1771-rtl.css → adminbar-1780-rtl.css} +0 -0
  63. css/dist/{adminbar-1771.css → adminbar-1780.css} +0 -0
  64. css/dist/{alerts-1771-rtl.css → alerts-1780-rtl.css} +0 -0
  65. css/dist/{alerts-1771.css → alerts-1780.css} +0 -0
  66. css/dist/dashboard-1771-rtl.css +0 -1
  67. css/dist/dashboard-1771.css +0 -1
  68. css/dist/dashboard-1780-rtl.css +1 -0
  69. css/dist/dashboard-1780.css +1 -0
  70. css/dist/{edit-page-1771-rtl.css → edit-page-1780-rtl.css} +0 -0
  71. css/dist/{edit-page-1771.css → edit-page-1780.css} +0 -0
  72. css/dist/{elementor-1771-rtl.css → elementor-1780-rtl.css} +1 -1
  73. css/dist/{elementor-1771.css → elementor-1780.css} +1 -1
  74. css/dist/{featured-image-1771-rtl.css → featured-image-1780-rtl.css} +0 -0
  75. css/dist/{featured-image-1771.css → featured-image-1780.css} +0 -0
  76. css/dist/{filter-explanation-1771-rtl.css → filter-explanation-1780-rtl.css} +0 -0
  77. css/dist/{filter-explanation-1771.css → filter-explanation-1780.css} +0 -0
  78. css/dist/{icons-1771-rtl.css → icons-1780-rtl.css} +1 -1
  79. css/dist/{icons-1771.css → icons-1780.css} +1 -1
  80. css/dist/{inside-editor-1771-rtl.css → inside-editor-1780-rtl.css} +0 -0
  81. css/dist/{inside-editor-1771.css → inside-editor-1780.css} +0 -0
  82. css/dist/metabox-1771-rtl.css +0 -1
  83. css/dist/metabox-1780-rtl.css +1 -0
  84. css/dist/{metabox-1771.css → metabox-1780.css} +1 -1
  85. css/dist/{metabox-primary-category-1771-rtl.css → metabox-primary-category-1780-rtl.css} +0 -0
  86. css/dist/{metabox-primary-category-1771.css → metabox-primary-category-1780.css} +0 -0
  87. css/dist/{modal-1771-rtl.css → modal-1780-rtl.css} +1 -1
  88. css/dist/{modal-1771.css → modal-1780.css} +1 -1
  89. css/dist/{monorepo-1771-rtl.css → monorepo-1780-rtl.css} +1 -1
  90. css/dist/{monorepo-1771.css → monorepo-1780.css} +1 -1
  91. css/dist/notifications-1771-rtl.css +0 -1
  92. css/dist/notifications-1771.css +0 -1
  93. css/dist/notifications-1780-rtl.css +1 -0
  94. css/dist/notifications-1780.css +1 -0
  95. css/dist/{schema-blocks-1771-rtl.css → schema-blocks-1780-rtl.css} +0 -0
  96. css/dist/{schema-blocks-1771.css → schema-blocks-1780.css} +0 -0
  97. css/dist/{score_icon-1771-rtl.css → score_icon-1780-rtl.css} +0 -0
  98. css/dist/{score_icon-1771.css → score_icon-1780.css} +0 -0
  99. css/dist/{search-appearance-1771-rtl.css → search-appearance-1780-rtl.css} +0 -0
  100. css/dist/{search-appearance-1771.css → search-appearance-1780.css} +0 -0
  101. css/dist/{structured-data-blocks-1771-rtl.css → structured-data-blocks-1780-rtl.css} +0 -0
  102. css/dist/{structured-data-blocks-1771.css → structured-data-blocks-1780.css} +0 -0
  103. css/dist/{toggle-switch-1771-rtl.css → toggle-switch-1780-rtl.css} +0 -0
  104. css/dist/{toggle-switch-1771.css → toggle-switch-1780.css} +0 -0
  105. css/dist/workouts-1771-rtl.css +0 -1
  106. css/dist/workouts-1771.css +0 -1
  107. css/dist/workouts-1780-rtl.css +1 -0
  108. css/dist/workouts-1780.css +1 -0
  109. css/dist/{wpseo-dismissible-1771-rtl.css → wpseo-dismissible-1780-rtl.css} +0 -0
  110. css/dist/{wpseo-dismissible-1771.css → wpseo-dismissible-1780.css} +0 -0
  111. css/dist/{yoast-components-1771-rtl.css → yoast-components-1780-rtl.css} +0 -0
  112. css/dist/{yoast-components-1771.css → yoast-components-1780.css} +0 -0
  113. css/dist/yoast-extensions-1771-rtl.css +0 -1
  114. css/dist/yoast-extensions-1771.css +0 -1
  115. css/dist/yoast-extensions-1780-rtl.css +1 -0
  116. css/dist/yoast-extensions-1780.css +1 -0
  117. css/dist/yst_plugin_tools-1771-rtl.css +0 -1
  118. css/dist/yst_plugin_tools-1771.css +0 -1
  119. css/dist/yst_plugin_tools-1780-rtl.css +1 -0
  120. css/dist/yst_plugin_tools-1780.css +1 -0
  121. css/dist/{yst_seo_score-1771-rtl.css → yst_seo_score-1780-rtl.css} +0 -0
  122. css/dist/{yst_seo_score-1771.css → yst_seo_score-1780.css} +0 -0
  123. images/question-mark.png +0 -0
  124. inc/class-wpseo-meta.php +5 -5
  125. inc/options/class-wpseo-option-ms.php +1 -0
  126. inc/options/class-wpseo-option-wpseo.php +7 -0
  127. inc/wpseo-functions.php +12 -12
  128. js/dist/{addon-installation-1771.js → addon-installation-1780.js} +2 -2
  129. js/dist/admin-global-1771.js +0 -1
  130. js/dist/admin-global-1780.js +1 -0
  131. js/dist/admin-modules-1771.js +0 -4
  132. js/dist/admin-modules-1780.js +4 -0
  133. js/dist/{analysis-worker-1771.js → analysis-worker-1780.js} +1 -1
  134. js/dist/{api-client-1771.js → api-client-1780.js} +1 -1
  135. js/dist/block-editor-1771.js +0 -73
admin/class-admin-asset-manager.php CHANGED
@@ -240,7 +240,12 @@ class WPSEO_Admin_Asset_Manager {
240
  'analysis-worker' => [ self::PREFIX . 'analysis-package' ],
241
  'api-client' => [ 'wp-api' ],
242
  'dashboard-widget' => [ self::PREFIX . 'api-client' ],
243
- 'elementor' => [ self::PREFIX . 'api-client' ],
 
 
 
 
 
244
  'indexation' => [
245
  'jquery-ui-core',
246
  'jquery-ui-progressbar',
@@ -248,6 +253,9 @@ class WPSEO_Admin_Asset_Manager {
248
  'post-edit' => [
249
  self::PREFIX . 'api-client',
250
  self::PREFIX . 'block-editor',
 
 
 
251
  self::PREFIX . 'select2',
252
  ],
253
  'reindex-links' => [
@@ -263,6 +271,9 @@ class WPSEO_Admin_Asset_Manager {
263
  'term-edit' => [
264
  self::PREFIX . 'api-client',
265
  self::PREFIX . 'classic-editor',
 
 
 
266
  self::PREFIX . 'select2',
267
  ],
268
  ];
@@ -335,6 +346,9 @@ class WPSEO_Admin_Asset_Manager {
335
  'wp-dom-ready',
336
  'wp-element',
337
  'wp-i18n',
 
 
 
338
  self::PREFIX . 'analysis',
339
  self::PREFIX . 'react-select',
340
  self::PREFIX . 'yoast-components',
240
  'analysis-worker' => [ self::PREFIX . 'analysis-package' ],
241
  'api-client' => [ 'wp-api' ],
242
  'dashboard-widget' => [ self::PREFIX . 'api-client' ],
243
+ 'elementor' => [
244
+ self::PREFIX . 'api-client',
245
+ self::PREFIX . 'externals-components',
246
+ self::PREFIX . 'externals-contexts',
247
+ self::PREFIX . 'externals-redux',
248
+ ],
249
  'indexation' => [
250
  'jquery-ui-core',
251
  'jquery-ui-progressbar',
253
  'post-edit' => [
254
  self::PREFIX . 'api-client',
255
  self::PREFIX . 'block-editor',
256
+ self::PREFIX . 'externals-components',
257
+ self::PREFIX . 'externals-contexts',
258
+ self::PREFIX . 'externals-redux',
259
  self::PREFIX . 'select2',
260
  ],
261
  'reindex-links' => [
271
  'term-edit' => [
272
  self::PREFIX . 'api-client',
273
  self::PREFIX . 'classic-editor',
274
+ self::PREFIX . 'externals-components',
275
+ self::PREFIX . 'externals-contexts',
276
+ self::PREFIX . 'externals-redux',
277
  self::PREFIX . 'select2',
278
  ],
279
  ];
346
  'wp-dom-ready',
347
  'wp-element',
348
  'wp-i18n',
349
+ self::PREFIX . 'externals-components',
350
+ self::PREFIX . 'externals-contexts',
351
+ self::PREFIX . 'externals-redux',
352
  self::PREFIX . 'analysis',
353
  self::PREFIX . 'react-select',
354
  self::PREFIX . 'yoast-components',
admin/class-admin.php CHANGED
@@ -5,6 +5,8 @@
5
  * @package WPSEO\Admin
6
  */
7
 
 
 
8
  /**
9
  * Class that holds most of the admin functionality for Yoast SEO.
10
  */
@@ -314,18 +316,22 @@ class WPSEO_Admin {
314
  * @return array
315
  */
316
  private function localize_admin_global_script() {
317
- return [
318
- 'isRtl' => is_rtl(),
319
- 'variable_warning' => sprintf(
320
- /* 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' */
321
- __( 'Warning: the variable %1$s cannot be used in this template. See the %2$s for more info.', 'wordpress-seo' ),
322
- '<code>%s</code>',
323
- 'HelpScout beacon'
324
- ),
325
- /* translators: %s: expends to Yoast SEO */
326
- 'help_video_iframe_title' => sprintf( __( '%s video tutorial', 'wordpress-seo' ), 'Yoast SEO' ),
327
- 'scrollable_table_hint' => __( 'Scroll to see the table content.', 'wordpress-seo' ),
328
- ];
 
 
 
 
329
  }
330
 
331
  /**
5
  * @package WPSEO\Admin
6
  */
7
 
8
+ use Yoast\WP\SEO\Config\Wincher_Links;
9
+
10
  /**
11
  * Class that holds most of the admin functionality for Yoast SEO.
12
  */
316
  * @return array
317
  */
318
  private function localize_admin_global_script() {
319
+ return array_merge(
320
+ [
321
+ 'isRtl' => is_rtl(),
322
+ 'variable_warning' => sprintf(
323
+ /* 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' */
324
+ __( 'Warning: the variable %1$s cannot be used in this template. See the %2$s for more info.', 'wordpress-seo' ),
325
+ '<code>%s</code>',
326
+ 'HelpScout beacon'
327
+ ),
328
+ /* translators: %s: expends to Yoast SEO */
329
+ 'help_video_iframe_title' => sprintf( __( '%s video tutorial', 'wordpress-seo' ), 'Yoast SEO' ),
330
+ 'scrollable_table_hint' => __( 'Scroll to see the table content.', 'wordpress-seo' ),
331
+ 'wincher_is_logged_in' => WPSEO_Options::get( 'wincher_integration_active', true ) ? YoastSEO()->helpers->wincher->login_status() : false,
332
+ ],
333
+ YoastSEO()->helpers->wincher->get_admin_global_links()
334
+ );
335
  }
336
 
337
  /**
admin/class-config.php CHANGED
@@ -42,7 +42,6 @@ class WPSEO_Admin_Pages {
42
  public function init() {
43
  if ( filter_input( INPUT_GET, 'wpseo_reset_defaults' ) && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), 'wpseo_reset_defaults' ) && current_user_can( 'manage_options' ) ) {
44
  WPSEO_Options::reset();
45
- wp_redirect( admin_url( 'admin.php?page=' . WPSEO_Configuration_Page::PAGE_IDENTIFIER ) );
46
  }
47
 
48
  add_action( 'admin_enqueue_scripts', [ $this, 'config_page_scripts' ] );
42
  public function init() {
43
  if ( filter_input( INPUT_GET, 'wpseo_reset_defaults' ) && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), 'wpseo_reset_defaults' ) && current_user_can( 'manage_options' ) ) {
44
  WPSEO_Options::reset();
 
45
  }
46
 
47
  add_action( 'admin_enqueue_scripts', [ $this, 'config_page_scripts' ] );
admin/class-expose-shortlinks.php CHANGED
@@ -51,6 +51,7 @@ class WPSEO_Expose_Shortlinks implements WPSEO_WordPress_Integration {
51
  'shortlinks.semrush.trend_help' => 'https://yoa.st/3-v',
52
  'shortlinks.semrush.prices' => 'https://yoa.st/semrush-prices',
53
  'shortlinks.semrush.premium_landing_page' => 'https://yoa.st/413',
 
54
  ];
55
 
56
  /**
51
  'shortlinks.semrush.trend_help' => 'https://yoa.st/3-v',
52
  'shortlinks.semrush.prices' => 'https://yoa.st/semrush-prices',
53
  'shortlinks.semrush.premium_landing_page' => 'https://yoa.st/413',
54
+ 'shortlinks.wincher.seo_performance' => 'https://yoa.st/wincher-integration',
55
  ];
56
 
57
  /**
admin/class-gutenberg-compatibility.php CHANGED
@@ -15,14 +15,14 @@ class WPSEO_Gutenberg_Compatibility {
15
  *
16
  * @var string
17
  */
18
- const CURRENT_RELEASE = '12.0.1';
19
 
20
  /**
21
  * The minimally supported version of Gutenberg by the plugin.
22
  *
23
  * @var string
24
  */
25
- const MINIMUM_SUPPORTED = '12.0.1';
26
 
27
  /**
28
  * Holds the current version.
15
  *
16
  * @var string
17
  */
18
+ const CURRENT_RELEASE = '12.1.0';
19
 
20
  /**
21
  * The minimally supported version of Gutenberg by the plugin.
22
  *
23
  * @var string
24
  */
25
+ const MINIMUM_SUPPORTED = '12.1.0';
26
 
27
  /**
28
  * Holds the current version.
admin/class-plugin-conflict.php CHANGED
@@ -6,6 +6,8 @@
6
  * @since 1.7.0
7
  */
8
 
 
 
9
  /**
10
  * Contains list of conflicting plugins.
11
  */
@@ -14,96 +16,18 @@ class WPSEO_Plugin_Conflict extends Yoast_Plugin_Conflict {
14
  /**
15
  * The plugins must be grouped per section.
16
  *
17
- * It's possible to check for each section if there are conflicting plugin
 
 
18
  *
19
  * @var array
20
  */
21
  protected $plugins = [
22
  // The plugin which are writing OG metadata.
23
- 'open_graph' => [
24
- '2-click-socialmedia-buttons/2-click-socialmedia-buttons.php',
25
- // 2 Click Social Media Buttons.
26
- 'add-link-to-facebook/add-link-to-facebook.php', // Add Link to Facebook.
27
- 'add-meta-tags/add-meta-tags.php', // Add Meta Tags.
28
- 'easy-facebook-share-thumbnails/esft.php', // Easy Facebook Share Thumbnail.
29
- 'facebook/facebook.php', // Facebook (official plugin).
30
- 'facebook-awd/AWD_facebook.php', // Facebook AWD All in one.
31
- 'facebook-featured-image-and-open-graph-meta-tags/fb-featured-image.php',
32
- // Facebook Featured Image & OG Meta Tags.
33
- 'facebook-meta-tags/facebook-metatags.php', // Facebook Meta Tags.
34
- 'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
35
- // Facebook Open Graph Meta Tags for WordPress.
36
- 'facebook-revised-open-graph-meta-tag/index.php', // Facebook Revised Open Graph Meta Tag.
37
- 'facebook-thumb-fixer/_facebook-thumb-fixer.php', // Facebook Thumb Fixer.
38
- 'facebook-and-digg-thumbnail-generator/facebook-and-digg-thumbnail-generator.php',
39
- // Fedmich's Facebook Open Graph Meta.
40
- 'network-publisher/networkpub.php', // Network Publisher.
41
- 'nextgen-facebook/nextgen-facebook.php', // NextGEN Facebook OG.
42
- 'opengraph/opengraph.php', // Open Graph.
43
- 'open-graph-protocol-framework/open-graph-protocol-framework.php',
44
- // Open Graph Protocol Framework.
45
- 'seo-facebook-comments/seofacebook.php', // SEO Facebook Comments.
46
- 'sexybookmarks/sexy-bookmarks.php', // Shareaholic.
47
- 'shareaholic/sexy-bookmarks.php', // Shareaholic.
48
- 'sharepress/sharepress.php', // SharePress.
49
- 'simple-facebook-connect/sfc.php', // Simple Facebook Connect.
50
- 'social-discussions/social-discussions.php', // Social Discussions.
51
- 'social-sharing-toolkit/social_sharing_toolkit.php', // Social Sharing Toolkit.
52
- 'socialize/socialize.php', // Socialize.
53
- 'only-tweet-like-share-and-google-1/tweet-like-plusone.php',
54
- // Tweet, Like, Google +1 and Share.
55
- 'wordbooker/wordbooker.php', // Wordbooker.
56
- 'wpsso/wpsso.php', // WordPress Social Sharing Optimization.
57
- 'wp-caregiver/wp-caregiver.php', // WP Caregiver.
58
- 'wp-facebook-like-send-open-graph-meta/wp-facebook-like-send-open-graph-meta.php',
59
- // WP Facebook Like Send & Open Graph Meta.
60
- 'wp-facebook-open-graph-protocol/wp-facebook-ogp.php', // WP Facebook Open Graph protocol.
61
- 'wp-ogp/wp-ogp.php', // WP-OGP.
62
- 'zoltonorg-social-plugin/zosp.php', // Zolton.org Social Plugin.
63
- ],
64
- 'xml_sitemaps' => [
65
- 'google-sitemap-plugin/google-sitemap-plugin.php',
66
- // Google Sitemap (BestWebSoft).
67
- 'xml-sitemaps/xml-sitemaps.php',
68
- // XML Sitemaps (Denis de Bernardy and Mike Koepke).
69
- 'bwp-google-xml-sitemaps/bwp-simple-gxs.php',
70
- // Better WordPress Google XML Sitemaps (Khang Minh).
71
- 'google-sitemap-generator/sitemap.php',
72
- // Google XML Sitemaps (Arne Brachhold).
73
- 'xml-sitemap-feed/xml-sitemap.php',
74
- // XML Sitemap & Google News feeds (RavanH).
75
- 'google-monthly-xml-sitemap/monthly-xml-sitemap.php',
76
- // Google Monthly XML Sitemap (Andrea Pernici).
77
- 'simple-google-sitemap-xml/simple-google-sitemap-xml.php',
78
- // Simple Google Sitemap XML (iTx Technologies).
79
- 'another-simple-xml-sitemap/another-simple-xml-sitemap.php',
80
- // Another Simple XML Sitemap.
81
- 'xml-maps/google-sitemap.php',
82
- // Xml Sitemap (Jason Martens).
83
- 'google-xml-sitemap-generator-by-anton-dachauer/adachauer-google-xml-sitemap.php',
84
- // Google XML Sitemap Generator by Anton Dachauer (Anton Dachauer).
85
- 'wp-xml-sitemap/wp-xml-sitemap.php',
86
- // WP XML Sitemap (Team Vivacity).
87
- 'sitemap-generator-for-webmasters/sitemap.php',
88
- // Sitemap Generator for Webmasters (iwebslogtech).
89
- 'xml-sitemap-xml-sitemapcouk/xmls.php',
90
- // XML Sitemap - XML-Sitemap.co.uk (Simon Hancox).
91
- 'sewn-in-xml-sitemap/sewn-xml-sitemap.php',
92
- // Sewn In XML Sitemap (jcow).
93
- 'rps-sitemap-generator/rps-sitemap-generator.php',
94
- // RPS Sitemap Generator (redpixelstudios).
95
- ],
96
- 'cloaking' => [
97
- 'rs-head-cleaner/rs-head-cleaner.php',
98
- // RS Head Cleaner Plus https://wordpress.org/plugins/rs-head-cleaner/.
99
- 'rs-head-cleaner-lite/rs-head-cleaner-lite.php',
100
- // RS Head Cleaner Lite https://wordpress.org/plugins/rs-head-cleaner-lite/.
101
- ],
102
- 'seo' => [
103
- 'all-in-one-seo-pack/all_in_one_seo_pack.php', // All in One SEO Pack.
104
- 'seo-ultimate/seo-ultimate.php', // SEO Ultimate.
105
- 'seo-by-rank-math/rank-math.php', // Rank Math.
106
- ],
107
  ];
108
 
109
  /**
@@ -125,13 +49,11 @@ class WPSEO_Plugin_Conflict extends Yoast_Plugin_Conflict {
125
  * @param string|bool $plugin Optional plugin basename to check.
126
  */
127
  public static function hook_check_for_plugin_conflicts( $plugin = false ) {
128
-
129
- // The instance of itself.
130
  $instance = self::get_instance();
131
 
132
- // Only add plugin as active plugin if $plugin isn't false.
133
  if ( $plugin && is_string( $plugin ) ) {
134
- // Because it's just activated.
135
  $instance->add_active_plugin( $instance->find_plugin_category( $plugin ), $plugin );
136
  }
137
 
6
  * @since 1.7.0
7
  */
8
 
9
+ use Yoast\WP\SEO\Config\Conflicting_Plugins;
10
+
11
  /**
12
  * Contains list of conflicting plugins.
13
  */
16
  /**
17
  * The plugins must be grouped per section.
18
  *
19
+ * It's possible to check for each section if there are conflicting plugin.
20
+ *
21
+ * NOTE: when changing this array, be sure to update the array in Conflicting_Plugins_Service too.
22
  *
23
  * @var array
24
  */
25
  protected $plugins = [
26
  // The plugin which are writing OG metadata.
27
+ 'open_graph' => Conflicting_Plugins::OPEN_GRAPH_PLUGINS,
28
+ 'xml_sitemaps' => Conflicting_Plugins::XML_SITEMAPS_PLUGINS,
29
+ 'cloaking' => Conflicting_Plugins::CLOAKING_PLUGINS,
30
+ 'seo' => Conflicting_Plugins::SEO_PLUGINS,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  ];
32
 
33
  /**
49
  * @param string|bool $plugin Optional plugin basename to check.
50
  */
51
  public static function hook_check_for_plugin_conflicts( $plugin = false ) {
52
+ // The instance of the plugin.
 
53
  $instance = self::get_instance();
54
 
55
+ // Only add the plugin as an active plugin if $plugin isn't false.
56
  if ( $plugin && is_string( $plugin ) ) {
 
57
  $instance->add_active_plugin( $instance->find_plugin_category( $plugin ), $plugin );
58
  }
59
 
admin/class-yoast-dashboard-widget.php CHANGED
@@ -5,6 +5,12 @@
5
  * @package WPSEO\Admin
6
  */
7
 
 
 
 
 
 
 
8
  /**
9
  * Class to change or add WordPress dashboard widgets.
10
  */
@@ -109,6 +115,7 @@ class Yoast_Dashboard_Widget implements WPSEO_WordPress_Integration {
109
  $yoast_components_l10n->localize_script( 'dashboard-widget' );
110
  $this->asset_manager->enqueue_script( 'dashboard-widget' );
111
  $this->asset_manager->enqueue_style( 'wp-dashboard' );
 
112
  }
113
 
114
  /**
@@ -117,15 +124,26 @@ class Yoast_Dashboard_Widget implements WPSEO_WordPress_Integration {
117
  * @return array The translated strings.
118
  */
119
  public function localize_dashboard_script() {
 
 
 
 
 
 
 
 
120
  return [
121
- 'feed_header' => sprintf(
122
  /* translators: %1$s resolves to Yoast.com */
123
  __( 'Latest blog posts on %1$s', 'wordpress-seo' ),
124
  'Yoast.com'
125
  ),
126
- 'feed_footer' => __( 'Read more like this on our SEO blog', 'wordpress-seo' ),
127
- 'wp_version' => substr( $GLOBALS['wp_version'], 0, 3 ) . '-' . ( is_plugin_active( 'classic-editor/classic-editor.php' ) ? '1' : '0' ),
128
- 'php_version' => PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION,
 
 
 
129
  ];
130
  }
131
 
5
  * @package WPSEO\Admin
6
  */
7
 
8
+ use Yoast\WP\SEO\Conditionals\Wincher_Conditional;
9
+ use Yoast\WP\SEO\Config\Wincher_Client;
10
+ use Yoast\WP\SEO\Exceptions\OAuth\Authentication_Failed_Exception;
11
+ use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Property_Exception;
12
+ use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Token_Exception;
13
+
14
  /**
15
  * Class to change or add WordPress dashboard widgets.
16
  */
115
  $yoast_components_l10n->localize_script( 'dashboard-widget' );
116
  $this->asset_manager->enqueue_script( 'dashboard-widget' );
117
  $this->asset_manager->enqueue_style( 'wp-dashboard' );
118
+ $this->asset_manager->enqueue_style( 'monorepo' );
119
  }
120
 
121
  /**
124
  * @return array The translated strings.
125
  */
126
  public function localize_dashboard_script() {
127
+ $is_wincher_active = WPSEO_Options::get( 'wincher_integration_active', true );
128
+
129
+ // If feature flag is disabled, Wincher should not be active.
130
+ $conditional = new Wincher_Conditional();
131
+ if ( ! $conditional->is_met() ) {
132
+ $is_wincher_active = false;
133
+ }
134
+
135
  return [
136
+ 'feed_header' => sprintf(
137
  /* translators: %1$s resolves to Yoast.com */
138
  __( 'Latest blog posts on %1$s', 'wordpress-seo' ),
139
  'Yoast.com'
140
  ),
141
+ 'feed_footer' => __( 'Read more like this on our SEO blog', 'wordpress-seo' ),
142
+ 'wp_version' => substr( $GLOBALS['wp_version'], 0, 3 ) . '-' . ( is_plugin_active( 'classic-editor/classic-editor.php' ) ? '1' : '0' ),
143
+ 'php_version' => PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION,
144
+ 'is_wincher_active' => $is_wincher_active ? 1 : 0,
145
+ 'wincher_is_logged_in' => $is_wincher_active ? YoastSEO()->helpers->wincher->login_status() : false,
146
+ 'wincher_website_id' => WPSEO_Options::get( 'wincher_website_id', '' ),
147
  ];
148
  }
149
 
admin/class-yoast-plugin-conflict.php CHANGED
@@ -33,7 +33,7 @@ class Yoast_Plugin_Conflict {
33
  *
34
  * @var array
35
  */
36
- protected $active_plugins = [];
37
 
38
  /**
39
  * Property for holding instance of itself.
@@ -52,8 +52,8 @@ class Yoast_Plugin_Conflict {
52
  */
53
  public static function get_instance( $class_name = '' ) {
54
 
55
- if ( is_null( self::$instance ) ) {
56
- if ( ! is_string( $class_name ) || $class_name === '' ) {
57
  $class_name = __CLASS__;
58
  }
59
 
@@ -71,9 +71,9 @@ class Yoast_Plugin_Conflict {
71
  */
72
  protected function __construct() {
73
  // Set active plugins.
74
- $this->all_active_plugins = get_option( 'active_plugins' );
75
 
76
- if ( filter_input( INPUT_GET, 'action' ) === 'deactivate' ) {
77
  $this->remove_deactivated_plugin();
78
  }
79
 
@@ -92,13 +92,18 @@ class Yoast_Plugin_Conflict {
92
 
93
  static $sections_checked;
94
 
 
 
 
 
 
95
  if ( $sections_checked === null ) {
96
  $sections_checked = [];
97
  }
98
 
99
- if ( ! in_array( $plugin_section, $sections_checked, true ) ) {
100
  $sections_checked[] = $plugin_section;
101
- $has_conflicts = ( ! empty( $this->active_plugins[ $plugin_section ] ) );
102
 
103
  return $has_conflicts;
104
  }
@@ -114,15 +119,18 @@ class Yoast_Plugin_Conflict {
114
  *
115
  * @param string $plugin_section Plugin conflict type (such as Open Graph or sitemap).
116
  *
 
 
 
117
  * @return string
118
  */
119
  public function get_conflicting_plugins_as_string( $plugin_section ) {
120
- if ( ! function_exists( 'get_plugin_data' ) ) {
121
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
122
  }
123
 
124
  // Getting the active plugins by given section.
125
- $plugins = $this->active_plugins[ $plugin_section ];
126
 
127
  $plugin_names = [];
128
  foreach ( $plugins as $plugin ) {
@@ -134,7 +142,7 @@ class Yoast_Plugin_Conflict {
134
  unset( $plugins, $plugin );
135
 
136
  if ( ! empty( $plugin_names ) ) {
137
- return implode( ' &amp; ', $plugin_names );
138
  }
139
  }
140
 
@@ -152,9 +160,9 @@ class Yoast_Plugin_Conflict {
152
  }
153
 
154
  // List of all active sections.
155
- $sections = array_keys( $plugin_sections );
156
  // List of all sections.
157
- $all_plugin_sections = array_keys( $this->plugins );
158
 
159
  /*
160
  * Get all sections that are inactive.
@@ -162,10 +170,10 @@ class Yoast_Plugin_Conflict {
162
  *
163
  * This happens when Sitemaps or OpenGraph implementations toggle active/disabled.
164
  */
165
- $inactive_sections = array_diff( $all_plugin_sections, $sections );
166
  if ( ! empty( $inactive_sections ) ) {
167
  foreach ( $inactive_sections as $section ) {
168
- array_walk( $this->plugins[ $section ], [ $this, 'clear_error' ] );
169
  }
170
  }
171
 
@@ -175,11 +183,11 @@ class Yoast_Plugin_Conflict {
175
  $inactive_plugins = $this->plugins[ $section ];
176
 
177
  // If there are active plugins, filter them from being cleared.
178
- if ( isset( $this->active_plugins[ $section ] ) ) {
179
- $inactive_plugins = array_diff( $this->plugins[ $section ], $this->active_plugins[ $section ] );
180
  }
181
 
182
- array_walk( $inactive_plugins, [ $this, 'clear_error' ] );
183
  }
184
  }
185
 
@@ -193,7 +201,7 @@ class Yoast_Plugin_Conflict {
193
 
194
  $notification_center = Yoast_Notification_Center::get();
195
 
196
- foreach ( $this->active_plugins[ $plugin_section ] as $plugin_file ) {
197
 
198
  $plugin_name = $this->get_plugin_name( $plugin_file );
199
 
@@ -265,7 +273,7 @@ class Yoast_Plugin_Conflict {
265
  * @return bool
266
  */
267
  protected function check_plugin_is_active( $plugin ) {
268
- return in_array( $plugin, $this->all_active_plugins, true );
269
  }
270
 
271
  /**
@@ -278,13 +286,12 @@ class Yoast_Plugin_Conflict {
278
  * @param string $plugin Plugin basename string.
279
  */
280
  protected function add_active_plugin( $plugin_section, $plugin ) {
281
-
282
- if ( ! array_key_exists( $plugin_section, $this->active_plugins ) ) {
283
- $this->active_plugins[ $plugin_section ] = [];
284
  }
285
 
286
- if ( ! in_array( $plugin, $this->active_plugins[ $plugin_section ], true ) ) {
287
- $this->active_plugins[ $plugin_section ][] = $plugin;
288
  }
289
  }
290
 
@@ -298,9 +305,8 @@ class Yoast_Plugin_Conflict {
298
  * @return int|string
299
  */
300
  protected function find_plugin_category( $plugin ) {
301
-
302
  foreach ( $this->plugins as $plugin_section => $plugins ) {
303
- if ( in_array( $plugin, $plugins, true ) ) {
304
  return $plugin_section;
305
  }
306
  }
@@ -314,7 +320,7 @@ class Yoast_Plugin_Conflict {
314
  * @return string|bool Plugin name or false when no name is set.
315
  */
316
  protected function get_plugin_name( $plugin ) {
317
- $plugin_details = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
318
 
319
  if ( $plugin_details['Name'] !== '' ) {
320
  return $plugin_details['Name'];
@@ -327,8 +333,8 @@ class Yoast_Plugin_Conflict {
327
  * When being in the deactivation process the currently deactivated plugin has to be removed.
328
  */
329
  private function remove_deactivated_plugin() {
330
- $deactivated_plugin = filter_input( INPUT_GET, 'plugin' );
331
- $key_to_remove = array_search( $deactivated_plugin, $this->all_active_plugins, true );
332
 
333
  if ( $key_to_remove !== false ) {
334
  unset( $this->all_active_plugins[ $key_to_remove ] );
@@ -343,6 +349,6 @@ class Yoast_Plugin_Conflict {
343
  * @return string
344
  */
345
  private function get_notification_identifier( $plugin_file ) {
346
- return md5( $plugin_file );
347
  }
348
  }
33
  *
34
  * @var array
35
  */
36
+ protected $active_conflicting_plugins = [];
37
 
38
  /**
39
  * Property for holding instance of itself.
52
  */
53
  public static function get_instance( $class_name = '' ) {
54
 
55
+ if ( \is_null( self::$instance ) ) {
56
+ if ( ! \is_string( $class_name ) || $class_name === '' ) {
57
  $class_name = __CLASS__;
58
  }
59
 
71
  */
72
  protected function __construct() {
73
  // Set active plugins.
74
+ $this->all_active_plugins = \get_option( 'active_plugins' );
75
 
76
+ if ( \filter_input( INPUT_GET, 'action' ) === 'deactivate' ) {
77
  $this->remove_deactivated_plugin();
78
  }
79
 
92
 
93
  static $sections_checked;
94
 
95
+ // Return early if there are no active conflicting plugins at all.
96
+ if ( empty( $this->active_conflicting_plugins ) ) {
97
+ return false;
98
+ }
99
+
100
  if ( $sections_checked === null ) {
101
  $sections_checked = [];
102
  }
103
 
104
+ if ( ! \in_array( $plugin_section, $sections_checked, true ) ) {
105
  $sections_checked[] = $plugin_section;
106
+ $has_conflicts = ( ! empty( $this->active_conflicting_plugins[ $plugin_section ] ) );
107
 
108
  return $has_conflicts;
109
  }
119
  *
120
  * @param string $plugin_section Plugin conflict type (such as Open Graph or sitemap).
121
  *
122
+ * @deprecated 17.7 This method is unused and will be removed in the future
123
+ * @codeCoverageIgnore
124
+ *
125
  * @return string
126
  */
127
  public function get_conflicting_plugins_as_string( $plugin_section ) {
128
+ if ( ! \function_exists( 'get_plugin_data' ) ) {
129
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
130
  }
131
 
132
  // Getting the active plugins by given section.
133
+ $plugins = $this->active_conflicting_plugins[ $plugin_section ];
134
 
135
  $plugin_names = [];
136
  foreach ( $plugins as $plugin ) {
142
  unset( $plugins, $plugin );
143
 
144
  if ( ! empty( $plugin_names ) ) {
145
+ return \implode( ' &amp; ', $plugin_names );
146
  }
147
  }
148
 
160
  }
161
 
162
  // List of all active sections.
163
+ $sections = \array_keys( $plugin_sections );
164
  // List of all sections.
165
+ $all_plugin_sections = \array_keys( $this->plugins );
166
 
167
  /*
168
  * Get all sections that are inactive.
170
  *
171
  * This happens when Sitemaps or OpenGraph implementations toggle active/disabled.
172
  */
173
+ $inactive_sections = \array_diff( $all_plugin_sections, $sections );
174
  if ( ! empty( $inactive_sections ) ) {
175
  foreach ( $inactive_sections as $section ) {
176
+ \array_walk( $this->plugins[ $section ], [ $this, 'clear_error' ] );
177
  }
178
  }
179
 
183
  $inactive_plugins = $this->plugins[ $section ];
184
 
185
  // If there are active plugins, filter them from being cleared.
186
+ if ( isset( $this->active_conflicting_plugins[ $section ] ) ) {
187
+ $inactive_plugins = \array_diff( $this->plugins[ $section ], $this->active_conflicting_plugins[ $section ] );
188
  }
189
 
190
+ \array_walk( $inactive_plugins, [ $this, 'clear_error' ] );
191
  }
192
  }
193
 
201
 
202
  $notification_center = Yoast_Notification_Center::get();
203
 
204
+ foreach ( $this->active_conflicting_plugins[ $plugin_section ] as $plugin_file ) {
205
 
206
  $plugin_name = $this->get_plugin_name( $plugin_file );
207
 
273
  * @return bool
274
  */
275
  protected function check_plugin_is_active( $plugin ) {
276
+ return \in_array( $plugin, $this->all_active_plugins, true );
277
  }
278
 
279
  /**
286
  * @param string $plugin Plugin basename string.
287
  */
288
  protected function add_active_plugin( $plugin_section, $plugin ) {
289
+ if ( ! \array_key_exists( $plugin_section, $this->active_conflicting_plugins ) ) {
290
+ $this->active_conflicting_plugins[ $plugin_section ] = [];
 
291
  }
292
 
293
+ if ( ! \in_array( $plugin, $this->active_conflicting_plugins[ $plugin_section ], true ) ) {
294
+ $this->active_conflicting_plugins[ $plugin_section ][] = $plugin;
295
  }
296
  }
297
 
305
  * @return int|string
306
  */
307
  protected function find_plugin_category( $plugin ) {
 
308
  foreach ( $this->plugins as $plugin_section => $plugins ) {
309
+ if ( \in_array( $plugin, $plugins, true ) ) {
310
  return $plugin_section;
311
  }
312
  }
320
  * @return string|bool Plugin name or false when no name is set.
321
  */
322
  protected function get_plugin_name( $plugin ) {
323
+ $plugin_details = \get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
324
 
325
  if ( $plugin_details['Name'] !== '' ) {
326
  return $plugin_details['Name'];
333
  * When being in the deactivation process the currently deactivated plugin has to be removed.
334
  */
335
  private function remove_deactivated_plugin() {
336
+ $deactivated_plugin = \filter_input( INPUT_GET, 'plugin' );
337
+ $key_to_remove = \array_search( $deactivated_plugin, $this->all_active_plugins, true );
338
 
339
  if ( $key_to_remove !== false ) {
340
  unset( $this->all_active_plugins[ $key_to_remove ] );
349
  * @return string
350
  */
351
  private function get_notification_identifier( $plugin_file ) {
352
+ return \md5( $plugin_file );
353
  }
354
  }
admin/config-ui/class-configuration-components.php DELETED
@@ -1,79 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin\ConfigurationUI
6
- */
7
-
8
- /**
9
- * Class WPSEO_Configuration_Components.
10
- */
11
- class WPSEO_Configuration_Components {
12
-
13
- /**
14
- * List of registered components.
15
- *
16
- * @var WPSEO_Config_Component[]
17
- */
18
- protected $components = [];
19
-
20
- /**
21
- * Adapter.
22
- *
23
- * @var WPSEO_Configuration_Options_Adapter
24
- */
25
- protected $adapter;
26
-
27
- /**
28
- * Add default components.
29
- */
30
- public function initialize() {
31
- $this->add_component( new WPSEO_Config_Component_Mailchimp_Signup() );
32
- $this->add_component( new WPSEO_Config_Component_Suggestions() );
33
- }
34
-
35
- /**
36
- * Add a component.
37
- *
38
- * @param WPSEO_Config_Component $component Component to add.
39
- */
40
- public function add_component( WPSEO_Config_Component $component ) {
41
- $this->components[] = $component;
42
- }
43
-
44
- /**
45
- * Sets the storage to use.
46
- *
47
- * @param WPSEO_Configuration_Storage $storage Storage to use.
48
- */
49
- public function set_storage( WPSEO_Configuration_Storage $storage ) {
50
- $this->set_adapter( $storage->get_adapter() );
51
-
52
- foreach ( $this->components as $component ) {
53
- $storage->add_field( $component->get_field() );
54
- }
55
- }
56
-
57
- /**
58
- * Sets the adapter to use.
59
- *
60
- * @param WPSEO_Configuration_Options_Adapter $adapter Adapter to use.
61
- */
62
- public function set_adapter( WPSEO_Configuration_Options_Adapter $adapter ) {
63
- $this->adapter = $adapter;
64
-
65
- foreach ( $this->components as $component ) {
66
- $adapter->add_custom_lookup(
67
- $component->get_field()->get_identifier(),
68
- [
69
- $component,
70
- 'get_data',
71
- ],
72
- [
73
- $component,
74
- 'set_data',
75
- ]
76
- );
77
- }
78
- }
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/config-ui/class-configuration-endpoint.php DELETED
@@ -1,102 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin\ConfigurationUI
6
- */
7
-
8
- /**
9
- * Class WPSEO_Configuration_Endpoint.
10
- */
11
- class WPSEO_Configuration_Endpoint {
12
-
13
- /**
14
- * Holds the REST namespace.
15
- *
16
- * @var string
17
- */
18
- const REST_NAMESPACE = 'yoast/v1';
19
-
20
- /**
21
- * Holds the endpoint to retrieve from.
22
- *
23
- * @var string
24
- */
25
- const ENDPOINT_RETRIEVE = 'configurator';
26
-
27
- /**
28
- * Holds the endpoint to store to.
29
- *
30
- * @var string
31
- */
32
- const ENDPOINT_STORE = 'configurator';
33
-
34
- /**
35
- * Holds the capability that can retrieve from the endpoint.
36
- *
37
- * @var string
38
- */
39
- const CAPABILITY_RETRIEVE = 'wpseo_manage_options';
40
-
41
- /**
42
- * Holds the capability that can store to the endpoint.
43
- *
44
- * @var string
45
- */
46
- const CAPABILITY_STORE = 'wpseo_manage_options';
47
-
48
- /**
49
- * Service to use.
50
- *
51
- * @var WPSEO_Configuration_Service
52
- */
53
- protected $service;
54
-
55
- /**
56
- * Sets the service to use.
57
- *
58
- * @param WPSEO_Configuration_Service $service Service to use.
59
- */
60
- public function set_service( WPSEO_Configuration_Service $service ) {
61
- $this->service = $service;
62
- }
63
-
64
- /**
65
- * Register REST routes.
66
- */
67
- public function register() {
68
- // Register fetch config.
69
- $route_args = [
70
- 'methods' => 'GET',
71
- 'callback' => [ $this->service, 'get_configuration' ],
72
- 'permission_callback' => [ $this, 'can_retrieve_data' ],
73
- ];
74
- register_rest_route( self::REST_NAMESPACE, self::ENDPOINT_RETRIEVE, $route_args );
75
-
76
- // Register save changes.
77
- $route_args = [
78
- 'methods' => 'POST',
79
- 'callback' => [ $this->service, 'set_configuration' ],
80
- 'permission_callback' => [ $this, 'can_save_data' ],
81
- ];
82
- register_rest_route( self::REST_NAMESPACE, self::ENDPOINT_STORE, $route_args );
83
- }
84
-
85
- /**
86
- * Permission callback implementation.
87
- *
88
- * @return bool
89
- */
90
- public function can_retrieve_data() {
91
- return current_user_can( self::CAPABILITY_RETRIEVE );
92
- }
93
-
94
- /**
95
- * Permission callback implementation.
96
- *
97
- * @return bool
98
- */
99
- public function can_save_data() {
100
- return current_user_can( self::CAPABILITY_STORE );
101
- }
102
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/config-ui/class-configuration-options-adapter.php DELETED
@@ -1,205 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin\ConfigurationUI
6
- */
7
-
8
- /**
9
- * Class WPSEO_Configuration_Options_Adapter.
10
- *
11
- * Convert Configuration settings to WPSEO Options.
12
- *
13
- * @since 3.6
14
- */
15
- class WPSEO_Configuration_Options_Adapter {
16
-
17
- /**
18
- * Holds the option type value that indicates: WordPress.
19
- *
20
- * @var string
21
- */
22
- const OPTION_TYPE_WORDPRESS = 'wordpress';
23
-
24
- /**
25
- * Holds the option type value that indicates: Yoast.
26
- *
27
- * @var string
28
- */
29
- const OPTION_TYPE_YOAST = 'yoast';
30
-
31
- /**
32
- * Holds the option type value that indicates: Custom.
33
- *
34
- * @var string
35
- */
36
- const OPTION_TYPE_CUSTOM = 'custom';
37
-
38
- /**
39
- * List of registered lookups.
40
- *
41
- * @var array
42
- */
43
- protected $lookup = [];
44
-
45
- /**
46
- * Add a lookup for a WordPress native option.
47
- *
48
- * @param string $class_name Class to bind to an option.
49
- * @param string $option Option name to use.
50
- *
51
- * @throws InvalidArgumentException Thrown when invalid input is provided.
52
- */
53
- public function add_wordpress_lookup( $class_name, $option ) {
54
-
55
- if ( ! is_string( $option ) ) {
56
- throw new InvalidArgumentException( 'WordPress option must be a string.' );
57
- }
58
-
59
- $this->add_lookup( $class_name, self::OPTION_TYPE_WORDPRESS, $option );
60
- }
61
-
62
- /**
63
- * Add a lookup for a Yoast option.
64
- *
65
- * @param string $class_name Class to bind to the lookup.
66
- * @param string $key Key in the option group to bind to.
67
- *
68
- * @throws InvalidArgumentException Thrown when invalid input is provided.
69
- */
70
- public function add_option_lookup( $class_name, $key ) {
71
-
72
- $test = WPSEO_Options::get( $key );
73
- if ( is_null( $test ) ) {
74
- /* translators: %1$s resolves to the option name passed to the lookup registration */
75
- throw new InvalidArgumentException( sprintf( __( 'Yoast option %1$s not found.', 'wordpress-seo' ), $key ) );
76
- }
77
-
78
- $this->add_lookup( $class_name, self::OPTION_TYPE_YOAST, $key );
79
- }
80
-
81
- /**
82
- * Add a lookup for a custom implementation.
83
- *
84
- * @param string $class_name Class to bind to the lookup.
85
- * @param callable $callback_get Callback to retrieve data.
86
- * @param callable $callback_set Callback to save data.
87
- *
88
- * @throws InvalidArgumentException Thrown when invalid input is provided.
89
- */
90
- public function add_custom_lookup( $class_name, $callback_get, $callback_set ) {
91
-
92
- if ( ! is_callable( $callback_get ) || ! is_callable( $callback_set ) ) {
93
- throw new InvalidArgumentException( 'Custom option must be callable.' );
94
- }
95
-
96
- $this->add_lookup(
97
- $class_name,
98
- self::OPTION_TYPE_CUSTOM,
99
- [ $callback_get, $callback_set ]
100
- );
101
- }
102
-
103
- /**
104
- * Add a field lookup.
105
- *
106
- * @param string $class_name Class to add lookup for.
107
- * @param string $type Type of lookup.
108
- * @param string|array $option Implementation of the lookup.
109
- *
110
- * @throws Exception Thrown when invalid input is provided.
111
- */
112
- protected function add_lookup( $class_name, $type, $option ) {
113
- $this->lookup[ $class_name ] = [
114
- 'type' => $type,
115
- 'option' => $option,
116
- ];
117
- }
118
-
119
- /**
120
- * Get the data for the provided field.
121
- *
122
- * @param WPSEO_Config_Field $field Field to get data for.
123
- *
124
- * @return mixed
125
- */
126
- public function get( WPSEO_Config_Field $field ) {
127
- $identifier = $field->get_identifier();
128
-
129
- // Lookup option and retrieve value.
130
- $type = $this->get_option_type( $identifier );
131
- $option = $this->get_option( $identifier );
132
-
133
- switch ( $type ) {
134
- case self::OPTION_TYPE_WORDPRESS:
135
- return get_option( $option );
136
-
137
- case self::OPTION_TYPE_YOAST:
138
- return WPSEO_Options::get( $option );
139
-
140
- case self::OPTION_TYPE_CUSTOM:
141
- return call_user_func( $option[0] );
142
- }
143
-
144
- return null;
145
- }
146
-
147
- /**
148
- * Save data from a field.
149
- *
150
- * @param WPSEO_Config_Field $field Field to use for lookup.
151
- * @param mixed $value Value to save to the lookup of the field.
152
- *
153
- * @return bool
154
- */
155
- public function set( WPSEO_Config_Field $field, $value ) {
156
- $identifier = $field->get_identifier();
157
-
158
- // Lookup option and retrieve value.
159
- $type = $this->get_option_type( $identifier );
160
- $option = $this->get_option( $identifier );
161
-
162
- switch ( $type ) {
163
- case self::OPTION_TYPE_WORDPRESS:
164
- return update_option( $option, $value );
165
-
166
- case self::OPTION_TYPE_YOAST:
167
- return WPSEO_Options::set( $option, $value );
168
-
169
- case self::OPTION_TYPE_CUSTOM:
170
- return call_user_func( $option[1], $value );
171
- }
172
-
173
- return false;
174
- }
175
-
176
- /**
177
- * Get the lookup type for a specific class.
178
- *
179
- * @param string $class_name Class to get the type of.
180
- *
181
- * @return string|null
182
- */
183
- protected function get_option_type( $class_name ) {
184
- if ( ! isset( $this->lookup[ $class_name ] ) ) {
185
- return null;
186
- }
187
-
188
- return $this->lookup[ $class_name ]['type'];
189
- }
190
-
191
- /**
192
- * Get the option for a specific class.
193
- *
194
- * @param string $class_name Class to get the option of.
195
- *
196
- * @return string|array|null
197
- */
198
- protected function get_option( $class_name ) {
199
- if ( ! isset( $this->lookup[ $class_name ] ) ) {
200
- return null;
201
- }
202
-
203
- return $this->lookup[ $class_name ]['option'];
204
- }
205
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/config-ui/class-configuration-page.php DELETED
@@ -1,250 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin
6
- */
7
-
8
- /**
9
- * Loads the Yoast configuration wizard.
10
- */
11
- class WPSEO_Configuration_Page {
12
-
13
- /**
14
- * Admin page identifier.
15
- *
16
- * @var string
17
- */
18
- const PAGE_IDENTIFIER = 'wpseo_configurator';
19
-
20
- /**
21
- * Sets the hooks when the user has enough rights and is on the right page.
22
- */
23
- public function set_hooks() {
24
- if ( ! ( $this->is_config_page() && current_user_can( WPSEO_Configuration_Endpoint::CAPABILITY_RETRIEVE ) ) ) {
25
- return;
26
- }
27
-
28
- // Register the page for the wizard.
29
- add_action( 'admin_menu', [ $this, 'add_wizard_page' ] );
30
- add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
31
- add_action( 'admin_init', [ $this, 'render_wizard_page' ] );
32
- }
33
-
34
- /**
35
- * Check if the configuration is finished. If so, just remove the notification.
36
- */
37
- public function catch_configuration_request() {
38
- $configuration_page = filter_input( INPUT_GET, 'configuration' );
39
- $page = filter_input( INPUT_GET, 'page' );
40
-
41
- $this->remove_notification();
42
- $this->remove_notification_option();
43
-
44
- if ( ! ( $configuration_page === 'finished' && ( $page === WPSEO_Admin::PAGE_IDENTIFIER ) ) ) {
45
- return;
46
- }
47
-
48
- wp_safe_redirect( admin_url( 'admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER ) );
49
- exit;
50
- }
51
-
52
- /**
53
- * Registers the page for the wizard.
54
- */
55
- public function add_wizard_page() {
56
- add_dashboard_page( '', '', 'wpseo_manage_options', self::PAGE_IDENTIFIER, '' );
57
- }
58
-
59
- /**
60
- * Renders the wizard page and exits to prevent the WordPress UI from loading.
61
- */
62
- public function render_wizard_page() {
63
- $this->show_wizard();
64
- exit;
65
- }
66
-
67
- /**
68
- * Enqueues the assets needed for the wizard.
69
- */
70
- public function enqueue_assets() {
71
- wp_enqueue_media();
72
-
73
- if ( ! wp_script_is( 'wp-element', 'registered' ) && function_exists( 'gutenberg_register_scripts_and_styles' ) ) {
74
- gutenberg_register_scripts_and_styles();
75
- }
76
-
77
- /*
78
- * Print the `forms.css` WP stylesheet before any Yoast style, this way
79
- * it's easier to override selectors with the same specificity later.
80
- */
81
- wp_enqueue_style( 'forms' );
82
- $asset_manager = new WPSEO_Admin_Asset_Manager();
83
- $asset_manager->register_assets();
84
- $asset_manager->enqueue_script( 'configuration-wizard' );
85
- $asset_manager->enqueue_style( 'yoast-components' );
86
-
87
- $config = $this->get_config();
88
-
89
- $asset_manager->localize_script( 'configuration-wizard', 'yoastWizardConfig', $config );
90
-
91
- $yoast_components_l10n = new WPSEO_Admin_Asset_Yoast_Components_L10n();
92
- $yoast_components_l10n->localize_script( 'configuration-wizard' );
93
- }
94
-
95
- /**
96
- * Setup Wizard Header.
97
- */
98
- public function show_wizard() {
99
- $this->enqueue_assets();
100
- $dashboard_url = admin_url( '/admin.php?page=wpseo_dashboard' );
101
- $wizard_title = sprintf(
102
- /* translators: %s expands to Yoast SEO. */
103
- __( '%s &rsaquo; Configuration Wizard', 'wordpress-seo' ),
104
- 'Yoast SEO'
105
- );
106
- ?>
107
- <!DOCTYPE html>
108
- <!--[if IE 9]>
109
- <html class="ie9" <?php language_attributes(); ?> >
110
- <![endif]-->
111
- <!--[if !(IE 9) ]><!-->
112
- <html <?php language_attributes(); ?>>
113
- <!--<![endif]-->
114
- <head>
115
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
116
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
117
- <title><?php echo esc_html( $wizard_title ); ?></title>
118
- <?php
119
- wp_print_head_scripts();
120
- wp_print_styles( 'yoast-seo-yoast-components' );
121
-
122
- /**
123
- * Is called before the closing </head> tag in the Yoast Configuration wizard.
124
- *
125
- * Allows users to add their own scripts or styles.
126
- *
127
- * @since 4.0
128
- */
129
- do_action( 'wpseo_configuration_wizard_head' );
130
- ?>
131
- </head>
132
- <body class="wp-admin wp-core-ui">
133
- <div id="wizard"></div>
134
- <div role="contentinfo" class="yoast-wizard-return-link-container">
135
- <a class="button yoast-wizard-return-link" href="<?php echo esc_url( $dashboard_url ); ?>">
136
- <span aria-hidden="true" class="dashicons dashicons-no"></span>
137
- <?php
138
- esc_html_e( 'Close the Wizard', 'wordpress-seo' );
139
- ?>
140
- </a>
141
- </div>
142
- <?php
143
- wp_print_media_templates();
144
- wp_print_footer_scripts();
145
-
146
- /**
147
- * Is called before the closing </body> tag in the Yoast Configuration wizard.
148
- *
149
- * Allows users to add their own scripts.
150
- *
151
- * @since 4.0
152
- */
153
- do_action( 'wpseo_configuration_wizard_footer' );
154
-
155
- wp_print_scripts( 'yoast-seo-configuration-wizard' );
156
- ?>
157
- </body>
158
- </html>
159
- <?php
160
- }
161
-
162
- /**
163
- * Get the API config for the wizard.
164
- *
165
- * @return array The API endpoint config.
166
- */
167
- public function get_config() {
168
- $config = [
169
- 'namespace' => WPSEO_Configuration_Endpoint::REST_NAMESPACE,
170
- 'endpoint_retrieve' => WPSEO_Configuration_Endpoint::ENDPOINT_RETRIEVE,
171
- 'endpoint_store' => WPSEO_Configuration_Endpoint::ENDPOINT_STORE,
172
- 'nonce' => wp_create_nonce( 'wp_rest' ),
173
- 'root' => esc_url_raw( rest_url() ),
174
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
175
- 'finishUrl' => admin_url( 'admin.php?page=wpseo_dashboard&configuration=finished' ),
176
- ];
177
-
178
- return $config;
179
- }
180
-
181
- /**
182
- * Checks if the current page is the configuration page.
183
- *
184
- * @return bool
185
- */
186
- protected function is_config_page() {
187
- return ( filter_input( INPUT_GET, 'page' ) === self::PAGE_IDENTIFIER );
188
- }
189
-
190
- /**
191
- * Adds a notification to the notification center.
192
- */
193
- private function add_notification() {
194
- $notification_center = Yoast_Notification_Center::get();
195
- $notification_center->add_notification( self::get_notification() );
196
- }
197
-
198
- /**
199
- * Removes the notification from the notification center.
200
- */
201
- private function remove_notification() {
202
- $notification_center = Yoast_Notification_Center::get();
203
- $notification_center->remove_notification( self::get_notification() );
204
- }
205
-
206
- /**
207
- * Gets the notification.
208
- *
209
- * @return Yoast_Notification
210
- */
211
- private static function get_notification() {
212
- $message = __( 'The configuration wizard helps you to easily configure your site to have the optimal SEO settings.', 'wordpress-seo' );
213
- $message .= '<br/>';
214
- $message .= sprintf(
215
- /* translators: %1$s resolves to Yoast SEO, %2$s resolves to the starting tag of the link to the wizard, %3$s resolves to the closing link tag */
216
- __( 'We have detected that you have not finished this wizard yet, so we recommend you to %2$sstart the configuration wizard to configure %1$s%3$s.', 'wordpress-seo' ),
217
- 'Yoast SEO',
218
- '<a href="' . admin_url( '?page=' . self::PAGE_IDENTIFIER ) . '">',
219
- '</a>'
220
- );
221
-
222
- $notification = new Yoast_Notification(
223
- $message,
224
- [
225
- 'type' => Yoast_Notification::WARNING,
226
- 'id' => 'wpseo-dismiss-onboarding-notice',
227
- 'capabilities' => 'wpseo_manage_options',
228
- 'priority' => 0.8,
229
- ]
230
- );
231
-
232
- return $notification;
233
- }
234
-
235
- /**
236
- * When the notice should be shown.
237
- *
238
- * @return bool
239
- */
240
- private function should_add_notification() {
241
- return ( WPSEO_Options::get( 'show_onboarding_notice' ) === true );
242
- }
243
-
244
- /**
245
- * Remove the options that triggers the notice for the configuration wizard.
246
- */
247
- private function remove_notification_option() {
248
- WPSEO_Options::set( 'show_onboarding_notice', false );
249
- }
250
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/config-ui/class-configuration-service.php DELETED
@@ -1,182 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin\ConfigurationUI
6
- */
7
-
8
- /**
9
- * Class WPSEO_Configuration_Service.
10
- */
11
- class WPSEO_Configuration_Service {
12
-
13
- /**
14
- * Class holding the onboarding wizard configuration.
15
- *
16
- * @var WPSEO_Configuration_Structure
17
- */
18
- protected $structure;
19
-
20
- /**
21
- * Class holding the onboarding wizard components.
22
- *
23
- * @var WPSEO_Configuration_Components
24
- */
25
- protected $components;
26
-
27
- /**
28
- * Class handling the onboarding wizard persistence.
29
- *
30
- * @var WPSEO_Configuration_Storage
31
- */
32
- protected $storage;
33
-
34
- /**
35
- * Class handling the onboarding wizard endpoint.
36
- *
37
- * @var WPSEO_Configuration_Endpoint
38
- */
39
- protected $endpoint;
40
-
41
- /**
42
- * Adapter that converts onboarding wizard configuration to WordPress options.
43
- *
44
- * @var WPSEO_Configuration_Options_Adapter
45
- */
46
- protected $adapter;
47
-
48
- /**
49
- * Class handling the onboarding wizard endpoint.
50
- *
51
- * @var WPSEO_Configuration_Translations
52
- */
53
- protected $translations;
54
-
55
- /**
56
- * Hook into the REST API and switch language.
57
- */
58
- public function initialize() {
59
- $this->set_default_providers();
60
- $this->endpoint->register();
61
- }
62
-
63
- /**
64
- * Set default handlers.
65
- */
66
- public function set_default_providers() {
67
- $this->set_storage( new WPSEO_Configuration_Storage() );
68
- $this->set_options_adapter( new WPSEO_Configuration_Options_Adapter() );
69
- $this->set_components( new WPSEO_Configuration_Components() );
70
- $this->set_endpoint( new WPSEO_Configuration_Endpoint() );
71
- $this->set_structure( new WPSEO_Configuration_Structure() );
72
- $this->set_translations( new WPSEO_Configuration_Translations( \get_user_locale() ) );
73
- }
74
-
75
- /**
76
- * Set storage handler.
77
- *
78
- * @param WPSEO_Configuration_Storage $storage Storage handler to use.
79
- */
80
- public function set_storage( WPSEO_Configuration_Storage $storage ) {
81
- $this->storage = $storage;
82
- }
83
-
84
- /**
85
- * Set endpoint handler.
86
- *
87
- * @param WPSEO_Configuration_Endpoint $endpoint Endpoint implementation to use.
88
- */
89
- public function set_endpoint( WPSEO_Configuration_Endpoint $endpoint ) {
90
- $this->endpoint = $endpoint;
91
- $this->endpoint->set_service( $this );
92
- }
93
-
94
- /**
95
- * Set the options adapter.
96
- *
97
- * @param WPSEO_Configuration_Options_Adapter $adapter Adapter to use.
98
- */
99
- public function set_options_adapter( WPSEO_Configuration_Options_Adapter $adapter ) {
100
- $this->adapter = $adapter;
101
- }
102
-
103
- /**
104
- * Set components provider.
105
- *
106
- * @param WPSEO_Configuration_Components $components Component provider to use.
107
- */
108
- public function set_components( WPSEO_Configuration_Components $components ) {
109
- $this->components = $components;
110
- }
111
-
112
- /**
113
- * Set structure provider.
114
- *
115
- * @param WPSEO_Configuration_Structure $structure Structure provider to use.
116
- */
117
- public function set_structure( WPSEO_Configuration_Structure $structure ) {
118
- $this->structure = $structure;
119
- }
120
-
121
- /**
122
- * Sets the translations object.
123
- *
124
- * @param WPSEO_Configuration_Translations $translations The translations object.
125
- */
126
- public function set_translations( WPSEO_Configuration_Translations $translations ) {
127
- $this->translations = $translations;
128
- }
129
-
130
- /**
131
- * Populate the configuration.
132
- */
133
- protected function populate_configuration() {
134
- // Switch to the user locale with fallback to the site locale.
135
- switch_to_locale( \get_user_locale() );
136
-
137
- // Make sure we have our translations available.
138
- wpseo_load_textdomain();
139
-
140
- $this->structure->initialize();
141
-
142
- $this->storage->set_adapter( $this->adapter );
143
- $this->storage->add_default_fields();
144
-
145
- $this->components->initialize();
146
- $this->components->set_storage( $this->storage );
147
-
148
- // @todo: check if this is really needed, since the switch happens only in the API.
149
- restore_current_locale();
150
- }
151
-
152
- /**
153
- * Used by endpoint to retrieve configuration.
154
- *
155
- * @return array List of settings.
156
- */
157
- public function get_configuration() {
158
- $this->populate_configuration();
159
- $fields = $this->storage->retrieve();
160
- $steps = $this->structure->retrieve();
161
- $translations = $this->translations->retrieve();
162
-
163
- return [
164
- 'fields' => $fields,
165
- 'steps' => $steps,
166
- 'translations' => $translations,
167
- ];
168
- }
169
-
170
- /**
171
- * Used by endpoint to store changes.
172
- *
173
- * @param WP_REST_Request $request Request from the REST API.
174
- *
175
- * @return array List of feedback per option if saving succeeded.
176
- */
177
- public function set_configuration( WP_REST_Request $request ) {
178
- $this->populate_configuration();
179
-
180
- return $this->storage->store( $request->get_json_params() );
181
- }
182
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/config-ui/class-configuration-storage.php DELETED
@@ -1,205 +0,0 @@
1
- <?php
2
- /**
3
- * WPSEO plugin file.
4
- *
5
- * @package WPSEO\Admin\ConfigurationUI
6
- */
7
-
8
- /**
9
- * Class WPSEO_Configuration_Storage.
10
- */
11
- class WPSEO_Configuration_Storage {
12
-
13
- /**
14
- * Holds the configuration options adapter.
15
- *
16
- * @var \WPSEO_Configuration_Options_Adapter
17
- */
18
- protected $adapter;
19
-
20
- /**
21
- * Holds the configuration fields.
22
- *
23
- * @var \WPSEO_Config_Field[]
24
- */
25
- protected $fields = [];
26
-
27
- /**
28
- * Add default fields.
29
- */
30
- public function add_default_fields() {
31
- $fields = [
32
- new WPSEO_Config_Field_Success_Message(),
33
- new WPSEO_Config_Field_Mailchimp_Signup(),
34
- new WPSEO_Config_Field_Environment(),
35
- new WPSEO_Config_Field_Site_Type(),
36
- new WPSEO_Config_Field_Multiple_Authors(),
37
- new WPSEO_Config_Field_Title_Intro(),
38
- new WPSEO_Config_Field_Site_Name(),
39
- new WPSEO_Config_Field_Separator(),
40
- new WPSEO_Config_Field_Profile_URL_Facebook(),
41
- new WPSEO_Config_Field_Profile_URL_Twitter(),
42
- new WPSEO_Config_Field_Profile_URL_Instagram(),
43