Version Description
Release Date: September 29th, 2020
Today, were launching Yoast SEO 15.0. This release features some awesome new additions and enhancements. Weve added full support for Arabic and made the Yoast SEO block editor sidebar fully-featured. Read more about those changes in our release post!
Enhancements:
- Introduces an advanced settings tab in the sidebar.
- Introduces buttons in the sidebar to open the Facebook and Twitter Preview in a modal.
- Changes the Google Preview modal styling to match the other new modals.
- Always shows the Google Preview editor fields and as a result removes the 'Edit snippet' button.
- Changes the styling of the Yoast SEO sidebar to match the standard Gutenberg styling.
- Slightly rearranges the order of items in the Yoast SEO sidebar.
- Adds a hover state styling to the items in the Metabox.
- Improves the English transition word assessment by adding the following words to the transition word list: 'note that', 'not only', 'initially', 'as opposed to'.
- Improves the keyphrase and prominent word recognition when words in the text occur with specific Arabic or Urdu punctuation marks.
Bugfixes:
- Fixes a bug where the value of the schema
@type
could containnull
. - Fixes a bug where the
archive
,imageindex
andsnippet
robot values would be output whennoindex
was present as well. - Fixes a bug where the indexable permalinks could have an incorrect value when the term slug was changed.
- Fixes a bug where parts of the content of a password protected post could be output in the schema.
- Fixes a bug where the 'Stop counting' button in the text link counter modal wouldn't stop the counting of links.
- Fixes a bug where indexable hierarchies were not being created during bulk indexing.
Other:
- Adds the
wpseo_sitemap_index_links
filter to enable adding links to the sitemap index. Props to Joseph Paul.
Download this release
Release Info
Developer | Yoast |
Plugin | Yoast SEO |
Version | 15.0 |
Comparing to | |
See all releases |
Code changes from version 14.9 to 15.0
- admin/class-admin-init.php +25 -24
- admin/class-admin.php +2 -2
- admin/class-bulk-description-editor-list-table.php +1 -1
- admin/class-bulk-editor-list-table.php +0 -1
- admin/class-gutenberg-compatibility.php +2 -2
- admin/class-meta-columns.php +6 -2
- admin/class-my-yoast-route.php +0 -317
- admin/class-premium-upsell-admin-block.php +4 -2
- admin/class-yoast-network-admin.php +6 -3
- admin/class-yoast-notification-center.php +3 -3
- admin/config-ui/class-configuration-structure.php +1 -0
- admin/config-ui/fields/class-field-tracking.php +4 -4
- admin/endpoints/class-endpoint-indexable.php +0 -102
- admin/endpoints/interface-endpoint-storable.php +0 -19
- admin/import/plugins/class-abstract-plugin-importer.php +3 -2
- admin/metabox/class-metabox.php +115 -161
- admin/roles/class-role-manager-wp.php +0 -1
- admin/services/class-indexable-post-provider.php +0 -232
- admin/services/class-indexable-provider.php +0 -38
- admin/services/class-indexable-term-provider.php +0 -168
- admin/services/class-indexable.php +0 -97
- admin/services/interface-indexable-provider.php +0 -42
- admin/taxonomy/class-taxonomy-content-fields.php +0 -66
- admin/taxonomy/class-taxonomy-fields.php +178 -25
- admin/taxonomy/class-taxonomy-metabox.php +78 -102
- admin/taxonomy/class-taxonomy-settings-fields.php +0 -51
- admin/taxonomy/class-taxonomy-social-fields.php +0 -152
- admin/tracking/class-tracking-server-data.php +0 -1
- admin/views/class-yoast-feature-toggle.php +7 -0
- admin/views/class-yoast-feature-toggles.php +21 -0
- admin/views/paper-collapsible.php +3 -4
- admin/views/partial-notifications-template.php +4 -4
- admin/views/sidebar.php +1 -1
- admin/views/tabs/dashboard/dashboard.php +4 -1
- admin/views/tabs/dashboard/features.php +4 -1
- admin/views/tabs/dashboard/webmaster-tools.php +3 -1
- admin/views/tabs/metas/archives.php +1 -0
- admin/views/tabs/metas/archives/help.php +3 -0
- admin/views/tabs/metas/breadcrumbs.php +2 -0
- admin/views/tabs/metas/general.php +1 -0
- admin/views/tabs/metas/media.php +1 -0
- admin/views/tabs/metas/paper-content/general/homepage.php +2 -0
- admin/views/tabs/metas/paper-content/general/knowledge-graph.php +8 -2
- admin/views/tabs/metas/paper-content/general/title-separator.php +7 -1
- admin/views/tabs/metas/paper-content/media-content.php +1 -0
- admin/views/tabs/metas/paper-content/post_type/post-type.php +1 -1
- admin/views/tabs/metas/paper-content/post_type/woocommerce-shop-page.php +1 -1
- admin/views/tabs/metas/paper-content/rss-content.php +2 -0
- admin/views/tabs/metas/post-types.php +1 -0
- admin/views/tabs/metas/rss.php +1 -0
- admin/views/tabs/metas/taxonomies.php +2 -0
- admin/views/tabs/network/features.php +0 -1
- admin/views/tabs/social/accounts.php +2 -0
- admin/views/tabs/social/facebook.php +9 -3
- admin/views/tool-bulk-editor.php +1 -1
- admin/views/tool-file-editor.php +0 -1
- css/dist/{admin-global-1490-rtl.css → admin-global-1500-rtl.css} +0 -0
- css/dist/{admin-global-1490.css → admin-global-1500.css} +0 -0
- css/dist/{adminbar-1490-rtl.css → adminbar-1500-rtl.css} +0 -0
- css/dist/{adminbar-1490.css → adminbar-1500.css} +0 -0
- css/dist/{alerts-1490-rtl.css → alerts-1500-rtl.css} +0 -0
- css/dist/{alerts-1490.css → alerts-1500.css} +0 -0
- css/dist/{dashboard-1490-rtl.css → dashboard-1500-rtl.css} +0 -0
- css/dist/{dashboard-1490.css → dashboard-1500.css} +0 -0
- css/dist/{edit-page-1490-rtl.css → edit-page-1500-rtl.css} +0 -0
- css/dist/{edit-page-1490.css → edit-page-1500.css} +0 -0
- css/dist/{featured-image-1490-rtl.css → featured-image-1500-rtl.css} +0 -0
- css/dist/{featured-image-1490.css → featured-image-1500.css} +0 -0
- css/dist/{filter-explanation-1490-rtl.css → filter-explanation-1500-rtl.css} +0 -0
- css/dist/{filter-explanation-1490.css → filter-explanation-1500.css} +0 -0
- css/dist/{icons-1490-rtl.css → icons-1500-rtl.css} +0 -0
- css/dist/{icons-1490.css → icons-1500.css} +0 -0
- css/dist/{inside-editor-1490-rtl.css → inside-editor-1500-rtl.css} +0 -0
- css/dist/{inside-editor-1490.css → inside-editor-1500.css} +0 -0
- css/dist/metabox-1490-rtl.css +0 -1
- css/dist/metabox-1500-rtl.css +1 -0
- css/dist/{metabox-1490.css → metabox-1500.css} +2 -2
- css/dist/{metabox-primary-category-1490-rtl.css → metabox-primary-category-1500-rtl.css} +0 -0
- css/dist/{metabox-primary-category-1490.css → metabox-primary-category-1500.css} +0 -0
- css/dist/modal-1490-rtl.css +0 -1
- css/dist/modal-1490.css +0 -1
- css/dist/modal-1500-rtl.css +1 -0
- css/dist/modal-1500.css +1 -0
- css/dist/monorepo-1490-rtl.css +0 -1
- css/dist/monorepo-1490.css +0 -1
- css/dist/monorepo-1500-rtl.css +1 -0
- css/dist/monorepo-1500.css +1 -0
- css/dist/{notifications-1490-rtl.css → notifications-1500-rtl.css} +0 -0
- css/dist/{notifications-1490.css → notifications-1500.css} +0 -0
- css/dist/{score_icon-1490-rtl.css → score_icon-1500-rtl.css} +0 -0
- css/dist/{score_icon-1490.css → score_icon-1500.css} +0 -0
- css/dist/{search-appearance-1490-rtl.css → search-appearance-1500-rtl.css} +0 -0
- css/dist/{search-appearance-1490.css → search-appearance-1500.css} +0 -0
- css/dist/{structured-data-blocks-1490-rtl.css → structured-data-blocks-1500-rtl.css} +0 -0
- css/dist/{structured-data-blocks-1490.css → structured-data-blocks-1500.css} +0 -0
- css/dist/{toggle-switch-1490-rtl.css → toggle-switch-1500-rtl.css} +0 -0
- css/dist/{toggle-switch-1490.css → toggle-switch-1500.css} +0 -0
- css/dist/{wpseo-dismissible-1490-rtl.css → wpseo-dismissible-1500-rtl.css} +0 -0
- css/dist/{wpseo-dismissible-1490.css → wpseo-dismissible-1500.css} +0 -0
- css/dist/{yoast-components-1490-rtl.css → yoast-components-1500-rtl.css} +0 -0
- css/dist/{yoast-components-1490.css → yoast-components-1500.css} +0 -0
- css/dist/{yoast-extensions-1490-rtl.css → yoast-extensions-1500-rtl.css} +0 -0
- css/dist/{yoast-extensions-1490.css → yoast-extensions-1500.css} +0 -0
- css/dist/{yst_plugin_tools-1490-rtl.css → yst_plugin_tools-1500-rtl.css} +0 -0
- css/dist/{yst_plugin_tools-1490.css → yst_plugin_tools-1500.css} +0 -0
- css/dist/{yst_seo_score-1490-rtl.css → yst_seo_score-1500-rtl.css} +0 -0
- css/dist/{yst_seo_score-1490.css → yst_seo_score-1500.css} +0 -0
- css/src/metabox.css +46 -0
- css/src/modal.css +97 -23
- inc/class-addon-manager.php +93 -7
- inc/class-my-yoast-api-request.php +1 -158
- inc/class-upgrade.php +2 -0
- inc/class-wpseo-image-utils.php +2 -2
- inc/class-wpseo-utils.php +25 -18
- inc/endpoints/class-myyoast-connect.php +0 -140
- inc/health-check-default-tagline.php +1 -2
- inc/indexables/class-indexable.php +0 -130
- inc/indexables/class-object-type.php +0 -113
- inc/indexables/class-post-indexable.php +0 -98
- inc/indexables/class-post-object-type.php +0 -31
- inc/indexables/class-term-indexable.php +0 -126
- inc/indexables/class-term-object-type.php +0 -31
- inc/indexables/validators/class-endpoint-validator.php +0 -21
- inc/indexables/validators/class-keyword-validator.php +0 -29
- inc/indexables/validators/class-link-validator.php +0 -29
- inc/indexables/validators/class-meta-values-validator.php +0 -51
- inc/indexables/validators/class-object-type-validator.php +0 -66
- inc/indexables/validators/class-opengraph-validator.php +0 -35
- inc/indexables/validators/class-robots-validator.php +0 -46
- inc/indexables/validators/class-twitter-validator.php +0 -35
- inc/options/class-wpseo-option-wpseo.php +1 -1
- inc/options/class-wpseo-option.php +22 -16
- inc/options/class-wpseo-options.php +2 -0
- inc/sitemaps/class-sitemaps.php +7 -0
- inc/wpseo-functions.php +64 -0
- js/dist/{admin-global-1490.js → admin-global-1500.js} +1 -1
- js/dist/analysis-1490.js +0 -21
admin/class-admin-init.php
CHANGED
@@ -139,7 +139,7 @@ class WPSEO_Admin_Init {
|
|
139 |
public function yoast_plugin_update_notification() {
|
140 |
$notification_center = Yoast_Notification_Center::get();
|
141 |
$current_minor_version = $this->get_major_minor_version( WPSEO_Options::get( 'version', WPSEO_VERSION ) );
|
142 |
-
$file
|
143 |
|
144 |
// Remove if file is not present.
|
145 |
if ( ! file_exists( $file ) ) {
|
@@ -147,7 +147,9 @@ class WPSEO_Admin_Init {
|
|
147 |
return;
|
148 |
}
|
149 |
|
|
|
150 |
$release_json = file_get_contents( $file );
|
|
|
151 |
/**
|
152 |
* Filter: 'wpseo_update_notice_content' - Allow filtering of the content
|
153 |
* of the update notice read from the release-info.json file.
|
@@ -160,7 +162,7 @@ class WPSEO_Admin_Init {
|
|
160 |
if ( is_null( $release_info )
|
161 |
|| empty( $release_info->version )
|
162 |
|| version_compare( $this->get_major_minor_version( $release_info->version ), $current_minor_version, '!=' )
|
163 |
-
|
164 |
) {
|
165 |
$notification_center->remove_notification_by_id( 'wpseo-plugin-updated' );
|
166 |
return;
|
@@ -171,7 +173,7 @@ class WPSEO_Admin_Init {
|
|
171 |
// Restore notification if it was dismissed in a previous minor version.
|
172 |
$last_dismissed_version = get_user_option( $notification->get_dismissal_key() );
|
173 |
if ( ! $last_dismissed_version
|
174 |
-
|
175 |
) {
|
176 |
Yoast_Notification_Center::restore_notification( $notification );
|
177 |
}
|
@@ -197,25 +199,25 @@ class WPSEO_Admin_Init {
|
|
197 |
* @return Yoast_Notification The notification for the present version
|
198 |
*/
|
199 |
private function get_yoast_seo_update_notification( $release_info ) {
|
200 |
-
$info_message
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
|
210 |
if ( ! empty( $release_info->shortlink ) ) {
|
211 |
-
$link
|
212 |
-
$info_message .= ' <a href="' . esc_url( $link ) . '" target="_blank">'
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
}
|
220 |
|
221 |
return new Yoast_Notification(
|
@@ -463,13 +465,13 @@ class WPSEO_Admin_Init {
|
|
463 |
// Show notice for each deprecated filter or action that has been registered.
|
464 |
foreach ( $deprecated_notices as $deprecated_filter ) {
|
465 |
$deprecation_info = $deprecated_filters[ $deprecated_filter ];
|
466 |
-
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped --
|
467 |
_deprecated_hook(
|
468 |
$deprecated_filter,
|
469 |
'WPSEO ' . $deprecation_info['version'],
|
470 |
$deprecation_info['alternative']
|
471 |
);
|
472 |
-
// phpcs:enable
|
473 |
}
|
474 |
}
|
475 |
|
@@ -636,8 +638,7 @@ class WPSEO_Admin_Init {
|
|
636 |
$blog_description = get_bloginfo( 'description' );
|
637 |
$default_blog_description = 'Just another WordPress site';
|
638 |
|
639 |
-
// We are
|
640 |
-
// @codingStandardsIgnoreLine
|
641 |
$translated_blog_description = __( 'Just another WordPress site', 'default' );
|
642 |
|
643 |
return $translated_blog_description === $blog_description || $default_blog_description === $blog_description;
|
139 |
public function yoast_plugin_update_notification() {
|
140 |
$notification_center = Yoast_Notification_Center::get();
|
141 |
$current_minor_version = $this->get_major_minor_version( WPSEO_Options::get( 'version', WPSEO_VERSION ) );
|
142 |
+
$file = plugin_dir_path( WPSEO_FILE ) . 'release-info.json';
|
143 |
|
144 |
// Remove if file is not present.
|
145 |
if ( ! file_exists( $file ) ) {
|
147 |
return;
|
148 |
}
|
149 |
|
150 |
+
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Retrieving a local file.
|
151 |
$release_json = file_get_contents( $file );
|
152 |
+
|
153 |
/**
|
154 |
* Filter: 'wpseo_update_notice_content' - Allow filtering of the content
|
155 |
* of the update notice read from the release-info.json file.
|
162 |
if ( is_null( $release_info )
|
163 |
|| empty( $release_info->version )
|
164 |
|| version_compare( $this->get_major_minor_version( $release_info->version ), $current_minor_version, '!=' )
|
165 |
+
|| empty( $release_info->release_description )
|
166 |
) {
|
167 |
$notification_center->remove_notification_by_id( 'wpseo-plugin-updated' );
|
168 |
return;
|
173 |
// Restore notification if it was dismissed in a previous minor version.
|
174 |
$last_dismissed_version = get_user_option( $notification->get_dismissal_key() );
|
175 |
if ( ! $last_dismissed_version
|
176 |
+
|| version_compare( $this->get_major_minor_version( $last_dismissed_version ), $current_minor_version, '<' )
|
177 |
) {
|
178 |
Yoast_Notification_Center::restore_notification( $notification );
|
179 |
}
|
199 |
* @return Yoast_Notification The notification for the present version
|
200 |
*/
|
201 |
private function get_yoast_seo_update_notification( $release_info ) {
|
202 |
+
$info_message = '<strong>';
|
203 |
+
$info_message .= sprintf(
|
204 |
+
/* translators: %1$s expands to Yoast SEO, %2$s expands to the plugin version. */
|
205 |
+
__( 'New in %1$s %2$s: ', 'wordpress-seo' ),
|
206 |
+
'Yoast SEO',
|
207 |
+
$release_info->version
|
208 |
+
);
|
209 |
+
$info_message .= '</strong>';
|
210 |
+
$info_message .= $release_info->release_description;
|
211 |
|
212 |
if ( ! empty( $release_info->shortlink ) ) {
|
213 |
+
$link = esc_url( WPSEO_Shortlinker::get( $release_info->shortlink ) );
|
214 |
+
$info_message .= ' <a href="' . esc_url( $link ) . '" target="_blank">';
|
215 |
+
$info_message .= sprintf(
|
216 |
+
/* translators: %s expands to the plugin version. */
|
217 |
+
__( 'Read all about version %s here', 'wordpress-seo' ),
|
218 |
+
$release_info->version
|
219 |
+
);
|
220 |
+
$info_message .= '</a>';
|
221 |
}
|
222 |
|
223 |
return new Yoast_Notification(
|
465 |
// Show notice for each deprecated filter or action that has been registered.
|
466 |
foreach ( $deprecated_notices as $deprecated_filter ) {
|
467 |
$deprecation_info = $deprecated_filters[ $deprecated_filter ];
|
468 |
+
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Only uses the hardcoded values from above.
|
469 |
_deprecated_hook(
|
470 |
$deprecated_filter,
|
471 |
'WPSEO ' . $deprecation_info['version'],
|
472 |
$deprecation_info['alternative']
|
473 |
);
|
474 |
+
// phpcs:enable
|
475 |
}
|
476 |
}
|
477 |
|
638 |
$blog_description = get_bloginfo( 'description' );
|
639 |
$default_blog_description = 'Just another WordPress site';
|
640 |
|
641 |
+
// We are using the WordPress internal translation.
|
|
|
642 |
$translated_blog_description = __( 'Just another WordPress site', 'default' );
|
643 |
|
644 |
return $translated_blog_description === $blog_description || $default_blog_description === $blog_description;
|
admin/class-admin.php
CHANGED
@@ -104,7 +104,6 @@ class WPSEO_Admin {
|
|
104 |
$integrations[] = new WPSEO_Admin_Gutenberg_Compatibility_Notification();
|
105 |
$integrations[] = new WPSEO_Expose_Shortlinks();
|
106 |
$integrations[] = new WPSEO_MyYoast_Proxy();
|
107 |
-
$integrations[] = new WPSEO_MyYoast_Route();
|
108 |
$integrations[] = new WPSEO_Schema_Person_Upgrade_Notification();
|
109 |
$integrations[] = new WPSEO_Tracking( 'https://tracking.yoast.com/stats', ( WEEK_IN_SECONDS * 2 ) );
|
110 |
$integrations[] = new WPSEO_Admin_Settings_Changed_Listener();
|
@@ -170,7 +169,8 @@ class WPSEO_Admin {
|
|
170 |
* Maps the manage_options cap on saving an options page to wpseo_manage_options.
|
171 |
*/
|
172 |
public function map_manage_options_cap() {
|
173 |
-
|
|
|
174 |
|
175 |
if ( strpos( $option_page, 'yoast_wpseo' ) === 0 ) {
|
176 |
add_filter( 'option_page_capability_' . $option_page, [ $this, 'get_manage_options_cap' ] );
|
104 |
$integrations[] = new WPSEO_Admin_Gutenberg_Compatibility_Notification();
|
105 |
$integrations[] = new WPSEO_Expose_Shortlinks();
|
106 |
$integrations[] = new WPSEO_MyYoast_Proxy();
|
|
|
107 |
$integrations[] = new WPSEO_Schema_Person_Upgrade_Notification();
|
108 |
$integrations[] = new WPSEO_Tracking( 'https://tracking.yoast.com/stats', ( WEEK_IN_SECONDS * 2 ) );
|
109 |
$integrations[] = new WPSEO_Admin_Settings_Changed_Listener();
|
169 |
* Maps the manage_options cap on saving an options page to wpseo_manage_options.
|
170 |
*/
|
171 |
public function map_manage_options_cap() {
|
172 |
+
// phpcs:ignore WordPress.Security -- The variable is only used in strpos and thus safe to not unslash or sanitize.
|
173 |
+
$option_page = ! empty( $_POST['option_page'] ) ? $_POST['option_page'] : '';
|
174 |
|
175 |
if ( strpos( $option_page, 'yoast_wpseo' ) === 0 ) {
|
176 |
add_filter( 'option_page_capability_' . $option_page, [ $this, 'get_manage_options_cap' ] );
|
admin/class-bulk-description-editor-list-table.php
CHANGED
@@ -72,7 +72,7 @@ class WPSEO_Bulk_Description_List_Table extends WPSEO_Bulk_List_Table {
|
|
72 |
// @todo Inconsistent return/echo behavior R.
|
73 |
// I traced the escaping of the attributes to WPSEO_Bulk_List_Table::column_attributes. Alexander.
|
74 |
// The output of WPSEO_Bulk_List_Table::parse_meta_data_field is properly escaped.
|
75 |
-
// phpcs:ignore WordPress.Security.EscapeOutput
|
76 |
echo $this->parse_meta_data_field( $record->ID, $attributes );
|
77 |
break;
|
78 |
}
|
72 |
// @todo Inconsistent return/echo behavior R.
|
73 |
// I traced the escaping of the attributes to WPSEO_Bulk_List_Table::column_attributes. Alexander.
|
74 |
// The output of WPSEO_Bulk_List_Table::parse_meta_data_field is properly escaped.
|
75 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
76 |
echo $this->parse_meta_data_field( $record->ID, $attributes );
|
77 |
break;
|
78 |
}
|
admin/class-bulk-editor-list-table.php
CHANGED
@@ -914,7 +914,6 @@ class WPSEO_Bulk_List_Table extends WP_List_Table {
|
|
914 |
$id = "wpseo-existing-$record_id-$this->target_db_field";
|
915 |
|
916 |
// $attributes correctly escaped, verified by Alexander. See WPSEO_Bulk_Description_List_Table::parse_page_specific_column.
|
917 |
-
// phpcs:ignore WordPress.Security.EscapeOutput
|
918 |
return sprintf( '<td %2$s id="%3$s">%1$s</td>', esc_html( $meta_value ), $attributes, esc_attr( $id ) );
|
919 |
}
|
920 |
|
914 |
$id = "wpseo-existing-$record_id-$this->target_db_field";
|
915 |
|
916 |
// $attributes correctly escaped, verified by Alexander. See WPSEO_Bulk_Description_List_Table::parse_page_specific_column.
|
|
|
917 |
return sprintf( '<td %2$s id="%3$s">%1$s</td>', esc_html( $meta_value ), $attributes, esc_attr( $id ) );
|
918 |
}
|
919 |
|
admin/class-gutenberg-compatibility.php
CHANGED
@@ -15,14 +15,14 @@ class WPSEO_Gutenberg_Compatibility {
|
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
-
const CURRENT_RELEASE = '
|
19 |
|
20 |
/**
|
21 |
* The minimally supported version of Gutenberg by the plugin.
|
22 |
*
|
23 |
* @var string
|
24 |
*/
|
25 |
-
const MINIMUM_SUPPORTED = '
|
26 |
|
27 |
/**
|
28 |
* Holds the current version.
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
+
const CURRENT_RELEASE = '9.0.0';
|
19 |
|
20 |
/**
|
21 |
* The minimally supported version of Gutenberg by the plugin.
|
22 |
*
|
23 |
* @var string
|
24 |
*/
|
25 |
+
const MINIMUM_SUPPORTED = '9.0.0';
|
26 |
|
27 |
/**
|
28 |
* Holds the current version.
|
admin/class-meta-columns.php
CHANGED
@@ -117,12 +117,12 @@ class WPSEO_Meta_Columns {
|
|
117 |
|
118 |
switch ( $column_name ) {
|
119 |
case 'wpseo-score':
|
120 |
-
//
|
121 |
echo $this->parse_column_score( $post_id );
|
122 |
return;
|
123 |
|
124 |
case 'wpseo-score-readability':
|
125 |
-
//
|
126 |
echo $this->parse_column_score_readability( $post_id );
|
127 |
return;
|
128 |
|
@@ -221,11 +221,13 @@ class WPSEO_Meta_Columns {
|
|
221 |
echo '<label class="screen-reader-text" for="wpseo-filter">' . esc_html__( 'Filter by SEO Score', 'wordpress-seo' ) . '</label>';
|
222 |
echo '<select name="seo_filter" id="wpseo-filter">';
|
223 |
|
|
|
224 |
echo $this->generate_option( '', __( 'All SEO Scores', 'wordpress-seo' ) );
|
225 |
|
226 |
foreach ( $ranks as $rank ) {
|
227 |
$selected = selected( $this->get_current_seo_filter(), $rank->get_rank(), false );
|
228 |
|
|
|
229 |
echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_label(), $selected );
|
230 |
}
|
231 |
|
@@ -247,11 +249,13 @@ class WPSEO_Meta_Columns {
|
|
247 |
echo '<label class="screen-reader-text" for="wpseo-readability-filter">' . esc_html__( 'Filter by Readability Score', 'wordpress-seo' ) . '</label>';
|
248 |
echo '<select name="readability_filter" id="wpseo-readability-filter">';
|
249 |
|
|
|
250 |
echo $this->generate_option( '', __( 'All Readability Scores', 'wordpress-seo' ) );
|
251 |
|
252 |
foreach ( $ranks as $rank ) {
|
253 |
$selected = selected( $this->get_current_readability_filter(), $rank->get_rank(), false );
|
254 |
|
|
|
255 |
echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_readability_labels(), $selected );
|
256 |
}
|
257 |
|
117 |
|
118 |
switch ( $column_name ) {
|
119 |
case 'wpseo-score':
|
120 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in render_score_indicator() method.
|
121 |
echo $this->parse_column_score( $post_id );
|
122 |
return;
|
123 |
|
124 |
case 'wpseo-score-readability':
|
125 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in render_score_indicator() method.
|
126 |
echo $this->parse_column_score_readability( $post_id );
|
127 |
return;
|
128 |
|
221 |
echo '<label class="screen-reader-text" for="wpseo-filter">' . esc_html__( 'Filter by SEO Score', 'wordpress-seo' ) . '</label>';
|
222 |
echo '<select name="seo_filter" id="wpseo-filter">';
|
223 |
|
224 |
+
// phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
|
225 |
echo $this->generate_option( '', __( 'All SEO Scores', 'wordpress-seo' ) );
|
226 |
|
227 |
foreach ( $ranks as $rank ) {
|
228 |
$selected = selected( $this->get_current_seo_filter(), $rank->get_rank(), false );
|
229 |
|
230 |
+
// phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
|
231 |
echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_label(), $selected );
|
232 |
}
|
233 |
|
249 |
echo '<label class="screen-reader-text" for="wpseo-readability-filter">' . esc_html__( 'Filter by Readability Score', 'wordpress-seo' ) . '</label>';
|
250 |
echo '<select name="readability_filter" id="wpseo-readability-filter">';
|
251 |
|
252 |
+
// phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
|
253 |
echo $this->generate_option( '', __( 'All Readability Scores', 'wordpress-seo' ) );
|
254 |
|
255 |
foreach ( $ranks as $rank ) {
|
256 |
$selected = selected( $this->get_current_readability_filter(), $rank->get_rank(), false );
|
257 |
|
258 |
+
// phpcs:ignore WordPress.Security.EscapeOutput -- Output is correctly escaped in the generate_option() method.
|
259 |
echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_readability_labels(), $selected );
|
260 |
}
|
261 |
|
admin/class-my-yoast-route.php
DELETED
@@ -1,317 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the route for MyYoast.
|
10 |
-
*/
|
11 |
-
class WPSEO_MyYoast_Route implements WPSEO_WordPress_Integration {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* The identifier of the page in the My Yoast route.
|
15 |
-
*
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
const PAGE_IDENTIFIER = 'wpseo_myyoast';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* The instance of the MyYoast client.
|
22 |
-
*
|
23 |
-
* @var WPSEO_MyYoast_Client
|
24 |
-
*/
|
25 |
-
protected $client;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* The actions that are supported.
|
29 |
-
*
|
30 |
-
* Each action should have a method named equally to the action.
|
31 |
-
*
|
32 |
-
* For example:
|
33 |
-
* The connect action is handled by a method named 'connect'.
|
34 |
-
*
|
35 |
-
* @var array
|
36 |
-
*/
|
37 |
-
protected static $allowed_actions = [ 'connect', 'authorize', 'complete' ];
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Sets the hooks when the user has enough rights and is on the right page.
|
41 |
-
*
|
42 |
-
* @return void
|
43 |
-
*/
|
44 |
-
public function register_hooks() {
|
45 |
-
$route = filter_input( INPUT_GET, 'page' );
|
46 |
-
if ( ! ( $this->is_myyoast_route( $route ) && $this->can_access_route() ) ) {
|
47 |
-
return;
|
48 |
-
}
|
49 |
-
|
50 |
-
if ( ! $this->is_valid_action( $this->get_action() ) ) {
|
51 |
-
return;
|
52 |
-
}
|
53 |
-
|
54 |
-
add_action( 'admin_menu', [ $this, 'register_route' ] );
|
55 |
-
add_action( 'admin_init', [ $this, 'handle_route' ] );
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Registers the page for the MyYoast route.
|
60 |
-
*
|
61 |
-
* @codeCoverageIgnore
|
62 |
-
*
|
63 |
-
* @return void
|
64 |
-
*/
|
65 |
-
public function register_route() {
|
66 |
-
add_dashboard_page(
|
67 |
-
'', // Is empty because we don't render a page.
|
68 |
-
'', // Is empty because we don't want a menu item.
|
69 |
-
'wpseo_manage_options',
|
70 |
-
self::PAGE_IDENTIFIER
|
71 |
-
);
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Abstracts the action from the URL and follows the appropriate route.
|
76 |
-
*
|
77 |
-
* @return void
|
78 |
-
*/
|
79 |
-
public function handle_route() {
|
80 |
-
$action = $this->get_action();
|
81 |
-
|
82 |
-
if ( ! $this->is_valid_action( $action ) || ! method_exists( $this, $action ) ) {
|
83 |
-
return;
|
84 |
-
}
|
85 |
-
|
86 |
-
// Dynamically call the method.
|
87 |
-
$this->$action();
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Checks if the current page is the MyYoast route.
|
92 |
-
*
|
93 |
-
* @param string $route The MyYoast route.
|
94 |
-
*
|
95 |
-
* @return bool True when url is the MyYoast route.
|
96 |
-
*/
|
97 |
-
protected function is_myyoast_route( $route ) {
|
98 |
-
return ( $route === self::PAGE_IDENTIFIER );
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Compares an action to a list of allowed actions to see if it is valid.
|
103 |
-
*
|
104 |
-
* @param string $action The action to check.
|
105 |
-
*
|
106 |
-
* @return bool True if the action is valid.
|
107 |
-
*/
|
108 |
-
protected function is_valid_action( $action ) {
|
109 |
-
return in_array( $action, self::$allowed_actions, true );
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Connects to MyYoast and generates a new clientId.
|
114 |
-
*
|
115 |
-
* @return void
|
116 |
-
*/
|
117 |
-
protected function connect() {
|
118 |
-
$client_id = $this->generate_uuid();
|
119 |
-
|
120 |
-
$this->save_client_id( $client_id );
|
121 |
-
|
122 |
-
$this->redirect(
|
123 |
-
'https://my.yoast.com/connect',
|
124 |
-
[
|
125 |
-
'url' => WPSEO_Utils::get_home_url(),
|
126 |
-
'client_id' => $client_id,
|
127 |
-
'extensions' => $this->get_extensions(),
|
128 |
-
'redirect_url' => admin_url( 'admin.php?page=' . self::PAGE_IDENTIFIER . '&action=complete' ),
|
129 |
-
'credentials_url' => rest_url( 'yoast/v1/myyoast/connect' ),
|
130 |
-
'type' => 'wordpress',
|
131 |
-
]
|
132 |
-
);
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* Redirects the user to the oAuth authorization page.
|
137 |
-
*
|
138 |
-
* @return void
|
139 |
-
*/
|
140 |
-
protected function authorize() {
|
141 |
-
$client = $this->get_client();
|
142 |
-
|
143 |
-
if ( ! $client->has_configuration() ) {
|
144 |
-
return;
|
145 |
-
}
|
146 |
-
|
147 |
-
$this->redirect(
|
148 |
-
$client->get_provider()->getAuthorizationUrl()
|
149 |
-
);
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Completes the oAuth connection flow.
|
154 |
-
*
|
155 |
-
* @return void
|
156 |
-
*/
|
157 |
-
protected function complete() {
|
158 |
-
$client = $this->get_client();
|
159 |
-
|
160 |
-
if ( ! $client->has_configuration() ) {
|
161 |
-
return;
|
162 |
-
}
|
163 |
-
|
164 |
-
try {
|
165 |
-
$access_token = $client
|
166 |
-
->get_provider()
|
167 |
-
->getAccessToken(
|
168 |
-
'authorization_code',
|
169 |
-
[
|
170 |
-
'code' => $this->get_authorization_code(),
|
171 |
-
]
|
172 |
-
);
|
173 |
-
|
174 |
-
$client->save_access_token(
|
175 |
-
$this->get_current_user_id(),
|
176 |
-
$access_token
|
177 |
-
);
|
178 |
-
}
|
179 |
-
// @codingStandardsIgnoreLine Generic.CodeAnalysis.EmptyStatement.DetectedCATCH -- There is nothing to do.
|
180 |
-
catch ( Exception $e ) {
|
181 |
-
// Do nothing.
|
182 |
-
}
|
183 |
-
|
184 |
-
$this->redirect_to_premium_page();
|
185 |
-
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Saves the client id.
|
189 |
-
*
|
190 |
-
* @codeCoverageIgnore
|
191 |
-
*
|
192 |
-
* @param string $client_id The client id to save.
|
193 |
-
*
|
194 |
-
* @return void
|
195 |
-
*/
|
196 |
-
protected function save_client_id( $client_id ) {
|
197 |
-
$this->get_client()->save_configuration(
|
198 |
-
[
|
199 |
-
'clientId' => $client_id,
|
200 |
-
]
|
201 |
-
);
|
202 |
-
}
|
203 |
-
|
204 |
-
/**
|
205 |
-
* Creates a new MyYoast Client instance.
|
206 |
-
*
|
207 |
-
* @codeCoverageIgnore
|
208 |
-
*
|
209 |
-
* @return WPSEO_MyYoast_Client Instance of the myyoast client.
|
210 |
-
*/
|
211 |
-
protected function get_client() {
|
212 |
-
if ( ! $this->client ) {
|
213 |
-
$this->client = new WPSEO_MyYoast_Client();
|
214 |
-
}
|
215 |
-
|
216 |
-
return $this->client;
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Abstracts the action from the url.
|
221 |
-
*
|
222 |
-
* @codeCoverageIgnore
|
223 |
-
*
|
224 |
-
* @return string The action from the url.
|
225 |
-
*/
|
226 |
-
protected function get_action() {
|
227 |
-
return filter_input( INPUT_GET, 'action' );
|
228 |
-
}
|
229 |
-
|
230 |
-
/**
|
231 |
-
* Abstracts the authorization code from the url.
|
232 |
-
*
|
233 |
-
* @codeCoverageIgnore
|
234 |
-
*
|
235 |
-
* @return string The action from the url.
|
236 |
-
*/
|
237 |
-
protected function get_authorization_code() {
|
238 |
-
return filter_input( INPUT_GET, 'code' );
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* Retrieves a list of activated extensions slugs.
|
243 |
-
*
|
244 |
-
* @codeCoverageIgnore
|
245 |
-
*
|
246 |
-
* @return array The extensions slugs.
|
247 |
-
*/
|
248 |
-
protected function get_extensions() {
|
249 |
-
$addon_manager = new WPSEO_Addon_Manager();
|
250 |
-
|
251 |
-
return array_keys( $addon_manager->get_subscriptions_for_active_addons() );
|
252 |
-
}
|
253 |
-
|
254 |
-
/**
|
255 |
-
* Generates an URL-encoded query string, redirects there.
|
256 |
-
*
|
257 |
-
* @codeCoverageIgnore
|
258 |
-
*
|
259 |
-
* @param string $url The url to redirect to.
|
260 |
-
* @param array $query_args The additional arguments to build the url from.
|
261 |
-
*
|
262 |
-
* @return void
|
263 |
-
*/
|
264 |
-
protected function redirect( $url, $query_args = [] ) {
|
265 |
-
if ( ! empty( $query_args ) ) {
|
266 |
-
$url .= '?' . http_build_query( $query_args );
|
267 |
-
}
|
268 |
-
|
269 |
-
wp_redirect( $url );
|
270 |
-
exit;
|
271 |
-
}
|
272 |
-
|
273 |
-
/**
|
274 |
-
* Checks if current user is allowed to access the route.
|
275 |
-
*
|
276 |
-
* @codeCoverageIgnore
|
277 |
-
*
|
278 |
-
* @return bool True when current user has rights to manage options.
|
279 |
-
*/
|
280 |
-
protected function can_access_route() {
|
281 |
-
return WPSEO_Utils::has_access_token_support() && current_user_can( 'wpseo_manage_options' );
|
282 |
-
}
|
283 |
-
|
284 |
-
/**
|
285 |
-
* Generates an unique user id.
|
286 |
-
*
|
287 |
-
* @codeCoverageIgnore
|
288 |
-
*
|
289 |
-
* @return string The generated unique user id.
|
290 |
-
*/
|
291 |
-
protected function generate_uuid() {
|
292 |
-
return wp_generate_uuid4();
|
293 |
-
}
|
294 |
-
|
295 |
-
/**
|
296 |
-
* Retrieves the current user id.
|
297 |
-
*
|
298 |
-
* @codeCoverageIgnore
|
299 |
-
*
|
300 |
-
* @return int The user id.
|
301 |
-
*/
|
302 |
-
protected function get_current_user_id() {
|
303 |
-
return get_current_user_id();
|
304 |
-
}
|
305 |
-
|
306 |
-
/**
|
307 |
-
* Redirects to the premium page.
|
308 |
-
*
|
309 |
-
* @codeCoverageIgnore
|
310 |
-
*
|
311 |
-
* @return void
|
312 |
-
*/
|
313 |
-
protected function redirect_to_premium_page() {
|
314 |
-
wp_safe_redirect( admin_url( 'admin.php?page=wpseo_licenses' ) );
|
315 |
-
exit;
|
316 |
-
}
|
317 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/class-premium-upsell-admin-block.php
CHANGED
@@ -64,7 +64,7 @@ class WPSEO_Premium_Upsell_Admin_Block {
|
|
64 |
$class = $this->get_html_class();
|
65 |
|
66 |
/* translators: %s expands to Yoast SEO Premium */
|
67 |
-
$button_text =
|
68 |
$button_text .= '<span class="screen-reader-text">' . esc_html__( '(Opens in a new browser tab)', 'wordpress-seo' ) . '</span>' .
|
69 |
'<span aria-hidden="true" class="yoast-button-upsell__caret"></span>';
|
70 |
|
@@ -85,9 +85,11 @@ class WPSEO_Premium_Upsell_Admin_Block {
|
|
85 |
'Yoast SEO Premium'
|
86 |
) .
|
87 |
'</h2>';
|
|
|
|
|
88 |
echo '<ul class="' . esc_attr( $class . '--motivation' ) . '">' . $arguments_html . '</ul>';
|
89 |
|
90 |
-
//
|
91 |
echo '<p>' . $upgrade_button . '</p>';
|
92 |
echo '</div>';
|
93 |
|
64 |
$class = $this->get_html_class();
|
65 |
|
66 |
/* translators: %s expands to Yoast SEO Premium */
|
67 |
+
$button_text = sprintf( esc_html__( 'Get %s', 'wordpress-seo' ), 'Yoast SEO Premium' );
|
68 |
$button_text .= '<span class="screen-reader-text">' . esc_html__( '(Opens in a new browser tab)', 'wordpress-seo' ) . '</span>' .
|
69 |
'<span aria-hidden="true" class="yoast-button-upsell__caret"></span>';
|
70 |
|
85 |
'Yoast SEO Premium'
|
86 |
) .
|
87 |
'</h2>';
|
88 |
+
|
89 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in $this->get_argument_html() method.
|
90 |
echo '<ul class="' . esc_attr( $class . '--motivation' ) . '">' . $arguments_html . '</ul>';
|
91 |
|
92 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in $upgrade_button and $button_text above.
|
93 |
echo '<p>' . $upgrade_button . '</p>';
|
94 |
echo '</div>';
|
95 |
|
admin/class-yoast-network-admin.php
CHANGED
@@ -113,15 +113,17 @@ class Yoast_Network_Admin implements WPSEO_WordPress_Integration, WPSEO_WordPres
|
|
113 |
return;
|
114 |
}
|
115 |
|
|
|
116 |
foreach ( $whitelist_options as $option_name ) {
|
117 |
$value = null;
|
118 |
-
if ( isset( $_POST[ $option_name ] ) ) {
|
119 |
// Adding sanitize_text_field around this will break the saving of settings because it expects a string: https://github.com/Yoast/wordpress-seo/issues/12440.
|
120 |
-
$value = wp_unslash( $_POST[ $option_name ] );
|
121 |
}
|
122 |
|
123 |
WPSEO_Options::update_site_option( $option_name, $value );
|
124 |
}
|
|
|
125 |
|
126 |
$settings_errors = get_settings_errors();
|
127 |
if ( empty( $settings_errors ) ) {
|
@@ -141,7 +143,8 @@ class Yoast_Network_Admin implements WPSEO_WordPress_Integration, WPSEO_WordPres
|
|
141 |
|
142 |
$option_group = 'wpseo_ms';
|
143 |
|
144 |
-
|
|
|
145 |
if ( ! $site_id ) {
|
146 |
add_settings_error( $option_group, 'settings_updated', __( 'No site has been selected to restore.', 'wordpress-seo' ), 'error' );
|
147 |
|
113 |
return;
|
114 |
}
|
115 |
|
116 |
+
// phpcs:disable WordPress.Security.NonceVerification -- Nonce verified via `verify_request()` above.
|
117 |
foreach ( $whitelist_options as $option_name ) {
|
118 |
$value = null;
|
119 |
+
if ( isset( $_POST[ $option_name ] ) ) {
|
120 |
// Adding sanitize_text_field around this will break the saving of settings because it expects a string: https://github.com/Yoast/wordpress-seo/issues/12440.
|
121 |
+
$value = wp_unslash( $_POST[ $option_name ] );
|
122 |
}
|
123 |
|
124 |
WPSEO_Options::update_site_option( $option_name, $value );
|
125 |
}
|
126 |
+
// phpcs:enable WordPress.Security.NonceVerification
|
127 |
|
128 |
$settings_errors = get_settings_errors();
|
129 |
if ( empty( $settings_errors ) ) {
|
143 |
|
144 |
$option_group = 'wpseo_ms';
|
145 |
|
146 |
+
// phpcs:ignore WordPress.Security.NonceVerification -- Nonce verified via `verify_request()` above.
|
147 |
+
$site_id = ! empty( $_POST[ $option_group ]['site_id'] ) ? (int) $_POST[ $option_group ]['site_id'] : 0;
|
148 |
if ( ! $site_id ) {
|
149 |
add_settings_error( $option_group, 'settings_updated', __( 'No site has been selected to restore.', 'wordpress-seo' ), 'error' );
|
150 |
|
admin/class-yoast-notification-center.php
CHANGED
@@ -164,9 +164,9 @@ class Yoast_Notification_Center {
|
|
164 |
return true;
|
165 |
}
|
166 |
|
167 |
-
$dismissal_key
|
168 |
-
$notification_id
|
169 |
-
$notification_json
|
170 |
|
171 |
$is_dismissing = ( $dismissal_key === self::get_user_input( 'notification' ) );
|
172 |
if ( ! $is_dismissing ) {
|
164 |
return true;
|
165 |
}
|
166 |
|
167 |
+
$dismissal_key = $notification->get_dismissal_key();
|
168 |
+
$notification_id = $notification->get_id();
|
169 |
+
$notification_json = $notification->get_json();
|
170 |
|
171 |
$is_dismissing = ( $dismissal_key === self::get_user_input( 'notification' ) );
|
172 |
if ( ! $is_dismissing ) {
|
admin/config-ui/class-configuration-structure.php
CHANGED
@@ -88,6 +88,7 @@ class WPSEO_Configuration_Structure {
|
|
88 |
);
|
89 |
|
90 |
$this->add_step( 'title-template', __( 'Title settings', 'wordpress-seo' ), $this->fields['titleTemplate'] );
|
|
|
91 |
$this->add_step( 'tracking', sprintf( __( 'Help us improve %s', 'wordpress-seo' ), 'Yoast SEO' ), $this->fields['tracking'] );
|
92 |
$this->add_step( 'newsletter', __( 'Continue learning', 'wordpress-seo' ), $this->fields['newsletter'], true, true );
|
93 |
$this->add_step( 'success', __( 'Success!', 'wordpress-seo' ), $this->fields['success'], true, true );
|
88 |
);
|
89 |
|
90 |
$this->add_step( 'title-template', __( 'Title settings', 'wordpress-seo' ), $this->fields['titleTemplate'] );
|
91 |
+
/* translators: %s expands to Yoast SEO */
|
92 |
$this->add_step( 'tracking', sprintf( __( 'Help us improve %s', 'wordpress-seo' ), 'Yoast SEO' ), $this->fields['tracking'] );
|
93 |
$this->add_step( 'newsletter', __( 'Continue learning', 'wordpress-seo' ), $this->fields['newsletter'], true, true );
|
94 |
$this->add_step( 'success', __( 'Success!', 'wordpress-seo' ), $this->fields['success'], true, true );
|
admin/config-ui/fields/class-field-tracking.php
CHANGED
@@ -18,8 +18,8 @@ class WPSEO_Config_Field_Tracking extends WPSEO_Config_Field_Choice {
|
|
18 |
|
19 |
$this->set_property( 'label', __( 'Can we collect anonymous information about your website and its usage?', 'wordpress-seo' ) );
|
20 |
|
21 |
-
$this->add_choice( '
|
22 |
-
$this->add_choice( '
|
23 |
}
|
24 |
|
25 |
/**
|
@@ -43,9 +43,9 @@ class WPSEO_Config_Field_Tracking extends WPSEO_Config_Field_Choice {
|
|
43 |
public function get_data() {
|
44 |
$tracking = WPSEO_Options::get( 'tracking' );
|
45 |
if ( $tracking ) {
|
46 |
-
return '
|
47 |
}
|
48 |
-
return '
|
49 |
}
|
50 |
|
51 |
/**
|
18 |
|
19 |
$this->set_property( 'label', __( 'Can we collect anonymous information about your website and its usage?', 'wordpress-seo' ) );
|
20 |
|
21 |
+
$this->add_choice( 'no', __( 'No, I don\'t want to allow you to track my site data.', 'wordpress-seo' ) );
|
22 |
+
$this->add_choice( 'yes', __( 'Yes, you can track my site\'s data!', 'wordpress-seo' ) );
|
23 |
}
|
24 |
|
25 |
/**
|
43 |
public function get_data() {
|
44 |
$tracking = WPSEO_Options::get( 'tracking' );
|
45 |
if ( $tracking ) {
|
46 |
+
return 'yes';
|
47 |
}
|
48 |
+
return 'no';
|
49 |
}
|
50 |
|
51 |
/**
|
admin/endpoints/class-endpoint-indexable.php
DELETED
@@ -1,102 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Endpoints
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents an implementation of the WPSEO_Endpoint interface to register one or multiple endpoints.
|
10 |
-
*/
|
11 |
-
class WPSEO_Endpoint_Indexable implements WPSEO_Endpoint, WPSEO_Endpoint_Storable {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* The namespace of the REST route.
|
15 |
-
*
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
const REST_NAMESPACE = 'yoast/v1';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* The route of the endpoint to retrieve or patch the indexable.
|
22 |
-
*
|
23 |
-
* @var string
|
24 |
-
*/
|
25 |
-
const ENDPOINT_SINGULAR = 'indexables/(?P<object_type>\w+)/(?P<object_id>\d+)';
|
26 |
-
|
27 |
-
/**
|
28 |
-
* The name of the capability needed to retrieve data using the endpoints.
|
29 |
-
*
|
30 |
-
* @var string
|
31 |
-
*/
|
32 |
-
const CAPABILITY_RETRIEVE = 'manage_options';
|
33 |
-
|
34 |
-
/**
|
35 |
-
* The name of the capability needed to store data using the endpoints.
|
36 |
-
*
|
37 |
-
* @var string
|
38 |
-
*/
|
39 |
-
const CAPABILITY_STORE = 'manage_options';
|
40 |
-
|
41 |
-
/**
|
42 |
-
* The indexable service.
|
43 |
-
*
|
44 |
-
* @var WPSEO_Indexable_Service
|
45 |
-
*/
|
46 |
-
private $service;
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Sets the service provider.
|
50 |
-
*
|
51 |
-
* @param WPSEO_Indexable_Service $service The service provider.
|
52 |
-
*/
|
53 |
-
public function __construct( WPSEO_Indexable_Service $service ) {
|
54 |
-
$this->service = $service;
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Registers the routes for the endpoints.
|
59 |
-
*
|
60 |
-
* @return void
|
61 |
-
*/
|
62 |
-
public function register() {
|
63 |
-
$endpoints = [];
|
64 |
-
|
65 |
-
$endpoints[] = new WPSEO_Endpoint_Factory(
|
66 |
-
self::REST_NAMESPACE,
|
67 |
-
self::ENDPOINT_SINGULAR,
|
68 |
-
[ $this->service, 'get_indexable' ],
|
69 |
-
[ $this, 'can_retrieve_data' ]
|
70 |
-
);
|
71 |
-
|
72 |
-
$endpoints[] = new WPSEO_Endpoint_Factory(
|
73 |
-
self::REST_NAMESPACE,
|
74 |
-
self::ENDPOINT_SINGULAR,
|
75 |
-
[ $this->service, 'patch_indexable' ],
|
76 |
-
[ $this, 'can_store_data' ],
|
77 |
-
'PATCH'
|
78 |
-
);
|
79 |
-
|
80 |
-
foreach ( $endpoints as $endpoint ) {
|
81 |
-
$endpoint->register();
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Determines whether or not data can be retrieved for the registered endpoints.
|
87 |
-
*
|
88 |
-
* @return bool Whether or not data can be retrieved.
|
89 |
-
*/
|
90 |
-
public function can_retrieve_data() {
|
91 |
-
return current_user_can( self::CAPABILITY_RETRIEVE );
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Determines whether or not data can be stored for the registered endpoints.
|
96 |
-
*
|
97 |
-
* @return bool Whether or not data can be stored.
|
98 |
-
*/
|
99 |
-
public function can_store_data() {
|
100 |
-
return current_user_can( self::CAPABILITY_STORE );
|
101 |
-
}
|
102 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/endpoints/interface-endpoint-storable.php
DELETED
@@ -1,19 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Endpoints
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Dictates the required methods for a storable implementation.
|
10 |
-
*/
|
11 |
-
interface WPSEO_Endpoint_Storable {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Determines whether or not data can be stored for the registered endpoints.
|
15 |
-
*
|
16 |
-
* @return bool Whether or not data can be stored.
|
17 |
-
*/
|
18 |
-
public function can_store_data();
|
19 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/import/plugins/class-abstract-plugin-importer.php
CHANGED
@@ -43,8 +43,7 @@ abstract class WPSEO_Plugin_Importer {
|
|
43 |
/**
|
44 |
* Class constructor.
|
45 |
*/
|
46 |
-
public function __construct() {
|
47 |
-
}
|
48 |
|
49 |
/**
|
50 |
* Returns the string for the plugin we're importing from.
|
@@ -188,6 +187,7 @@ abstract class WPSEO_Plugin_Importer {
|
|
188 |
// First we create a temp table with all the values for meta_key.
|
189 |
$result = $wpdb->query(
|
190 |
$wpdb->prepare(
|
|
|
191 |
"CREATE TEMPORARY TABLE tmp_meta_table SELECT * FROM {$wpdb->postmeta} WHERE meta_key = %s",
|
192 |
$old_key
|
193 |
)
|
@@ -225,6 +225,7 @@ abstract class WPSEO_Plugin_Importer {
|
|
225 |
$wpdb->query( "INSERT INTO {$wpdb->postmeta} SELECT * FROM tmp_meta_table" );
|
226 |
|
227 |
// Now we drop our temporary table.
|
|
|
228 |
$wpdb->query( 'DROP TEMPORARY TABLE IF EXISTS tmp_meta_table' );
|
229 |
|
230 |
return true;
|
43 |
/**
|
44 |
* Class constructor.
|
45 |
*/
|
46 |
+
public function __construct() {}
|
|
|
47 |
|
48 |
/**
|
49 |
* Returns the string for the plugin we're importing from.
|
187 |
// First we create a temp table with all the values for meta_key.
|
188 |
$result = $wpdb->query(
|
189 |
$wpdb->prepare(
|
190 |
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- This is intentional + temporary.
|
191 |
"CREATE TEMPORARY TABLE tmp_meta_table SELECT * FROM {$wpdb->postmeta} WHERE meta_key = %s",
|
192 |
$old_key
|
193 |
)
|
225 |
$wpdb->query( "INSERT INTO {$wpdb->postmeta} SELECT * FROM tmp_meta_table" );
|
226 |
|
227 |
// Now we drop our temporary table.
|
228 |
+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- This is intentional + a temporary table.
|
229 |
$wpdb->query( 'DROP TEMPORARY TABLE IF EXISTS tmp_meta_table' );
|
230 |
|
231 |
return true;
|
admin/metabox/class-metabox.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
*/
|
7 |
|
8 |
use Yoast\WP\SEO\Presenters\Admin\Alert_Presenter;
|
|
|
9 |
|
10 |
/**
|
11 |
* This class generates the metabox on the edit post / page as well as contains all page analysis functionality.
|
@@ -13,25 +14,25 @@ use Yoast\WP\SEO\Presenters\Admin\Alert_Presenter;
|
|
13 |
class WPSEO_Metabox extends WPSEO_Meta {
|
14 |
|
15 |
/**
|
16 |
-
* Whether or not the social tab is enabled
|
17 |
*
|
18 |
* @var bool
|
19 |
*/
|
20 |
private $social_is_enabled;
|
21 |
|
22 |
/**
|
23 |
-
*
|
24 |
*
|
25 |
* @var WPSEO_Metabox_Analysis_SEO
|
26 |
*/
|
27 |
-
protected $
|
28 |
|
29 |
/**
|
30 |
-
*
|
31 |
*
|
32 |
* @var WPSEO_Metabox_Analysis_Readability
|
33 |
*/
|
34 |
-
protected $
|
35 |
|
36 |
/**
|
37 |
* The metabox editor object.
|
@@ -40,6 +41,13 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
40 |
*/
|
41 |
protected $editor;
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
/**
|
44 |
* Whether or not the advanced metadata is enabled.
|
45 |
*
|
@@ -69,8 +77,8 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
69 |
$this->social_is_enabled = WPSEO_Options::get( 'opengraph', false ) || WPSEO_Options::get( 'twitter', false );
|
70 |
$this->is_advanced_metadata_enabled = WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta' ) === false;
|
71 |
|
72 |
-
$this->
|
73 |
-
$this->
|
74 |
}
|
75 |
|
76 |
/**
|
@@ -251,23 +259,22 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
251 |
* @return array
|
252 |
*/
|
253 |
public function get_metabox_script_data() {
|
254 |
-
$post = $this->get_metabox_post();
|
255 |
$permalink = '';
|
256 |
|
257 |
-
if ( is_object( $
|
258 |
-
$permalink = get_sample_permalink( $
|
259 |
$permalink = $permalink[0];
|
260 |
}
|
261 |
|
262 |
$post_formatter = new WPSEO_Metabox_Formatter(
|
263 |
-
new WPSEO_Post_Metabox_Formatter( $
|
264 |
);
|
265 |
|
266 |
$values = $post_formatter->get_values();
|
267 |
|
268 |
/** This filter is documented in admin/filters/class-cornerstone-filter.php. */
|
269 |
$post_types = apply_filters( 'wpseo_cornerstone_post_types', WPSEO_Post_Type::get_accessible_post_types() );
|
270 |
-
if ( $values['cornerstoneActive'] && ! in_array( $
|
271 |
$values['cornerstoneActive'] = false;
|
272 |
}
|
273 |
|
@@ -292,9 +299,7 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
292 |
* @return string String describing the current scope.
|
293 |
*/
|
294 |
private function determine_scope() {
|
295 |
-
|
296 |
-
|
297 |
-
if ( $post_type === 'page' ) {
|
298 |
return 'page';
|
299 |
}
|
300 |
|
@@ -303,156 +308,118 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
303 |
|
304 |
/**
|
305 |
* Outputs the meta box.
|
306 |
-
*
|
307 |
-
* @param WP_Post $post The post.
|
308 |
*/
|
309 |
-
public function meta_box(
|
310 |
-
|
311 |
-
$
|
312 |
-
|
313 |
-
echo '<div class="wpseo-metabox-content">';
|
314 |
-
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: $this->get_product_title is considered safe.
|
315 |
-
printf( '<div class="wpseo-metabox-menu"><ul role="tablist" class="yoast-aria-tabs" aria-label="%s">', $this->get_product_title() );
|
316 |
-
|
317 |
-
foreach ( $content_sections as $content_section ) {
|
318 |
-
if ( $content_section->name === 'premium' ) {
|
319 |
-
continue;
|
320 |
-
}
|
321 |
-
|
322 |
-
$content_section->display_link();
|
323 |
-
}
|
324 |
-
|
325 |
-
echo '</ul></div>';
|
326 |
-
|
327 |
-
foreach ( $content_sections as $content_section ) {
|
328 |
-
$content_section->display_content();
|
329 |
-
}
|
330 |
-
|
331 |
-
echo '</div>';
|
332 |
}
|
333 |
|
334 |
/**
|
335 |
-
*
|
336 |
-
*
|
337 |
-
* @param string $post_type The post type.
|
338 |
*
|
339 |
-
* @return
|
340 |
*/
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
$content_sections[] = $this->get_seo_meta_section();
|
345 |
|
346 |
-
|
347 |
-
$content_sections[] = $this->get_readability_meta_section();
|
348 |
-
}
|
349 |
|
350 |
if ( $this->is_advanced_metadata_enabled ) {
|
351 |
-
|
352 |
}
|
353 |
|
354 |
-
|
|
|
355 |
if ( $this->social_is_enabled ) {
|
356 |
-
|
357 |
}
|
358 |
|
359 |
-
|
360 |
-
|
361 |
-
|
|
|
|
|
|
|
362 |
}
|
363 |
|
364 |
/**
|
365 |
-
*
|
366 |
*
|
367 |
-
* @return
|
368 |
*/
|
369 |
-
|
370 |
-
|
|
|
|
|
|
|
|
|
371 |
|
372 |
-
$
|
|
|
|
|
|
|
373 |
|
374 |
-
|
375 |
-
|
376 |
|
377 |
-
|
378 |
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
}
|
385 |
|
386 |
/**
|
387 |
-
* Returns the metabox
|
388 |
*
|
389 |
-
* @return WPSEO_Metabox_Section
|
390 |
*/
|
391 |
-
private function
|
392 |
-
|
393 |
-
|
394 |
-
$content = $this->get_tab_content( 'general' );
|
395 |
|
396 |
$label = __( 'SEO', 'wordpress-seo' );
|
397 |
-
if ( $this->
|
398 |
$label = '<span class="wpseo-score-icon-container" id="wpseo-seo-score-icon"></span>' . $label;
|
399 |
}
|
|
|
400 |
|
401 |
-
$
|
|
|
|
|
402 |
|
403 |
if ( $this->is_advanced_metadata_enabled ) {
|
404 |
-
$
|
|
|
|
|
|
|
|
|
405 |
}
|
406 |
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
$content,
|
418 |
-
[
|
419 |
-
'html_after' => $html_after,
|
420 |
-
]
|
421 |
-
);
|
422 |
-
}
|
423 |
|
424 |
-
|
425 |
-
* Returns the metabox section for the schema tab.
|
426 |
-
*
|
427 |
-
* @param string $post_type The post type.
|
428 |
-
*
|
429 |
-
* @return WPSEO_Metabox_Section_React
|
430 |
-
*/
|
431 |
-
private function get_schema_meta_section( $post_type ) {
|
432 |
-
$content = $this->get_tab_content( 'schema', $post_type );
|
433 |
-
return new WPSEO_Metabox_Section_React(
|
434 |
-
'schema',
|
435 |
-
'<span class="wpseo-schema-icon"></span>' . __( 'Schema', 'wordpress-seo' ),
|
436 |
-
$content
|
437 |
-
);
|
438 |
-
}
|
439 |
|
440 |
-
|
441 |
-
* Returns the metabox section for the readability analysis.
|
442 |
-
*
|
443 |
-
* @return WPSEO_Metabox_Section
|
444 |
-
*/
|
445 |
-
private function get_readability_meta_section() {
|
446 |
-
return new WPSEO_Metabox_Section_Readability();
|
447 |
}
|
448 |
|
449 |
/**
|
450 |
-
* Returns the metabox
|
451 |
*
|
452 |
* @return WPSEO_Metabox_Section_Additional[]
|
453 |
*/
|
454 |
-
protected function
|
455 |
-
$
|
456 |
|
457 |
/**
|
458 |
* Private filter: 'yoast_free_additional_metabox_sections'.
|
@@ -461,10 +428,10 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
461 |
*
|
462 |
* @since 11.9
|
463 |
*
|
464 |
-
* @param array[] $
|
465 |
* An array of arrays with tab specifications.
|
466 |
*
|
467 |
-
* @type array $
|
468 |
* A tab specification.
|
469 |
*
|
470 |
* @type string $name The name of the tab. Used in the HTML IDs, href and aria properties.
|
@@ -479,38 +446,21 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
479 |
* }
|
480 |
* }
|
481 |
*/
|
482 |
-
$
|
483 |
-
|
484 |
-
foreach ( $
|
485 |
-
if ( is_array( $
|
486 |
-
$options
|
487 |
-
$
|
488 |
-
$
|
489 |
-
$
|
490 |
-
$
|
491 |
$options
|
492 |
);
|
493 |
}
|
494 |
}
|
495 |
|
496 |
-
return $
|
497 |
-
}
|
498 |
-
|
499 |
-
/**
|
500 |
-
* Retrieves the contents for the metabox tab.
|
501 |
-
*
|
502 |
-
* @param string $tab_name Tab for which to retrieve the field definitions.
|
503 |
-
* @param string $post_type The post type. Defaults to post.
|
504 |
-
*
|
505 |
-
* @return string
|
506 |
-
*/
|
507 |
-
private function get_tab_content( $tab_name, $post_type = 'post' ) {
|
508 |
-
$content = '';
|
509 |
-
foreach ( WPSEO_Meta::get_meta_field_defs( $tab_name, $post_type ) as $key => $meta_field ) {
|
510 |
-
$content .= $this->do_meta_box( $meta_field, $key );
|
511 |
-
}
|
512 |
-
|
513 |
-
return $content;
|
514 |
}
|
515 |
|
516 |
/**
|
@@ -822,11 +772,11 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
822 |
* @return bool Whether the given meta value key is disabled.
|
823 |
*/
|
824 |
public function is_meta_value_disabled( $key ) {
|
825 |
-
if ( $key === 'linkdex' && ! $this->
|
826 |
return true;
|
827 |
}
|
828 |
|
829 |
-
if ( $key === 'content_score' && ! $this->
|
830 |
return true;
|
831 |
}
|
832 |
|
@@ -872,7 +822,7 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
872 |
$asset_manager->enqueue_style( 'select2' );
|
873 |
$asset_manager->enqueue_style( 'monorepo' );
|
874 |
|
875 |
-
$is_block_editor
|
876 |
$post_edit_handle = 'post-edit';
|
877 |
if ( ! $is_block_editor ) {
|
878 |
$post_edit_handle = 'post-edit-classic';
|
@@ -946,16 +896,23 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
946 |
* @returns WP_Post|array
|
947 |
*/
|
948 |
protected function get_metabox_post() {
|
|
|
|
|
|
|
|
|
949 |
$post = filter_input( INPUT_GET, 'post' );
|
950 |
if ( ! empty( $post ) ) {
|
951 |
$post_id = (int) WPSEO_Utils::validate_int( $post );
|
952 |
|
953 |
-
|
954 |
-
}
|
955 |
|
|
|
|
|
956 |
|
957 |
if ( isset( $GLOBALS['post'] ) ) {
|
958 |
-
|
|
|
|
|
959 |
}
|
960 |
|
961 |
return [];
|
@@ -982,8 +939,6 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
982 |
* @return array Replace vars.
|
983 |
*/
|
984 |
private function get_replace_vars() {
|
985 |
-
$post = $this->get_metabox_post();
|
986 |
-
|
987 |
$cached_replacement_vars = [];
|
988 |
|
989 |
$vars_to_cache = [
|
@@ -997,11 +952,11 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
997 |
];
|
998 |
|
999 |
foreach ( $vars_to_cache as $var ) {
|
1000 |
-
$cached_replacement_vars[ $var ] = wpseo_replace_vars( '%%' . $var . '%%', $
|
1001 |
}
|
1002 |
|
1003 |
// Merge custom replace variables with the WordPress ones.
|
1004 |
-
return array_merge( $cached_replacement_vars, $this->get_custom_replace_vars( $
|
1005 |
}
|
1006 |
|
1007 |
/**
|
@@ -1011,10 +966,9 @@ class WPSEO_Metabox extends WPSEO_Meta {
|
|
1011 |
*/
|
1012 |
private function get_recommended_replace_vars() {
|
1013 |
$recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
|
1014 |
-
$post = $this->get_metabox_post();
|
1015 |
|
1016 |
// What is recommended depends on the current context.
|
1017 |
-
$post_type = $recommended_replace_vars->determine_for_post( $
|
1018 |
|
1019 |
return $recommended_replace_vars->get_recommended_replacevars_for( $post_type );
|
1020 |
}
|
6 |
*/
|
7 |
|
8 |
use Yoast\WP\SEO\Presenters\Admin\Alert_Presenter;
|
9 |
+
use Yoast\WP\SEO\Presenters\Admin\Meta_Fields_Presenter;
|
10 |
|
11 |
/**
|
12 |
* This class generates the metabox on the edit post / page as well as contains all page analysis functionality.
|
14 |
class WPSEO_Metabox extends WPSEO_Meta {
|
15 |
|
16 |
/**
|
17 |
+
* Whether or not the social tab is enabled.
|
18 |
*
|
19 |
* @var bool
|
20 |
*/
|
21 |
private $social_is_enabled;
|
22 |
|
23 |
/**
|
24 |
+
* Helper to determine whether or not the SEO analysis is enabled.
|
25 |
*
|
26 |
* @var WPSEO_Metabox_Analysis_SEO
|
27 |
*/
|
28 |
+
protected $seo_analysis;
|
29 |
|
30 |
/**
|
31 |
+
* Helper to determine whether or not the readability analysis is enabled.
|
32 |
*
|
33 |
* @var WPSEO_Metabox_Analysis_Readability
|
34 |
*/
|
35 |
+
protected $readability_analysis;
|
36 |
|
37 |
/**
|
38 |
* The metabox editor object.
|
41 |
*/
|
42 |
protected $editor;
|
43 |
|
44 |
+
/**
|
45 |
+
* The Metabox post.
|
46 |
+
*
|
47 |
+
* @var WP_Post
|
48 |
+
*/
|
49 |
+
protected $post = null;
|
50 |
+
|
51 |
/**
|
52 |
* Whether or not the advanced metadata is enabled.
|
53 |
*
|
77 |
$this->social_is_enabled = WPSEO_Options::get( 'opengraph', false ) || WPSEO_Options::get( 'twitter', false );
|
78 |
$this->is_advanced_metadata_enabled = WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta' ) === false;
|
79 |
|
80 |
+
$this->seo_analysis = new WPSEO_Metabox_Analysis_SEO();
|
81 |
+
$this->readability_analysis = new WPSEO_Metabox_Analysis_Readability();
|
82 |
}
|
83 |
|
84 |
/**
|
259 |
* @return array
|
260 |
*/
|
261 |
public function get_metabox_script_data() {
|
|
|
262 |
$permalink = '';
|
263 |
|
264 |
+
if ( is_object( $this->get_metabox_post() ) ) {
|
265 |
+
$permalink = get_sample_permalink( $this->get_metabox_post()->ID );
|
266 |
$permalink = $permalink[0];
|
267 |
}
|
268 |
|
269 |
$post_formatter = new WPSEO_Metabox_Formatter(
|
270 |
+
new WPSEO_Post_Metabox_Formatter( $this->get_metabox_post(), [], $permalink )
|
271 |
);
|
272 |
|
273 |
$values = $post_formatter->get_values();
|
274 |
|
275 |
/** This filter is documented in admin/filters/class-cornerstone-filter.php. */
|
276 |
$post_types = apply_filters( 'wpseo_cornerstone_post_types', WPSEO_Post_Type::get_accessible_post_types() );
|
277 |
+
if ( $values['cornerstoneActive'] && ! in_array( $this->get_metabox_post()->post_type, $post_types, true ) ) {
|
278 |
$values['cornerstoneActive'] = false;
|
279 |
}
|
280 |
|
299 |
* @return string String describing the current scope.
|
300 |
*/
|
301 |
private function determine_scope() {
|
302 |
+
if ( $this->get_metabox_post()->post_type === 'page' ) {
|
|
|
|
|
303 |
return 'page';
|
304 |
}
|
305 |
|
308 |
|
309 |
/**
|
310 |
* Outputs the meta box.
|
|
|
|
|
311 |
*/
|
312 |
+
public function meta_box() {
|
313 |
+
$this->render_hidden_fields();
|
314 |
+
$this->render_tabs();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
}
|
316 |
|
317 |
/**
|
318 |
+
* Renders the metabox hidden fields.
|
|
|
|
|
319 |
*
|
320 |
+
* @return void
|
321 |
*/
|
322 |
+
protected function render_hidden_fields() {
|
323 |
+
wp_nonce_field( 'yoast_free_metabox', 'yoast_free_metabox_nonce' );
|
|
|
|
|
324 |
|
325 |
+
echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'general' );
|
|
|
|
|
326 |
|
327 |
if ( $this->is_advanced_metadata_enabled ) {
|
328 |
+
echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'advanced' );
|
329 |
}
|
330 |
|
331 |
+
echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'schema', $this->get_metabox_post()->post_type );
|
332 |
+
|
333 |
if ( $this->social_is_enabled ) {
|
334 |
+
echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'social' );
|
335 |
}
|
336 |
|
337 |
+
/**
|
338 |
+
* Filter: 'wpseo_content_meta_section_content' - Allow filtering the metabox content before outputting.
|
339 |
+
*
|
340 |
+
* @api string $post_content The metabox content string.
|
341 |
+
*/
|
342 |
+
echo apply_filters( 'wpseo_content_meta_section_content', '' );
|
343 |
}
|
344 |
|
345 |
/**
|
346 |
+
* Renders the metabox tabs.
|
347 |
*
|
348 |
+
* @return void
|
349 |
*/
|
350 |
+
protected function render_tabs() {
|
351 |
+
echo '<div class="wpseo-metabox-content">';
|
352 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: $this->get_product_title() returns a hard-coded string.
|
353 |
+
printf( '<div class="wpseo-metabox-menu"><ul role="tablist" class="yoast-aria-tabs" aria-label="%s">', $this->get_product_title() );
|
354 |
+
|
355 |
+
$tabs = $this->get_tabs();
|
356 |
|
357 |
+
foreach ( $tabs as $tab ) {
|
358 |
+
if ( $tab->name === 'premium' ) {
|
359 |
+
continue;
|
360 |
+
}
|
361 |
|
362 |
+
$tab->display_link();
|
363 |
+
}
|
364 |
|
365 |
+
echo '</ul></div>';
|
366 |
|
367 |
+
foreach ( $tabs as $tab ) {
|
368 |
+
$tab->display_content();
|
369 |
+
}
|
370 |
+
|
371 |
+
echo '</div>';
|
372 |
}
|
373 |
|
374 |
/**
|
375 |
+
* Returns the relevant metabox tabs for the current view.
|
376 |
*
|
377 |
+
* @return WPSEO_Metabox_Section[]
|
378 |
*/
|
379 |
+
private function get_tabs() {
|
380 |
+
$tabs = [];
|
|
|
|
|
381 |
|
382 |
$label = __( 'SEO', 'wordpress-seo' );
|
383 |
+
if ( $this->seo_analysis->is_enabled() ) {
|
384 |
$label = '<span class="wpseo-score-icon-container" id="wpseo-seo-score-icon"></span>' . $label;
|
385 |
}
|
386 |
+
$tabs[] = new WPSEO_Metabox_Section_React( 'content', $label );
|
387 |
|
388 |
+
if ( $this->readability_analysis->is_enabled() ) {
|
389 |
+
$tabs[] = new WPSEO_Metabox_Section_Readability();
|
390 |
+
}
|
391 |
|
392 |
if ( $this->is_advanced_metadata_enabled ) {
|
393 |
+
$tabs[] = new WPSEO_Metabox_Section_React(
|
394 |
+
'schema',
|
395 |
+
'<span class="wpseo-schema-icon"></span>' . __( 'Schema', 'wordpress-seo' ),
|
396 |
+
''
|
397 |
+
);
|
398 |
}
|
399 |
|
400 |
+
if ( $this->social_is_enabled ) {
|
401 |
+
$tabs[] = new WPSEO_Metabox_Section_React(
|
402 |
+
'social',
|
403 |
+
'<span class="dashicons dashicons-share"></span>' . __( 'Social', 'wordpress-seo' ),
|
404 |
+
'',
|
405 |
+
[
|
406 |
+
'html_after' => '<div id="wpseo-section-social"></div>',
|
407 |
+
]
|
408 |
+
);
|
409 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
410 |
|
411 |
+
$tabs = array_merge( $tabs, $this->get_additional_tabs() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
412 |
|
413 |
+
return $tabs;
|
|
|
|
|
|
|
|
|
|
|
|
|
414 |
}
|
415 |
|
416 |
/**
|
417 |
+
* Returns the metabox tabs that have been added by other plugins.
|
418 |
*
|
419 |
* @return WPSEO_Metabox_Section_Additional[]
|
420 |
*/
|
421 |
+
protected function get_additional_tabs() {
|
422 |
+
$tabs = [];
|
423 |
|
424 |
/**
|
425 |
* Private filter: 'yoast_free_additional_metabox_sections'.
|
428 |
*
|
429 |
* @since 11.9
|
430 |
*
|
431 |
+
* @param array[] $tabs {
|
432 |
* An array of arrays with tab specifications.
|
433 |
*
|
434 |
+
* @type array $tab {
|
435 |
* A tab specification.
|
436 |
*
|
437 |
* @type string $name The name of the tab. Used in the HTML IDs, href and aria properties.
|
446 |
* }
|
447 |
* }
|
448 |
*/
|
449 |
+
$requested_tabs = apply_filters( 'yoast_free_additional_metabox_sections', [] );
|
450 |
+
|
451 |
+
foreach ( $requested_tabs as $tab ) {
|
452 |
+
if ( is_array( $tab ) && array_key_exists( 'name', $tab ) && array_key_exists( 'link_content', $tab ) && array_key_exists( 'content', $tab ) ) {
|
453 |
+
$options = array_key_exists( 'options', $tab ) ? $tab['options'] : [];
|
454 |
+
$tabs[] = new WPSEO_Metabox_Section_Additional(
|
455 |
+
$tab['name'],
|
456 |
+
$tab['link_content'],
|
457 |
+
$tab['content'],
|
458 |
$options
|
459 |
);
|
460 |
}
|
461 |
}
|
462 |
|
463 |
+
return $tabs;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
464 |
}
|
465 |
|
466 |
/**
|
772 |
* @return bool Whether the given meta value key is disabled.
|
773 |
*/
|
774 |
public function is_meta_value_disabled( $key ) {
|
775 |
+
if ( $key === 'linkdex' && ! $this->seo_analysis->is_enabled() ) {
|
776 |
return true;
|
777 |
}
|
778 |
|
779 |
+
if ( $key === 'content_score' && ! $this->readability_analysis->is_enabled() ) {
|
780 |
return true;
|
781 |
}
|
782 |
|
822 |
$asset_manager->enqueue_style( 'select2' );
|
823 |
$asset_manager->enqueue_style( 'monorepo' );
|
824 |
|
825 |
+
$is_block_editor = WP_Screen::get()->is_block_editor();
|
826 |
$post_edit_handle = 'post-edit';
|
827 |
if ( ! $is_block_editor ) {
|
828 |
$post_edit_handle = 'post-edit-classic';
|
896 |
* @returns WP_Post|array
|
897 |
*/
|
898 |
protected function get_metabox_post() {
|
899 |
+
if ( $this->post !== null ) {
|
900 |
+
return $this->post;
|
901 |
+
}
|
902 |
+
|
903 |
$post = filter_input( INPUT_GET, 'post' );
|
904 |
if ( ! empty( $post ) ) {
|
905 |
$post_id = (int) WPSEO_Utils::validate_int( $post );
|
906 |
|
907 |
+
$this->post = get_post( $post_id );
|
|
|
908 |
|
909 |
+
return $this->post;
|
910 |
+
}
|
911 |
|
912 |
if ( isset( $GLOBALS['post'] ) ) {
|
913 |
+
$this->post = $GLOBALS['post'];
|
914 |
+
|
915 |
+
return $this->post;
|
916 |
}
|
917 |
|
918 |
return [];
|
939 |
* @return array Replace vars.
|
940 |
*/
|
941 |
private function get_replace_vars() {
|
|
|
|
|
942 |
$cached_replacement_vars = [];
|
943 |
|
944 |
$vars_to_cache = [
|
952 |
];
|
953 |
|
954 |
foreach ( $vars_to_cache as $var ) {
|
955 |
+
$cached_replacement_vars[ $var ] = wpseo_replace_vars( '%%' . $var . '%%', $this->get_metabox_post() );
|
956 |
}
|
957 |
|
958 |
// Merge custom replace variables with the WordPress ones.
|
959 |
+
return array_merge( $cached_replacement_vars, $this->get_custom_replace_vars( $this->get_metabox_post() ) );
|
960 |
}
|
961 |
|
962 |
/**
|
966 |
*/
|
967 |
private function get_recommended_replace_vars() {
|
968 |
$recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars();
|
|
|
969 |
|
970 |
// What is recommended depends on the current context.
|
971 |
+
$post_type = $recommended_replace_vars->determine_for_post( $this->get_metabox_post() );
|
972 |
|
973 |
return $recommended_replace_vars->get_recommended_replacevars_for( $post_type );
|
974 |
}
|
admin/roles/class-role-manager-wp.php
CHANGED
@@ -29,7 +29,6 @@ final class WPSEO_Role_Manager_WP extends WPSEO_Abstract_Role_Manager {
|
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
-
// @codingStandardsIgnoreLine
|
33 |
add_role( $role, $display_name, $capabilities );
|
34 |
}
|
35 |
|
29 |
return;
|
30 |
}
|
31 |
|
|
|
32 |
add_role( $role, $display_name, $capabilities );
|
33 |
}
|
34 |
|
admin/services/class-indexable-post-provider.php
DELETED
@@ -1,232 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* WPSEO plugin file.
|
4 |
-
*
|
5 |
-
* @package WPSEO\Admin\Services
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Represents the indexable post service.
|
10 |
-
*/
|
11 |
-
class WPSEO_Indexable_Service_Post_Provider extends WPSEO_Indexable_Provider {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* List of fields that need to be renamed.
|
15 |
-
*
|
16 |
-
* @var array
|
17 |
-
*/
|
18 |
-
protected $renameable_fields = [
|
19 |
-
'description' => 'metadesc',
|
20 |
-
'breadcrumb_title' => 'bctitle',
|
21 |
-
'og_title' => 'opengraph-title',
|
22 |
-
'og_description' => 'opengraph-description',
|
23 |
-
'og_image' => 'opengraph-image',
|
24 |
-
'twitter_title' => 'twitter-title',
|
25 |
-
'twitter_description' => 'twitter-description',
|
26 |
-
'twitter_image' => 'twitter-image',
|
27 |
-
'is_robots_noindex' => 'meta-robots-noindex',
|
28 |
-
'is_robots_nofollow' => 'meta-robots-nofollow',
|
29 |
-
'primary_focus_keyword' => 'focuskw',
|
30 |
-
'primary_focus_keyword_score' => 'linkdex',
|
31 |
-
'readability_score' => 'content_score',
|
32 |
-
];
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Returns an array with data for the target object.
|
36 |
-
*
|
37 |
-
* @param integer $object_id The target object id.
|
38 |
-
* @param bool $as_object Optional. Whether or not to return the indexable
|
39 |
-
* as an object. Defaults to false.
|
40 |
-
*
|
41 |
-
* @return array|WPSEO_Post_Indexable The retrieved data. Defaults to an array format.
|
42 |
-
*
|
43 |
-
* @throws WPSEO_Invalid_Argument_Exception The invalid argument exception.
|
44 |
-
*/
|
45 |
-
public function get( $object_id, $as_object = false ) {
|
46 |
-
if ( ! $this->is_indexable( $object_id ) ) {
|
47 |
-
return [];
|
48 |
-
}
|
49 |
-
|
50 |
-
$indexable = WPSEO_Post_Indexable::from_object( $object_id );
|
51 |
-
|
52 |
-
if ( $as_object === true ) {
|
53 |
-
return $indexable;
|
54 |
-
}
|
55 |
-
|
56 |
-
return $indexable->to_array();
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* Handles the patching of values for an existing indexable.
|
61 |
-
*
|
62 |
-
* @param int $object_id The ID of the object.
|
63 |
-
* @param array $requestdata The request data to store.
|
64 |
-
*
|
65 |
-
* @return array The patched indexable.
|
66 |
-
*
|
67 |
-
* @throws WPSEO_Invalid_Indexable_Exception The invalid argument exception.
|
68 |
-
* @throws WPSEO_REST_Request_Exception Exception that is thrown if patching the object has failed.
|
69 |
-
*/
|
70 |
-
public function patch( $object_id, $requestdata ) {
|
71 |
-
$indexable = $this->get( $object_id, true );
|
72 |
-
|
73 |
-
if ( $indexable === [] ) {
|
74 |
-
throw WPSEO_Invalid_Indexable_Exception::non_existing_indexable( $object_id );
|
75 |
-
}
|
76 |
-
|
77 |
-
$new_indexable = $indexable->update( $requestdata );
|
78 |
-
$stored_indexable = $this->store_indexable( $new_indexable );
|
79 |
-
|
80 |
-
if ( $stored_indexable === true ) {
|
81 |
-
return $new_indexable->to_array();
|
82 |
-
}
|
83 |
-
|
84 |
-
throw WPSEO_REST_Request_Exception::patch( 'Post', $object_id );
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Stores the indexable object.
|
89 |
-
*
|
90 |
-
* @param WPSEO_Indexable $indexable The indexable object to store.
|
91 |
-
*
|
92 |
-
* @return bool True if saving was successful.
|
93 |
-
*/
|
94 |
-
protected function store_indexable( WPSEO_Indexable $indexable ) {
|
95 |
-
$values = $this->convert_indexable_data( $indexable->to_array() );
|
96 |
-
$renamed_values = $this->rename_indexable_data( $values );
|
97 |
-
|
98 |
-
foreach ( $renamed_values as $key => $item ) {
|
99 |
-
WPSEO_Meta::set_value( $key, $item, $values['object_id'] );
|
100 |
-
}
|
101 |
-
|
102 |
-
return true;
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Checks if the given object id belongs to an indexable.
|
107 |
-
*
|
108 |
-
* @param int $object_id The object id.
|
109 |
-
*
|
110 |
-
* @return bool Whether the object id is indexable.
|
111 |
-
*/
|
112 |
-
public function is_indexable( $object_id ) {
|
113 |
-
if ( get_post( $object_id ) === null ) {
|
114 |
-
return false;
|
115 |
-
}
|
116 |
-
|
117 |
-
if ( wp_is_post_autosave( $object_id ) ) {
|
118 |
-
return false;
|
119 |
-
}
|
120 |
-
|
121 |
-
if ( wp_is_post_revision( $object_id ) ) {
|
122 |
-
return false;
|
123 |
-
}
|
124 |
-
|
125 |
-
return true;
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Converts some of the indexable data to its database variant.
|
130 |
-
*
|
131 |
-
* @param array $indexable_data The indexable data to convert.
|
132 |
-
*
|
133 |
-
* @return array The converted indexable data.
|
134 |
-
*/
|
135 |
-
protected function convert_indexable_data( $indexable_data ) {
|
136 |
-
if ( WPSEO_Validator::key_exists( $indexable_data, 'is_robots_nofollow' ) ) {
|
137 |
-
$indexable_data['is_robots_nofollow'] = $this->convert_nofollow( $indexable_data['is_robots_nofollow'] );
|
138 |
-
}
|
139 |
-
|
140 |
-
if ( WPSEO_Validator::key_exists( $indexable_data, 'is_robots_noindex' ) ) {
|
141 |
-
$indexable_data['is_robots_noindex'] = $this->convert_noindex( $indexable_data['is_robots_noindex'] );
|
142 |
-
}
|
143 |
-
|
144 |
-
if ( WPSEO_Validator::key_exists( $indexable_data, 'is_cornerstone' ) ) {
|
145 |
-
$indexable_data['is_cornerstone'] = $this->convert_cornerstone( $indexable_data['is_cornerstone'] );
|
146 |
-
}
|
147 |
-
|
148 |
-
$indexable_data['meta-robots-adv'] = $this->convert_advanced( $indexable_data );
|
149 |
-
|
150 |
-
return $indexable_data;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* Converts the cornerstone value to its database variant.
|
155 |
-
*
|
156 |
-
* @param string $cornerstone_value The cornerstone value.
|
157 |
-
*
|
158 |
-
* @return string The converted indexable cornerstone value.
|
159 |
-
*/
|
160 |
-
protected function convert_cornerstone( $cornerstone_value ) {
|
161 |
-
if ( $cornerstone_value === 'true' ) {
|
162 |
-
return '1';
|
163 |
-
}
|
164 |
-
|
165 |
-
return null;
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* Converts the advanced meta settings to its database variant.
|
170 |
-
*
|
171 |
-
* @param array $indexable_data The indexable data to convert the advanced meta settings from.
|
172 |
-
*
|
173 |
-
* @return string The converted advanced meta settings.
|
174 |
-
*/
|
175 |
-
protected function convert_advanced( &$indexable_data ) {
|
176 |
-
$translated_advanced_data = [];
|
177 |
-
|
178 |
-
if ( WPSEO_Validator::key_exists( $indexable_data, 'is_robots_nosnippet' ) && (bool) $indexable_data['is_robots_nosnippet'] === true ) {
|
179 |
-
$translated_advanced_data[] = 'nosnippet';
|
180 |
-
|
181 |
-
unset( $indexable_data['is_robots_nosnippet'] );
|
182 |
-
}
|
183 |
-
|
184 |
-
if ( WPSEO_Validator::key_exists( $indexable_data, 'is_robots_noarchive' ) && (bool) $indexable_data['is_robots_noarchive'] === true ) {
|
185 |
-
$translated_advanced_data[] = 'noarchive';
|
186 |
-
|
187 |
-
unset( $indexable_data['is_robots_noarchive'] );
|
188 |
-
}
|
189 |
-
|
190 |
-
if ( WPSEO_Validator::key_exists( $indexable_data, 'is_robots_noimageindex' ) && (bool) $indexable_data['is_robots_noimageindex'] === true ) {
|
191 |
-
$translated_advanced_data[] = 'noimageindex';
|
192 |
-
|
193 |
-
unset( $indexable_data['is_robots_noimageindex'] );
|
194 |
-
}
|
195 |
-
|
196 |
-
return implode( ',', $translated_advanced_data );
|
197 |
-
}
|
198 |
-
|
199 |
-
/**
|
200 |
-
* Converts the nofollow value to a database compatible one.
|
201 |
-
*
|
202 |
-
* @param bool $nofollow The current nofollow value.
|
203 |
-
*
|
204 |
-
* @return string The converted value.
|
205 |
-
*/
|
206 |
-
protected function convert_nofollow( $nofollow ) {
|
207 |
-
if ( $nofollow === 'true' ) {
|
208 |
-
return '1';
|
209 |
-
}
|
210 |
-
|
211 |
-
return '0';
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Converts the noindex value to a database compatible one.
|
216 |
-
*
|
217 |
-
* @param string $noindex The current noindex value.
|
218 |
-
*
|
219 |
-
* @return string|null The converted value.
|
220 |
-
*/
|
221 |
-
protected function convert_noindex( $noindex ) {
|
222 |
-
if ( $noindex === 'false' ) {
|
223 |
-
return '2';
|
224 |
-
}
|
225 |
-
|
226 |
-
if ( $noindex === 'true' ) {
|
227 |
-
return '1';
|
228 |
-
}
|
229 |
-
|
230 |
-
return null;
|
231 |
-
}
|
232 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|