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 | Yoast SEO |
Version | 17.8 |
Comparing to | |
See all releases |
Code changes from version 17.7.1 to 17.8
- admin/class-admin-asset-manager.php +15 -1
- admin/class-admin.php +18 -12
- admin/class-config.php +0 -1
- admin/class-expose-shortlinks.php +1 -0
- admin/class-gutenberg-compatibility.php +2 -2
- admin/class-plugin-conflict.php +11 -89
- admin/class-yoast-dashboard-widget.php +22 -4
- admin/class-yoast-plugin-conflict.php +36 -30
- admin/config-ui/class-configuration-components.php +0 -79
- admin/config-ui/class-configuration-endpoint.php +0 -102
- admin/config-ui/class-configuration-options-adapter.php +0 -205
- admin/config-ui/class-configuration-page.php +0 -250
- admin/config-ui/class-configuration-service.php +0 -182
- admin/config-ui/class-configuration-storage.php +0 -205
- admin/config-ui/class-configuration-structure.php +0 -123
- admin/config-ui/class-configuration-translations.php +0 -64
- admin/config-ui/components/class-component-mailchimp-signup.php +0 -86
- admin/config-ui/components/class-component-suggestions.php +0 -119
- admin/config-ui/components/interface-component.php +0 -42
- admin/config-ui/factories/class-factory-post-type.php +0 -76
- admin/config-ui/fields/class-field-choice-post-type.php +0 -87
- admin/config-ui/fields/class-field-choice.php +0 -42
- admin/config-ui/fields/class-field-company-info-missing.php +0 -28
- admin/config-ui/fields/class-field-company-logo.php +0 -32
- admin/config-ui/fields/class-field-company-name.php +0 -33
- admin/config-ui/fields/class-field-company-or-person.php +0 -35
- admin/config-ui/fields/class-field-environment.php +0 -91
- admin/config-ui/fields/class-field-mailchimp-signup.php +0 -65
- admin/config-ui/fields/class-field-multiple-authors.php +0 -86
- admin/config-ui/fields/class-field-person.php +0 -32
- admin/config-ui/fields/class-field-post-type-visibility.php +0 -25
- admin/config-ui/fields/class-field-profile-url-facebook.php +0 -33
- admin/config-ui/fields/class-field-profile-url-instagram.php +0 -33
- admin/config-ui/fields/class-field-profile-url-linkedin.php +0 -33
- admin/config-ui/fields/class-field-profile-url-myspace.php +0 -33
- admin/config-ui/fields/class-field-profile-url-pinterest.php +0 -33
- admin/config-ui/fields/class-field-profile-url-twitter.php +0 -32
- admin/config-ui/fields/class-field-profile-url-wikipedia.php +0 -35
- admin/config-ui/fields/class-field-profile-url-youtube.php +0 -33
- admin/config-ui/fields/class-field-separator.php +0 -43
- admin/config-ui/fields/class-field-site-name.php +0 -60
- admin/config-ui/fields/class-field-site-type.php +0 -39
- admin/config-ui/fields/class-field-success-message.php +0 -38
- admin/config-ui/fields/class-field-suggestions.php +0 -43
- admin/config-ui/fields/class-field-title-intro.php +0 -25
- admin/config-ui/fields/class-field-tracking-intro.php +0 -25
- admin/config-ui/fields/class-field-tracking.php +0 -66
- admin/config-ui/fields/class-field.php +0 -157
- admin/formatter/class-metabox-formatter.php +16 -2
- admin/formatter/class-term-metabox-formatter.php +1 -0
- admin/menu/class-menu.php +0 -4
- admin/metabox/class-metabox.php +5 -0
- admin/notifiers/class-configuration-notifier.php +0 -176
- admin/tracking/class-tracking-settings-data.php +6 -0
- admin/views/class-yoast-integration-toggles.php +37 -0
- admin/views/sidebar.php +1 -8
- admin/views/tabs/metas/paper-content/integrations/wincher.php +126 -0
- css/dist/admin-global-1771-rtl.css +0 -1
- css/dist/admin-global-1771.css +0 -1
- css/dist/admin-global-1780-rtl.css +1 -0
- css/dist/admin-global-1780.css +1 -0
- css/dist/{adminbar-1771-rtl.css → adminbar-1780-rtl.css} +0 -0
- css/dist/{adminbar-1771.css → adminbar-1780.css} +0 -0
- css/dist/{alerts-1771-rtl.css → alerts-1780-rtl.css} +0 -0
- css/dist/{alerts-1771.css → alerts-1780.css} +0 -0
- css/dist/dashboard-1771-rtl.css +0 -1
- css/dist/dashboard-1771.css +0 -1
- css/dist/dashboard-1780-rtl.css +1 -0
- css/dist/dashboard-1780.css +1 -0
- css/dist/{edit-page-1771-rtl.css → edit-page-1780-rtl.css} +0 -0
- css/dist/{edit-page-1771.css → edit-page-1780.css} +0 -0
- css/dist/{elementor-1771-rtl.css → elementor-1780-rtl.css} +1 -1
- css/dist/{elementor-1771.css → elementor-1780.css} +1 -1
- css/dist/{featured-image-1771-rtl.css → featured-image-1780-rtl.css} +0 -0
- css/dist/{featured-image-1771.css → featured-image-1780.css} +0 -0
- css/dist/{filter-explanation-1771-rtl.css → filter-explanation-1780-rtl.css} +0 -0
- css/dist/{filter-explanation-1771.css → filter-explanation-1780.css} +0 -0
- css/dist/{icons-1771-rtl.css → icons-1780-rtl.css} +1 -1
- css/dist/{icons-1771.css → icons-1780.css} +1 -1
- css/dist/{inside-editor-1771-rtl.css → inside-editor-1780-rtl.css} +0 -0
- css/dist/{inside-editor-1771.css → inside-editor-1780.css} +0 -0
- css/dist/metabox-1771-rtl.css +0 -1
- css/dist/metabox-1780-rtl.css +1 -0
- css/dist/{metabox-1771.css → metabox-1780.css} +1 -1
- css/dist/{metabox-primary-category-1771-rtl.css → metabox-primary-category-1780-rtl.css} +0 -0
- css/dist/{metabox-primary-category-1771.css → metabox-primary-category-1780.css} +0 -0
- css/dist/{modal-1771-rtl.css → modal-1780-rtl.css} +1 -1
- css/dist/{modal-1771.css → modal-1780.css} +1 -1
- css/dist/{monorepo-1771-rtl.css → monorepo-1780-rtl.css} +1 -1
- css/dist/{monorepo-1771.css → monorepo-1780.css} +1 -1
- css/dist/notifications-1771-rtl.css +0 -1
- css/dist/notifications-1771.css +0 -1
- css/dist/notifications-1780-rtl.css +1 -0
- css/dist/notifications-1780.css +1 -0
- css/dist/{schema-blocks-1771-rtl.css → schema-blocks-1780-rtl.css} +0 -0
- css/dist/{schema-blocks-1771.css → schema-blocks-1780.css} +0 -0
- css/dist/{score_icon-1771-rtl.css → score_icon-1780-rtl.css} +0 -0
- css/dist/{score_icon-1771.css → score_icon-1780.css} +0 -0
- css/dist/{search-appearance-1771-rtl.css → search-appearance-1780-rtl.css} +0 -0
- css/dist/{search-appearance-1771.css → search-appearance-1780.css} +0 -0
- css/dist/{structured-data-blocks-1771-rtl.css → structured-data-blocks-1780-rtl.css} +0 -0
- css/dist/{structured-data-blocks-1771.css → structured-data-blocks-1780.css} +0 -0
- css/dist/{toggle-switch-1771-rtl.css → toggle-switch-1780-rtl.css} +0 -0
- css/dist/{toggle-switch-1771.css → toggle-switch-1780.css} +0 -0
- css/dist/workouts-1771-rtl.css +0 -1
- css/dist/workouts-1771.css +0 -1
- css/dist/workouts-1780-rtl.css +1 -0
- css/dist/workouts-1780.css +1 -0
- css/dist/{wpseo-dismissible-1771-rtl.css → wpseo-dismissible-1780-rtl.css} +0 -0
- css/dist/{wpseo-dismissible-1771.css → wpseo-dismissible-1780.css} +0 -0
- css/dist/{yoast-components-1771-rtl.css → yoast-components-1780-rtl.css} +0 -0
- css/dist/{yoast-components-1771.css → yoast-components-1780.css} +0 -0
- css/dist/yoast-extensions-1771-rtl.css +0 -1
- css/dist/yoast-extensions-1771.css +0 -1
- css/dist/yoast-extensions-1780-rtl.css +1 -0
- css/dist/yoast-extensions-1780.css +1 -0
- css/dist/yst_plugin_tools-1771-rtl.css +0 -1
- css/dist/yst_plugin_tools-1771.css +0 -1
- css/dist/yst_plugin_tools-1780-rtl.css +1 -0
- css/dist/yst_plugin_tools-1780.css +1 -0
- css/dist/{yst_seo_score-1771-rtl.css → yst_seo_score-1780-rtl.css} +0 -0
- css/dist/{yst_seo_score-1771.css → yst_seo_score-1780.css} +0 -0
- images/question-mark.png +0 -0
- inc/class-wpseo-meta.php +5 -5
- inc/options/class-wpseo-option-ms.php +1 -0
- inc/options/class-wpseo-option-wpseo.php +7 -0
- inc/wpseo-functions.php +12 -12
- js/dist/{addon-installation-1771.js → addon-installation-1780.js} +2 -2
- js/dist/admin-global-1771.js +0 -1
- js/dist/admin-global-1780.js +1 -0
- js/dist/admin-modules-1771.js +0 -4
- js/dist/admin-modules-1780.js +4 -0
- js/dist/{analysis-worker-1771.js → analysis-worker-1780.js} +1 -1
- js/dist/{api-client-1771.js → api-client-1780.js} +1 -1
- 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' => [
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
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
|
19 |
|
20 |
/**
|
21 |
* The minimally supported version of Gutenberg by the plugin.
|
22 |
*
|
23 |
* @var string
|
24 |
*/
|
25 |
-
const MINIMUM_SUPPORTED = '12.0
|
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 |
-
|
25 |
-
|
26 |
-
|
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'
|
122 |
/* translators: %1$s resolves to Yoast.com */
|
123 |
__( 'Latest blog posts on %1$s', 'wordpress-seo' ),
|
124 |
'Yoast.com'
|
125 |
),
|
126 |
-
'feed_footer'
|
127 |
-
'wp_version'
|
128 |
-
'php_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 $
|
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->
|
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->
|
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( ' & ', $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->
|
179 |
-
$inactive_plugins = array_diff( $this->plugins[ $section ], $this->
|
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->
|
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 |
-
|
283 |
-
$this->active_plugins[ $plugin_section ] = [];
|
284 |
}
|
285 |
|
286 |
-
if ( ! in_array( $plugin, $this->
|
287 |
-
$this->
|
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( ' & ', $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 › 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 |