Version Description
Release date: November 29th, 2022
Yoast SEO 19.11 is out now. We're optimizing the Yoast SEO plugin to use fewer resources. This helps make your site faster and more efficient. In this release, we're doing this by streamlining your database. Find out more about what's new in Yoast SEO 19.11 in our release post!
Enhancements
- Adds a WP-CLI command to clean up unused data from our custom database tables:
wp yoast cleanup
. - Performs a cleanup of indexables when a public post type (or taxonomy) becomes non-public.
- Notifies users to run the SEO optimization when a non-public post type (or taxonomy) becomes public.
Bugfixes
- Fixes a bug where a fatal error would be thrown when the SEO optimization was run after a post type had been manually excluded via a filter.
- Fixes a bug where an entry would be added to our indexables table when saving, updating, or accessing a post (or term) for a non-public post type (or taxonomy).
- Fixes a bug where duplicate indexable records would be created for the same object.
- Fixes a bug where indexables for users would not get removed when a user did not have any publicly viewable posts anymore.
- Fixes a bug where indexables for users would not get removed when author archives were disabled.
- Fixes a bug where indexables would be created for users when author archives were disabled.
- Fixes a bug where indexables would be created for users who did not have any publicly viewable posts.
Other
- Introduces the
wpseo_indexable_excluded_taxonomies
filter, to allow manually excluding taxonomies from being indexed.
Download this release
Release Info
Developer | Yoast |
Plugin | Yoast SEO |
Version | 19.11 |
Comparing to | |
See all releases |
Code changes from version 19.10 to 19.11
- admin/class-gutenberg-compatibility.php +2 -2
- admin/views/tabs/metas/post-types.php +3 -0
- css/dist/{admin-global-19100-rtl.css → admin-global-19110-rtl.css} +0 -0
- css/dist/{admin-global-19100.css → admin-global-19110.css} +0 -0
- css/dist/{adminbar-19100-rtl.css → adminbar-19110-rtl.css} +0 -0
- css/dist/{adminbar-19100.css → adminbar-19110.css} +0 -0
- css/dist/{alerts-19100-rtl.css → alerts-19110-rtl.css} +0 -0
- css/dist/{alerts-19100.css → alerts-19110.css} +0 -0
- css/dist/{dashboard-19100-rtl.css → dashboard-19110-rtl.css} +0 -0
- css/dist/{dashboard-19100.css → dashboard-19110.css} +0 -0
- css/dist/{edit-page-19100-rtl.css → edit-page-19110-rtl.css} +0 -0
- css/dist/{edit-page-19100.css → edit-page-19110.css} +0 -0
- css/dist/{elementor-19100-rtl.css → elementor-19110-rtl.css} +0 -0
- css/dist/{elementor-19100.css → elementor-19110.css} +0 -0
- css/dist/{featured-image-19100-rtl.css → featured-image-19110-rtl.css} +0 -0
- css/dist/{featured-image-19100.css → featured-image-19110.css} +0 -0
- css/dist/{filter-explanation-19100-rtl.css → filter-explanation-19110-rtl.css} +0 -0
- css/dist/{filter-explanation-19100.css → filter-explanation-19110.css} +0 -0
- css/dist/{icons-19100-rtl.css → icons-19110-rtl.css} +0 -0
- css/dist/{icons-19100.css → icons-19110.css} +0 -0
- css/dist/{inside-editor-19100-rtl.css → inside-editor-19110-rtl.css} +0 -0
- css/dist/{inside-editor-19100.css → inside-editor-19110.css} +0 -0
- css/dist/{metabox-19100-rtl.css → metabox-19110-rtl.css} +0 -0
- css/dist/{metabox-19100.css → metabox-19110.css} +0 -0
- css/dist/{metabox-primary-category-19100-rtl.css → metabox-primary-category-19110-rtl.css} +0 -0
- css/dist/{metabox-primary-category-19100.css → metabox-primary-category-19110.css} +0 -0
- css/dist/{modal-19100-rtl.css → modal-19110-rtl.css} +0 -0
- css/dist/{modal-19100.css → modal-19110.css} +0 -0
- css/dist/{monorepo-19100-rtl.css → monorepo-19110-rtl.css} +0 -0
- css/dist/{monorepo-19100.css → monorepo-19110.css} +0 -0
- css/dist/{new-settings-19100-rtl.css → new-settings-19110-rtl.css} +0 -0
- css/dist/{new-settings-19100.css → new-settings-19110.css} +0 -0
- css/dist/{notifications-19100-rtl.css → notifications-19110-rtl.css} +0 -0
- css/dist/{notifications-19100.css → notifications-19110.css} +0 -0
- css/dist/{notifications-new-19100-rtl.css → notifications-new-19110-rtl.css} +0 -0
- css/dist/{notifications-new-19100.css → notifications-new-19110.css} +0 -0
- css/dist/{schema-blocks-19100-rtl.css → schema-blocks-19110-rtl.css} +0 -0
- css/dist/{schema-blocks-19100.css → schema-blocks-19110.css} +0 -0
- css/dist/{score_icon-19100-rtl.css → score_icon-19110-rtl.css} +0 -0
- css/dist/{score_icon-19100.css → score_icon-19110.css} +0 -0
- css/dist/{search-appearance-19100-rtl.css → search-appearance-19110-rtl.css} +0 -0
- css/dist/{search-appearance-19100.css → search-appearance-19110.css} +0 -0
- css/dist/{structured-data-blocks-19100-rtl.css → structured-data-blocks-19110-rtl.css} +0 -0
- css/dist/{structured-data-blocks-19100.css → structured-data-blocks-19110.css} +0 -0
- css/dist/{tailwind-19100-rtl.css → tailwind-19110-rtl.css} +0 -0
- css/dist/{tailwind-19100.css → tailwind-19110.css} +0 -0
- css/dist/{toggle-switch-19100-rtl.css → toggle-switch-19110-rtl.css} +0 -0
- css/dist/{toggle-switch-19100.css → toggle-switch-19110.css} +0 -0
- css/dist/{tooltips-19100-rtl.css → tooltips-19110-rtl.css} +0 -0
- css/dist/{tooltips-19100.css → tooltips-19110.css} +0 -0
- css/dist/{workouts-19100-rtl.css → workouts-19110-rtl.css} +0 -0
- css/dist/{workouts-19100.css → workouts-19110.css} +0 -0
- css/dist/{wpseo-dismissible-19100-rtl.css → wpseo-dismissible-19110-rtl.css} +0 -0
- css/dist/{wpseo-dismissible-19100.css → wpseo-dismissible-19110.css} +0 -0
- css/dist/{yoast-components-19100-rtl.css → yoast-components-19110-rtl.css} +0 -0
- css/dist/{yoast-components-19100.css → yoast-components-19110.css} +0 -0
- css/dist/{yoast-extensions-19100-rtl.css → yoast-extensions-19110-rtl.css} +0 -0
- css/dist/{yoast-extensions-19100.css → yoast-extensions-19110.css} +0 -0
- css/dist/{yst_plugin_tools-19100-rtl.css → yst_plugin_tools-19110-rtl.css} +0 -0
- css/dist/{yst_plugin_tools-19100.css → yst_plugin_tools-19110.css} +0 -0
- css/dist/{yst_seo_score-19100-rtl.css → yst_seo_score-19110-rtl.css} +0 -0
- css/dist/{yst_seo_score-19100.css → yst_seo_score-19110.css} +0 -0
- inc/class-post-type.php +20 -0
- inc/class-upgrade.php +241 -3
- inc/options/class-wpseo-option-wpseo.php +4 -0
- inc/sitemaps/class-author-sitemap-provider.php +1 -3
- readme.txt +33 -33
- src/actions/indexing/indexable-post-indexation-action.php +2 -15
- src/actions/indexing/indexable-term-indexation-action.php +5 -4
- src/actions/indexing/post-link-indexing-action.php +2 -2
- src/actions/indexing/term-link-indexing-action.php +5 -4
- src/builders/indexable-author-builder.php +39 -0
- src/builders/indexable-builder.php +52 -23
- src/builders/indexable-post-builder.php +4 -2
- src/builders/indexable-term-builder.php +8 -1
- src/commands/cleanup-command.php +196 -0
- src/config/indexing-reasons.php +10 -0
- src/exceptions/indexable/author-not-built-exception.php +51 -0
- src/exceptions/indexable/not-built-exception.php +23 -0
- src/exceptions/indexable/post-not-built-exception.php +34 -0
- src/exceptions/indexable/term-not-built-exception.php +22 -0
- src/generated/container.php +71 -7
- src/generators/schema/breadcrumb.php +4 -0
- src/generators/schema/webpage.php +3 -0
- src/helpers/author-archive-helper.php +66 -0
- src/helpers/post-helper.php +22 -3
- src/helpers/post-type-helper.php +13 -0
- src/helpers/taxonomy-helper.php +47 -0
- src/integrations/admin/indexables-exclude-taxonomy-integration.php +53 -0
- src/integrations/cleanup-integration.php +207 -1
- src/integrations/watchers/indexable-author-archive-watcher.php +58 -0
- src/integrations/watchers/indexable-post-type-change-watcher.php +184 -0
- src/integrations/watchers/indexable-post-watcher.php +35 -4
- src/integrations/watchers/indexable-taxonomy-change-watcher.php +186 -0
- src/presentations/indexable-term-archive-presentation.php +5 -1
- src/presenters/admin/indexing-notification-presenter.php +6 -0
- src/routes/indexing-route.php +0 -2
- src/routes/yoast-head-rest-field.php +2 -2
- vendor/autoload.php +1 -1
- vendor/composer/autoload_classmap.php +9 -0
- vendor/composer/autoload_real.php +4 -4
- vendor/composer/autoload_static.php +13 -4
- vendor/composer/installed.php +2 -2
- wp-seo-main.php +2 -2
- wp-seo.php +1 -1
admin/class-gutenberg-compatibility.php
CHANGED
@@ -15,14 +15,14 @@ class WPSEO_Gutenberg_Compatibility {
|
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
-
const CURRENT_RELEASE = '14.
|
19 |
|
20 |
/**
|
21 |
* The minimally supported version of Gutenberg by the plugin.
|
22 |
*
|
23 |
* @var string
|
24 |
*/
|
25 |
-
const MINIMUM_SUPPORTED = '14.
|
26 |
|
27 |
/**
|
28 |
* Holds the current version.
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
+
const CURRENT_RELEASE = '14.5.0';
|
19 |
|
20 |
/**
|
21 |
* The minimally supported version of Gutenberg by the plugin.
|
22 |
*
|
23 |
* @var string
|
24 |
*/
|
25 |
+
const MINIMUM_SUPPORTED = '14.5.0';
|
26 |
|
27 |
/**
|
28 |
* Holds the current version.
|
admin/views/tabs/metas/post-types.php
CHANGED
@@ -11,6 +11,9 @@ if ( ! defined( 'WPSEO_VERSION' ) ) {
|
|
11 |
exit();
|
12 |
}
|
13 |
|
|
|
|
|
|
|
14 |
/*
|
15 |
* WPSEO_Post_Type::get_accessible_post_types() should *not* be used here.
|
16 |
* Otherwise setting a post-type to `noindex` will remove it from the list,
|
11 |
exit();
|
12 |
}
|
13 |
|
14 |
+
WPSEO_Post_Type::remove_post_types_made_public_notification();
|
15 |
+
WPSEO_Post_Type::remove_taxonomies_made_public_notification();
|
16 |
+
|
17 |
/*
|
18 |
* WPSEO_Post_Type::get_accessible_post_types() should *not* be used here.
|
19 |
* Otherwise setting a post-type to `noindex` will remove it from the list,
|
css/dist/{admin-global-19100-rtl.css → admin-global-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{admin-global-19100.css → admin-global-19110.css}
RENAMED
File without changes
|
css/dist/{adminbar-19100-rtl.css → adminbar-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{adminbar-19100.css → adminbar-19110.css}
RENAMED
File without changes
|
css/dist/{alerts-19100-rtl.css → alerts-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{alerts-19100.css → alerts-19110.css}
RENAMED
File without changes
|
css/dist/{dashboard-19100-rtl.css → dashboard-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{dashboard-19100.css → dashboard-19110.css}
RENAMED
File without changes
|
css/dist/{edit-page-19100-rtl.css → edit-page-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{edit-page-19100.css → edit-page-19110.css}
RENAMED
File without changes
|
css/dist/{elementor-19100-rtl.css → elementor-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{elementor-19100.css → elementor-19110.css}
RENAMED
File without changes
|
css/dist/{featured-image-19100-rtl.css → featured-image-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{featured-image-19100.css → featured-image-19110.css}
RENAMED
File without changes
|
css/dist/{filter-explanation-19100-rtl.css → filter-explanation-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{filter-explanation-19100.css → filter-explanation-19110.css}
RENAMED
File without changes
|
css/dist/{icons-19100-rtl.css → icons-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{icons-19100.css → icons-19110.css}
RENAMED
File without changes
|
css/dist/{inside-editor-19100-rtl.css → inside-editor-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{inside-editor-19100.css → inside-editor-19110.css}
RENAMED
File without changes
|
css/dist/{metabox-19100-rtl.css → metabox-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{metabox-19100.css → metabox-19110.css}
RENAMED
File without changes
|
css/dist/{metabox-primary-category-19100-rtl.css → metabox-primary-category-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{metabox-primary-category-19100.css → metabox-primary-category-19110.css}
RENAMED
File without changes
|
css/dist/{modal-19100-rtl.css → modal-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{modal-19100.css → modal-19110.css}
RENAMED
File without changes
|
css/dist/{monorepo-19100-rtl.css → monorepo-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{monorepo-19100.css → monorepo-19110.css}
RENAMED
File without changes
|
css/dist/{new-settings-19100-rtl.css → new-settings-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{new-settings-19100.css → new-settings-19110.css}
RENAMED
File without changes
|
css/dist/{notifications-19100-rtl.css → notifications-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{notifications-19100.css → notifications-19110.css}
RENAMED
File without changes
|
css/dist/{notifications-new-19100-rtl.css → notifications-new-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{notifications-new-19100.css → notifications-new-19110.css}
RENAMED
File without changes
|
css/dist/{schema-blocks-19100-rtl.css → schema-blocks-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{schema-blocks-19100.css → schema-blocks-19110.css}
RENAMED
File without changes
|
css/dist/{score_icon-19100-rtl.css → score_icon-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{score_icon-19100.css → score_icon-19110.css}
RENAMED
File without changes
|
css/dist/{search-appearance-19100-rtl.css → search-appearance-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{search-appearance-19100.css → search-appearance-19110.css}
RENAMED
File without changes
|
css/dist/{structured-data-blocks-19100-rtl.css → structured-data-blocks-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{structured-data-blocks-19100.css → structured-data-blocks-19110.css}
RENAMED
File without changes
|
css/dist/{tailwind-19100-rtl.css → tailwind-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{tailwind-19100.css → tailwind-19110.css}
RENAMED
File without changes
|
css/dist/{toggle-switch-19100-rtl.css → toggle-switch-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{toggle-switch-19100.css → toggle-switch-19110.css}
RENAMED
File without changes
|
css/dist/{tooltips-19100-rtl.css → tooltips-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{tooltips-19100.css → tooltips-19110.css}
RENAMED
File without changes
|
css/dist/{workouts-19100-rtl.css → workouts-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{workouts-19100.css → workouts-19110.css}
RENAMED
File without changes
|
css/dist/{wpseo-dismissible-19100-rtl.css → wpseo-dismissible-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{wpseo-dismissible-19100.css → wpseo-dismissible-19110.css}
RENAMED
File without changes
|
css/dist/{yoast-components-19100-rtl.css → yoast-components-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{yoast-components-19100.css → yoast-components-19110.css}
RENAMED
File without changes
|
css/dist/{yoast-extensions-19100-rtl.css → yoast-extensions-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{yoast-extensions-19100.css → yoast-extensions-19110.css}
RENAMED
File without changes
|
css/dist/{yst_plugin_tools-19100-rtl.css → yst_plugin_tools-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{yst_plugin_tools-19100.css → yst_plugin_tools-19110.css}
RENAMED
File without changes
|
css/dist/{yst_seo_score-19100-rtl.css → yst_seo_score-19110-rtl.css}
RENAMED
File without changes
|
css/dist/{yst_seo_score-19100.css → yst_seo_score-19110.css}
RENAMED
File without changes
|
inc/class-post-type.php
CHANGED
@@ -98,4 +98,24 @@ class WPSEO_Post_Type {
|
|
98 |
public static function has_metabox_enabled( $post_type ) {
|
99 |
return WPSEO_Options::get( 'display-metabox-pt-' . $post_type, false );
|
100 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
}
|
98 |
public static function has_metabox_enabled( $post_type ) {
|
99 |
return WPSEO_Options::get( 'display-metabox-pt-' . $post_type, false );
|
100 |
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Removes the notification related to the post types which have been made public.
|
104 |
+
*
|
105 |
+
* @return void
|
106 |
+
*/
|
107 |
+
public static function remove_post_types_made_public_notification() {
|
108 |
+
$notification_center = Yoast_Notification_Center::get();
|
109 |
+
$notification_center->remove_notification_by_id( 'post-types-made-public' );
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Removes the notification related to the taxonomies which have been made public.
|
114 |
+
*
|
115 |
+
* @return void
|
116 |
+
*/
|
117 |
+
public static function remove_taxonomies_made_public_notification() {
|
118 |
+
$notification_center = Yoast_Notification_Center::get();
|
119 |
+
$notification_center->remove_notification_by_id( 'taxonomies-made-public' );
|
120 |
+
}
|
121 |
}
|
inc/class-upgrade.php
CHANGED
@@ -6,6 +6,12 @@
|
|
6 |
*/
|
7 |
|
8 |
use Yoast\WP\Lib\Model;
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
/**
|
11 |
* This code handles the option upgrades.
|
@@ -82,10 +88,10 @@ class WPSEO_Upgrade {
|
|
82 |
'19.1-RC0' => 'upgrade_191',
|
83 |
'19.3-RC0' => 'upgrade_193',
|
84 |
'19.6-RC0' => 'upgrade_196',
|
|
|
85 |
];
|
86 |
|
87 |
array_walk( $routines, [ $this, 'run_upgrade_routine' ], $version );
|
88 |
-
|
89 |
if ( version_compare( $version, '12.5-RC0', '<' ) ) {
|
90 |
/*
|
91 |
* We have to run this by hook, because otherwise:
|
@@ -847,8 +853,8 @@ class WPSEO_Upgrade {
|
|
847 |
\wp_unschedule_hook( 'wpseo_cleanup_orphaned_indexables' );
|
848 |
\wp_unschedule_hook( 'wpseo_cleanup_indexables' );
|
849 |
|
850 |
-
if ( ! \wp_next_scheduled(
|
851 |
-
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ),
|
852 |
}
|
853 |
}
|
854 |
|
@@ -948,6 +954,19 @@ class WPSEO_Upgrade {
|
|
948 |
wp_clear_scheduled_hook( 'wpseo_ryte_fetch' );
|
949 |
}
|
950 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
951 |
/**
|
952 |
* Sets the home_url option for the 15.1 upgrade routine.
|
953 |
*
|
@@ -1341,4 +1360,223 @@ class WPSEO_Upgrade {
|
|
1341 |
|
1342 |
update_option( 'wpseo_titles', $wpseo_titles );
|
1343 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1344 |
}
|
6 |
*/
|
7 |
|
8 |
use Yoast\WP\Lib\Model;
|
9 |
+
use Yoast\WP\SEO\Helpers\Author_Archive_Helper;
|
10 |
+
use Yoast\WP\SEO\Helpers\Options_Helper;
|
11 |
+
use Yoast\WP\SEO\Helpers\Post_Type_Helper;
|
12 |
+
use Yoast\WP\SEO\Helpers\String_Helper;
|
13 |
+
use Yoast\WP\SEO\Helpers\Taxonomy_Helper;
|
14 |
+
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
15 |
|
16 |
/**
|
17 |
* This code handles the option upgrades.
|
88 |
'19.1-RC0' => 'upgrade_191',
|
89 |
'19.3-RC0' => 'upgrade_193',
|
90 |
'19.6-RC0' => 'upgrade_196',
|
91 |
+
'19.11-RC0' => 'upgrade_1911',
|
92 |
];
|
93 |
|
94 |
array_walk( $routines, [ $this, 'run_upgrade_routine' ], $version );
|
|
|
95 |
if ( version_compare( $version, '12.5-RC0', '<' ) ) {
|
96 |
/*
|
97 |
* We have to run this by hook, because otherwise:
|
853 |
\wp_unschedule_hook( 'wpseo_cleanup_orphaned_indexables' );
|
854 |
\wp_unschedule_hook( 'wpseo_cleanup_indexables' );
|
855 |
|
856 |
+
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
857 |
+
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
858 |
}
|
859 |
}
|
860 |
|
954 |
wp_clear_scheduled_hook( 'wpseo_ryte_fetch' );
|
955 |
}
|
956 |
|
957 |
+
/**
|
958 |
+
* Performs the 19.11 upgrade routine.
|
959 |
+
*/
|
960 |
+
private function upgrade_1911() {
|
961 |
+
\add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_post_types' ] );
|
962 |
+
\add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_taxonomies' ] );
|
963 |
+
$this->deduplicate_unindexed_indexable_rows();
|
964 |
+
$this->remove_indexable_rows_for_disabled_authors_archive();
|
965 |
+
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
966 |
+
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
967 |
+
}
|
968 |
+
}
|
969 |
+
|
970 |
/**
|
971 |
* Sets the home_url option for the 15.1 upgrade routine.
|
972 |
*
|
1360 |
|
1361 |
update_option( 'wpseo_titles', $wpseo_titles );
|
1362 |
}
|
1363 |
+
|
1364 |
+
/**
|
1365 |
+
* Removes all indexables for posts that are not publicly viewable.
|
1366 |
+
* This method should be called after init, because post_types can still be registered.
|
1367 |
+
*
|
1368 |
+
* @return void
|
1369 |
+
*/
|
1370 |
+
public function remove_indexable_rows_for_non_public_post_types() {
|
1371 |
+
global $wpdb;
|
1372 |
+
|
1373 |
+
// If migrations haven't been completed successfully the following may give false errors. So suppress them.
|
1374 |
+
$show_errors = $wpdb->show_errors;
|
1375 |
+
$wpdb->show_errors = false;
|
1376 |
+
|
1377 |
+
$indexable_table = Model::get_table_name( 'Indexable' );
|
1378 |
+
|
1379 |
+
$included_post_types = \YoastSEO()->helpers->post_type->get_indexable_post_types();
|
1380 |
+
|
1381 |
+
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
|
1382 |
+
if ( empty( $included_post_types ) ) {
|
1383 |
+
$delete_query =
|
1384 |
+
"DELETE FROM $indexable_table
|
1385 |
+
WHERE object_type = 'post'
|
1386 |
+
AND object_sub_type IS NOT NULL";
|
1387 |
+
}
|
1388 |
+
else {
|
1389 |
+
$delete_query = $wpdb->prepare(
|
1390 |
+
"DELETE FROM $indexable_table
|
1391 |
+
WHERE object_type = 'post'
|
1392 |
+
AND object_sub_type IS NOT NULL
|
1393 |
+
AND object_sub_type NOT IN ( " . \implode( ', ', \array_fill( 0, \count( $included_post_types ), '%s' ) ) . ' )',
|
1394 |
+
$included_post_types
|
1395 |
+
);
|
1396 |
+
}
|
1397 |
+
// phpcs:enable
|
1398 |
+
|
1399 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
|
1400 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
1401 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
|
1402 |
+
$wpdb->query( $delete_query );
|
1403 |
+
// phpcs:enable
|
1404 |
+
|
1405 |
+
$wpdb->show_errors = $show_errors;
|
1406 |
+
}
|
1407 |
+
|
1408 |
+
/**
|
1409 |
+
* Removes all indexables for terms that are not publicly viewable.
|
1410 |
+
* This method should be called after init, because taxonomies can still be registered.
|
1411 |
+
*
|
1412 |
+
* @return void
|
1413 |
+
*/
|
1414 |
+
public function remove_indexable_rows_for_non_public_taxonomies() {
|
1415 |
+
global $wpdb;
|
1416 |
+
|
1417 |
+
// If migrations haven't been completed successfully the following may give false errors. So suppress them.
|
1418 |
+
$show_errors = $wpdb->show_errors;
|
1419 |
+
$wpdb->show_errors = false;
|
1420 |
+
|
1421 |
+
$indexable_table = Model::get_table_name( 'Indexable' );
|
1422 |
+
|
1423 |
+
$included_taxonomies = \YoastSEO()->helpers->taxonomy->get_indexable_taxonomies();
|
1424 |
+
|
1425 |
+
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
|
1426 |
+
if ( empty( $included_taxonomies ) ) {
|
1427 |
+
$delete_query = "DELETE FROM $indexable_table
|
1428 |
+
WHERE object_type = 'term'
|
1429 |
+
AND object_sub_type IS NOT NULL";
|
1430 |
+
}
|
1431 |
+
else {
|
1432 |
+
$delete_query = $wpdb->prepare(
|
1433 |
+
"DELETE FROM $indexable_table
|
1434 |
+
WHERE object_type = 'term'
|
1435 |
+
AND object_sub_type IS NOT NULL
|
1436 |
+
AND object_sub_type NOT IN ( " . \implode( ', ', \array_fill( 0, \count( $included_taxonomies ), '%s' ) ) . ' )',
|
1437 |
+
$included_taxonomies
|
1438 |
+
);
|
1439 |
+
}
|
1440 |
+
// phpcs:enable
|
1441 |
+
|
1442 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
|
1443 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
1444 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
|
1445 |
+
$wpdb->query( $delete_query );
|
1446 |
+
// phpcs:enable
|
1447 |
+
|
1448 |
+
$wpdb->show_errors = $show_errors;
|
1449 |
+
}
|
1450 |
+
|
1451 |
+
/**
|
1452 |
+
* De-duplicates indexables that have more than one "unindexed" rows for the same object. Keeps the newest indexable.
|
1453 |
+
*
|
1454 |
+
* @return void
|
1455 |
+
*/
|
1456 |
+
private function deduplicate_unindexed_indexable_rows() {
|
1457 |
+
global $wpdb;
|
1458 |
+
|
1459 |
+
// If migrations haven't been completed successfully the following may give false errors. So suppress them.
|
1460 |
+
$show_errors = $wpdb->show_errors;
|
1461 |
+
$wpdb->show_errors = false;
|
1462 |
+
|
1463 |
+
$indexable_table = Model::get_table_name( 'Indexable' );
|
1464 |
+
|
1465 |
+
$query =
|
1466 |
+
"SELECT
|
1467 |
+
MAX(id) as newest_id,
|
1468 |
+
object_id,
|
1469 |
+
object_type
|
1470 |
+
FROM
|
1471 |
+
$indexable_table
|
1472 |
+
WHERE
|
1473 |
+
post_status = 'unindexed'
|
1474 |
+
AND object_type IN ( 'term', 'post', 'user' )
|
1475 |
+
GROUP BY
|
1476 |
+
object_id,
|
1477 |
+
object_type
|
1478 |
+
HAVING
|
1479 |
+
count(*) > 1";
|
1480 |
+
|
1481 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
|
1482 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
1483 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
|
1484 |
+
$duplicates = $wpdb->get_results( $query, ARRAY_A );
|
1485 |
+
// phpcs:enable
|
1486 |
+
|
1487 |
+
if ( empty( $duplicates ) ) {
|
1488 |
+
$wpdb->show_errors = $show_errors;
|
1489 |
+
|
1490 |
+
return;
|
1491 |
+
}
|
1492 |
+
|
1493 |
+
// Users, terms and posts may share the same object_id. So delete them in separate, more performant, queries.
|
1494 |
+
$delete_queries = [
|
1495 |
+
$this->get_indexable_deduplication_query_for_type( 'post', $duplicates, $wpdb ),
|
1496 |
+
$this->get_indexable_deduplication_query_for_type( 'term', $duplicates, $wpdb ),
|
1497 |
+
$this->get_indexable_deduplication_query_for_type( 'user', $duplicates, $wpdb ),
|
1498 |
+
];
|
1499 |
+
|
1500 |
+
foreach ( $delete_queries as $delete_query ) {
|
1501 |
+
if ( ! empty( $delete_query ) ) {
|
1502 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
|
1503 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
1504 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
|
1505 |
+
$wpdb->query( $delete_query );
|
1506 |
+
// phpcs:enable
|
1507 |
+
}
|
1508 |
+
}
|
1509 |
+
|
1510 |
+
$wpdb->show_errors = $show_errors;
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
/**
|
1514 |
+
* Removes all user indexable rows when the author archive is disabled.
|
1515 |
+
*
|
1516 |
+
* @return void
|
1517 |
+
*/
|
1518 |
+
private function remove_indexable_rows_for_disabled_authors_archive() {
|
1519 |
+
global $wpdb;
|
1520 |
+
|
1521 |
+
if ( ! \YoastSEO()->helpers->author_archive->are_disabled() ) {
|
1522 |
+
return;
|
1523 |
+
}
|
1524 |
+
|
1525 |
+
// If migrations haven't been completed successfully the following may give false errors. So suppress them.
|
1526 |
+
$show_errors = $wpdb->show_errors;
|
1527 |
+
$wpdb->show_errors = false;
|
1528 |
+
|
1529 |
+
$indexable_table = Model::get_table_name( 'Indexable' );
|
1530 |
+
|
1531 |
+
$delete_query = "DELETE FROM $indexable_table WHERE object_type = 'user'";
|
1532 |
+
// phpcs:enable
|
1533 |
+
|
1534 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
1535 |
+
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
|
1536 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
|
1537 |
+
$wpdb->query( $delete_query );
|
1538 |
+
// phpcs:enable
|
1539 |
+
|
1540 |
+
$wpdb->show_errors = $show_errors;
|
1541 |
+
}
|
1542 |
+
|
1543 |
+
/**
|
1544 |
+
* Creates a query for de-duplicating indexables for a particular type.
|
1545 |
+
*
|
1546 |
+
* @param string $object_type The object type to deduplicate.
|
1547 |
+
* @param array $duplicates The result of the duplicate query.
|
1548 |
+
* @param wpdb $wpdb The wpdb object.
|
1549 |
+
*
|
1550 |
+
* @return string The query that removes all but one duplicate for each object of the object type.
|
1551 |
+
*/
|
1552 |
+
private function get_indexable_deduplication_query_for_type( $object_type, $duplicates, $wpdb ) {
|
1553 |
+
$indexable_table = Model::get_table_name( 'Indexable' );
|
1554 |
+
|
1555 |
+
$filtered_duplicates = \array_filter(
|
1556 |
+
$duplicates,
|
1557 |
+
static function ( $duplicate ) use ( $object_type ) {
|
1558 |
+
return $duplicate['object_type'] === $object_type;
|
1559 |
+
}
|
1560 |
+
);
|
1561 |
+
|
1562 |
+
if ( empty( $filtered_duplicates ) ) {
|
1563 |
+
return '';
|
1564 |
+
}
|
1565 |
+
|
1566 |
+
$object_ids = wp_list_pluck( $filtered_duplicates, 'object_id' );
|
1567 |
+
$newest_indexable_ids = wp_list_pluck( $filtered_duplicates, 'newest_id' );
|
1568 |
+
|
1569 |
+
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
|
1570 |
+
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber -- Reason: we're passing an array instead.
|
1571 |
+
return $wpdb->prepare(
|
1572 |
+
"DELETE FROM
|
1573 |
+
$indexable_table
|
1574 |
+
WHERE
|
1575 |
+
object_id IN ( " . \implode( ', ', \array_fill( 0, \count( $filtered_duplicates ), '%d' ) ) . ' )
|
1576 |
+
AND id NOT IN ( ' . \implode( ', ', \array_fill( 0, \count( $filtered_duplicates ), '%d' ) ) . ' )
|
1577 |
+
AND object_type = %s',
|
1578 |
+
array_merge( array_values( $object_ids ), array_values( $newest_indexable_ids ), [ $object_type ] )
|
1579 |
+
);
|
1580 |
+
// phpcs:enable
|
1581 |
+
}
|
1582 |
}
|
inc/options/class-wpseo-option-wpseo.php
CHANGED
@@ -131,6 +131,8 @@ class WPSEO_Option_Wpseo extends WPSEO_Option {
|
|
131 |
'least_linked_ignore_list' => [],
|
132 |
'indexables_page_reading_list' => [ false, false, false, false, false ],
|
133 |
'indexables_overview_state' => 'dashboard-not-visited',
|
|
|
|
|
134 |
];
|
135 |
|
136 |
/**
|
@@ -400,6 +402,8 @@ class WPSEO_Option_Wpseo extends WPSEO_Option {
|
|
400 |
case 'most_linked_ignore_list':
|
401 |
case 'least_linked_ignore_list':
|
402 |
case 'indexables_page_reading_list':
|
|
|
|
|
403 |
$clean[ $key ] = $old[ $key ];
|
404 |
|
405 |
if ( isset( $dirty[ $key ] ) ) {
|
131 |
'least_linked_ignore_list' => [],
|
132 |
'indexables_page_reading_list' => [ false, false, false, false, false ],
|
133 |
'indexables_overview_state' => 'dashboard-not-visited',
|
134 |
+
'last_known_public_post_types' => [],
|
135 |
+
'last_known_public_taxonomies' => [],
|
136 |
];
|
137 |
|
138 |
/**
|
402 |
case 'most_linked_ignore_list':
|
403 |
case 'least_linked_ignore_list':
|
404 |
case 'indexables_page_reading_list':
|
405 |
+
case 'last_known_public_post_types':
|
406 |
+
case 'last_known_public_taxonomies':
|
407 |
$clean[ $key ] = $old[ $key ];
|
408 |
|
409 |
if ( isset( $dirty[ $key ] ) ) {
|
inc/sitemaps/class-author-sitemap-provider.php
CHANGED
@@ -5,7 +5,6 @@
|
|
5 |
* @package WPSEO\XML_Sitemaps
|
6 |
*/
|
7 |
|
8 |
-
use Yoast\WP\SEO\Helpers\Author_Archive_Helper;
|
9 |
use Yoast\WP\SEO\Helpers\Wordpress_Helper;
|
10 |
|
11 |
/**
|
@@ -131,8 +130,7 @@ class WPSEO_Author_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
|
131 |
|
132 |
if ( WPSEO_Options::get( 'noindex-author-noposts-wpseo', true ) ) {
|
133 |
unset( $defaults['who'], $defaults['capability'] ); // Otherwise it cancels out next argument.
|
134 |
-
$
|
135 |
-
$defaults['has_published_posts'] = $author_archive->get_author_archive_post_types();
|
136 |
}
|
137 |
|
138 |
return get_users( array_merge( $defaults, $arguments ) );
|
5 |
* @package WPSEO\XML_Sitemaps
|
6 |
*/
|
7 |
|
|
|
8 |
use Yoast\WP\SEO\Helpers\Wordpress_Helper;
|
9 |
|
10 |
/**
|
130 |
|
131 |
if ( WPSEO_Options::get( 'noindex-author-noposts-wpseo', true ) ) {
|
132 |
unset( $defaults['who'], $defaults['capability'] ); // Otherwise it cancels out next argument.
|
133 |
+
$defaults['has_published_posts'] = YoastSEO()->helpers->author_archive->get_author_archive_post_types();
|
|
|
134 |
}
|
135 |
|
136 |
return get_users( array_merge( $defaults, $arguments ) );
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ License: GPLv3
|
|
5 |
License URI: http://www.gnu.org/licenses/gpl.html
|
6 |
Tags: SEO, XML sitemap, Content analysis, Readability, Schema
|
7 |
Tested up to: 6.1
|
8 |
-
Stable tag: 19.
|
9 |
Requires PHP: 5.6.20
|
10 |
|
11 |
Improve your WordPress SEO: Write better content and have a fully optimized WordPress site using the Yoast SEO plugin.
|
@@ -245,53 +245,53 @@ Your question has most likely been answered on our help center: [yoast.com/help/
|
|
245 |
|
246 |
== Changelog ==
|
247 |
|
248 |
-
= 19.
|
249 |
-
Release Date: November 8th, 2022
|
250 |
|
251 |
-
|
252 |
|
253 |
-
|
|
|
|
|
254 |
|
255 |
-
*
|
|
|
|
|
256 |
|
257 |
-
Bugfixes
|
258 |
|
259 |
-
* Fixes a bug where a fatal error would be thrown
|
260 |
-
* Fixes a bug where
|
261 |
-
* Fixes a bug where
|
|
|
|
|
|
|
|
|
262 |
|
263 |
-
Other
|
264 |
|
265 |
-
*
|
266 |
-
* Ensures compatibility with the _High Performance Order Storage_ feature in WooCommerce 7.1+.
|
267 |
-
* Sets the WordPress tested up to version to 6.1.
|
268 |
|
269 |
-
= 19.
|
270 |
-
Release Date: October 25th, 2022
|
271 |
|
272 |
-
|
273 |
|
274 |
-
|
275 |
|
276 |
-
|
277 |
-
* Improves the Schema output for Organization by no longer putting out an empty array if no social profiles have been added for it.
|
278 |
-
* Adds immediate keyphrase tracking after connecting to Wincher.
|
279 |
|
280 |
-
|
281 |
|
282 |
-
|
283 |
-
* Fixes a bug where social or canonical URLs containing `@` would lead to encoding issues. Props to [@stodorovic](https://github.com/stodorovic).
|
284 |
-
* Fixes a bug where the buttons in the _FAQ_ and in the _how-to_ block would be hardly visible when using a dark theme.
|
285 |
-
* Fixes a bug where the number of words would be counted incorrectly when using Cyrillic script. Props to [kudinovfedor](https://github.com/kudinovfedor).
|
286 |
-
* Fixes a bug where the _previously used keyphrase_ assessment would also appear under the readability analysis tab when the cornerstone content toggle would be switched on.
|
287 |
-
* Fixes a bug where the SEO optimization routine would give an error when an image file of an image linked in a post could not be retrieved.
|
288 |
-
* Fixes a bug where the wrong canonical URL would be set on attachment pages.
|
289 |
|
290 |
-
|
|
|
|
|
|
|
|
|
291 |
|
292 |
-
*
|
293 |
-
*
|
294 |
-
*
|
295 |
|
296 |
= Earlier versions =
|
297 |
For the changelog of earlier versions, please refer to [the changelog on yoast.com](https://yoa.st/yoast-seo-changelog).
|
5 |
License URI: http://www.gnu.org/licenses/gpl.html
|
6 |
Tags: SEO, XML sitemap, Content analysis, Readability, Schema
|
7 |
Tested up to: 6.1
|
8 |
+
Stable tag: 19.11
|
9 |
Requires PHP: 5.6.20
|
10 |
|
11 |
Improve your WordPress SEO: Write better content and have a fully optimized WordPress site using the Yoast SEO plugin.
|
245 |
|
246 |
== Changelog ==
|
247 |
|
248 |
+
= 19.11 =
|
|
|
249 |
|
250 |
+
Release date: November 29th, 2022
|
251 |
|
252 |
+
Yoast SEO 19.11 is out now. We're optimizing the Yoast SEO plugin to use fewer resources. This helps make your site faster and more efficient. In this release, we're doing this by streamlining your database. Find out more about what's new in Yoast SEO 19.11 in [our release post](https://yoa.st/release-29-11-22)!
|
253 |
+
|
254 |
+
#### Enhancements
|
255 |
|
256 |
+
* Adds a WP-CLI command to clean up unused data from our custom database tables: `wp yoast cleanup`.
|
257 |
+
* Performs a cleanup of indexables when a public post type (or taxonomy) becomes non-public.
|
258 |
+
* Notifies users to run the SEO optimization when a non-public post type (or taxonomy) becomes public.
|
259 |
|
260 |
+
#### Bugfixes
|
261 |
|
262 |
+
* Fixes a bug where a fatal error would be thrown when the SEO optimization was run after a post type had been manually excluded via a filter.
|
263 |
+
* Fixes a bug where an entry would be added to our indexables table when saving, updating, or accessing a post (or term) for a non-public post type (or taxonomy).
|
264 |
+
* Fixes a bug where duplicate indexable records would be created for the same object.
|
265 |
+
* Fixes a bug where indexables for users would not get removed when a user did not have any publicly viewable posts anymore.
|
266 |
+
* Fixes a bug where indexables for users would not get removed when author archives were disabled.
|
267 |
+
* Fixes a bug where indexables would be created for users when author archives were disabled.
|
268 |
+
* Fixes a bug where indexables would be created for users who did not have any publicly viewable posts.
|
269 |
|
270 |
+
#### Other
|
271 |
|
272 |
+
* Introduces the `wpseo_indexable_excluded_taxonomies` filter, to allow manually excluding taxonomies from being indexed.
|
|
|
|
|
273 |
|
274 |
+
= 19.10 =
|
|
|
275 |
|
276 |
+
Release date: November 8th, 2022
|
277 |
|
278 |
+
Yoast SEO 19.10 is out today. This release mostly consists of bug fixes and enhancements. In addition, we're getting our WordPress plugins ready for the upcoming High Performance Order Storage feature in WooCommerce 7.1+. Update now! Read more about what's new in Yoast SEO 19.10 in [our release post in English](https://yoa.st/release-8-11-22) or [our release post in Spanish](https://yoa.st/release-8-11-22-spanish)!
|
279 |
|
280 |
+
#### Enhancements
|
|
|
|
|
281 |
|
282 |
+
* Improves the call-to-action feedback string of the Flesch Reading Ease insight when the text is recognized as fairly difficult.
|
283 |
|
284 |
+
#### Bugfixes
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
|
286 |
+
* Fixes a bug where a fatal error would be thrown in the classic editor in combination with certain plugins that misuse metabox hooks.
|
287 |
+
* Fixes a bug where users with site-wide basic access authentication would be prompted to insert their credentials when saving a post in Elementor if they didn’t have the manage_options capability.
|
288 |
+
* Fixes a bug where Yoast SEO-related post meta data would not be saved if a user without the manage_options capability would save a post in Elementor.
|
289 |
+
|
290 |
+
#### Other
|
291 |
|
292 |
+
* Deprecates the hooks used to add custom content to the Yoast SEO settings pages, in preparation for future releases. The following hooks have been deprecated: wpseo_tools_overview_list_items, wpseo_settings_tab_crawl_cleanup, wpseo_settings_tab_site_analysis, Yoast\WP\SEOdmin_author_archives_meta, Yoast\WP\SEOdmin_date_archives_meta, Yoast\WP\SEOdmin_post_types_beforearchive, Yoast\WP\SEOdmin_post_types_archive, Yoast\WP\SEOdmin_taxonomies_meta, wpseo_admin_other_section, wpseo_admin_opengraph_section, wpseo_admin_pinterest_section, wpseo_admin_twitter_section, wpseo_import_other_plugins.
|
293 |
+
* Ensures compatibility with the High Performance Order Storage feature in WooCommerce 7.1+.
|
294 |
+
* Sets the WordPress tested up to version to 6.1.
|
295 |
|
296 |
= Earlier versions =
|
297 |
For the changelog of earlier versions, please refer to [the changelog on yoast.com](https://yoa.st/yoast-seo-changelog).
|
src/actions/indexing/indexable-post-indexation-action.php
CHANGED
@@ -139,7 +139,7 @@ class Indexable_Post_Indexation_Action extends Abstract_Indexing_Action {
|
|
139 |
protected function get_count_query() {
|
140 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
141 |
|
142 |
-
$post_types = $this->
|
143 |
$excluded_post_statuses = $this->post_helper->get_excluded_post_statuses();
|
144 |
$replacements = \array_merge(
|
145 |
$post_types,
|
@@ -174,7 +174,7 @@ class Indexable_Post_Indexation_Action extends Abstract_Indexing_Action {
|
|
174 |
protected function get_select_query( $limit = false ) {
|
175 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
176 |
|
177 |
-
$post_types = $this->
|
178 |
$excluded_post_statuses = $this->post_helper->get_excluded_post_statuses();
|
179 |
$replacements = \array_merge(
|
180 |
$post_types,
|
@@ -204,17 +204,4 @@ class Indexable_Post_Indexation_Action extends Abstract_Indexing_Action {
|
|
204 |
$replacements
|
205 |
);
|
206 |
}
|
207 |
-
|
208 |
-
/**
|
209 |
-
* Returns the post types that should be indexed.
|
210 |
-
*
|
211 |
-
* @return array The post types that should be indexed.
|
212 |
-
*/
|
213 |
-
protected function get_post_types() {
|
214 |
-
$public_post_types = $this->post_type_helper->get_public_post_types();
|
215 |
-
$excluded_post_types = $this->post_type_helper->get_excluded_post_types_for_indexables();
|
216 |
-
|
217 |
-
// `array_values`, to make sure that the keys are reset.
|
218 |
-
return \array_values( \array_diff( $public_post_types, $excluded_post_types ) );
|
219 |
-
}
|
220 |
}
|
139 |
protected function get_count_query() {
|
140 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
141 |
|
142 |
+
$post_types = $this->post_type_helper->get_indexable_post_types();
|
143 |
$excluded_post_statuses = $this->post_helper->get_excluded_post_statuses();
|
144 |
$replacements = \array_merge(
|
145 |
$post_types,
|
174 |
protected function get_select_query( $limit = false ) {
|
175 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
176 |
|
177 |
+
$post_types = $this->post_type_helper->get_indexable_post_types();
|
178 |
$excluded_post_statuses = $this->post_helper->get_excluded_post_statuses();
|
179 |
$replacements = \array_merge(
|
180 |
$post_types,
|
204 |
$replacements
|
205 |
);
|
206 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
src/actions/indexing/indexable-term-indexation-action.php
CHANGED
@@ -124,9 +124,10 @@ class Indexable_Term_Indexation_Action extends Abstract_Indexing_Action {
|
|
124 |
* @return string The prepared query string.
|
125 |
*/
|
126 |
protected function get_count_query() {
|
127 |
-
$indexable_table
|
128 |
-
$taxonomy_table
|
129 |
-
$public_taxonomies
|
|
|
130 |
$taxonomies_placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
|
131 |
|
132 |
$replacements = [ $this->version ];
|
@@ -157,7 +158,7 @@ class Indexable_Term_Indexation_Action extends Abstract_Indexing_Action {
|
|
157 |
protected function get_select_query( $limit = false ) {
|
158 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
159 |
$taxonomy_table = $this->wpdb->term_taxonomy;
|
160 |
-
$public_taxonomies =
|
161 |
$placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
|
162 |
|
163 |
$replacements = [ $this->version ];
|
124 |
* @return string The prepared query string.
|
125 |
*/
|
126 |
protected function get_count_query() {
|
127 |
+
$indexable_table = Model::get_table_name( 'Indexable' );
|
128 |
+
$taxonomy_table = $this->wpdb->term_taxonomy;
|
129 |
+
$public_taxonomies = $this->taxonomy->get_indexable_taxonomies();
|
130 |
+
|
131 |
$taxonomies_placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
|
132 |
|
133 |
$replacements = [ $this->version ];
|
158 |
protected function get_select_query( $limit = false ) {
|
159 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
160 |
$taxonomy_table = $this->wpdb->term_taxonomy;
|
161 |
+
$public_taxonomies = $this->taxonomy->get_indexable_taxonomies();
|
162 |
$placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
|
163 |
|
164 |
$replacements = [ $this->version ];
|
src/actions/indexing/post-link-indexing-action.php
CHANGED
@@ -73,7 +73,7 @@ class Post_Link_Indexing_Action extends Abstract_Link_Indexing_Action {
|
|
73 |
* @return string The prepared query string.
|
74 |
*/
|
75 |
protected function get_count_query() {
|
76 |
-
$public_post_types = $this->post_type_helper->
|
77 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
78 |
$links_table = Model::get_table_name( 'SEO_Links' );
|
79 |
|
@@ -106,7 +106,7 @@ class Post_Link_Indexing_Action extends Abstract_Link_Indexing_Action {
|
|
106 |
* @return string The prepared query string.
|
107 |
*/
|
108 |
protected function get_select_query( $limit = false ) {
|
109 |
-
$public_post_types = $this->post_type_helper->
|
110 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
111 |
$links_table = Model::get_table_name( 'SEO_Links' );
|
112 |
$replacements = $public_post_types;
|
73 |
* @return string The prepared query string.
|
74 |
*/
|
75 |
protected function get_count_query() {
|
76 |
+
$public_post_types = $this->post_type_helper->get_indexable_post_types();
|
77 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
78 |
$links_table = Model::get_table_name( 'SEO_Links' );
|
79 |
|
106 |
* @return string The prepared query string.
|
107 |
*/
|
108 |
protected function get_select_query( $limit = false ) {
|
109 |
+
$public_post_types = $this->post_type_helper->get_indexable_post_types();
|
110 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
111 |
$links_table = Model::get_table_name( 'SEO_Links' );
|
112 |
$replacements = $public_post_types;
|
src/actions/indexing/term-link-indexing-action.php
CHANGED
@@ -73,7 +73,7 @@ class Term_Link_Indexing_Action extends Abstract_Link_Indexing_Action {
|
|
73 |
* @return string The prepared query string.
|
74 |
*/
|
75 |
protected function get_count_query() {
|
76 |
-
$public_taxonomies = $this->taxonomy_helper->
|
77 |
$placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
|
78 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
79 |
|
@@ -100,9 +100,10 @@ class Term_Link_Indexing_Action extends Abstract_Link_Indexing_Action {
|
|
100 |
* @return string The prepared query string.
|
101 |
*/
|
102 |
protected function get_select_query( $limit = false ) {
|
103 |
-
$public_taxonomies = $this->taxonomy_helper->
|
104 |
-
|
105 |
-
$
|
|
|
106 |
|
107 |
$limit_query = '';
|
108 |
if ( $limit ) {
|
73 |
* @return string The prepared query string.
|
74 |
*/
|
75 |
protected function get_count_query() {
|
76 |
+
$public_taxonomies = $this->taxonomy_helper->get_indexable_taxonomies();
|
77 |
$placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
|
78 |
$indexable_table = Model::get_table_name( 'Indexable' );
|
79 |
|
100 |
* @return string The prepared query string.
|
101 |
*/
|
102 |
protected function get_select_query( $limit = false ) {
|
103 |
+
$public_taxonomies = $this->taxonomy_helper->get_indexable_taxonomies();
|
104 |
+
|
105 |
+
$indexable_table = Model::get_table_name( 'Indexable' );
|
106 |
+
$replacements = $public_taxonomies;
|
107 |
|
108 |
$limit_query = '';
|
109 |
if ( $limit ) {
|
src/builders/indexable-author-builder.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace Yoast\WP\SEO\Builders;
|
4 |
|
5 |
use wpdb;
|
|
|
6 |
use Yoast\WP\SEO\Helpers\Author_Archive_Helper;
|
7 |
use Yoast\WP\SEO\Helpers\Post_Helper;
|
8 |
use Yoast\WP\SEO\Models\Indexable;
|
@@ -72,8 +73,15 @@ class Indexable_Author_Builder {
|
|
72 |
* @param Indexable $indexable The indexable to format.
|
73 |
*
|
74 |
* @return Indexable The extended indexable.
|
|
|
|
|
75 |
*/
|
76 |
public function build( $user_id, Indexable $indexable ) {
|
|
|
|
|
|
|
|
|
|
|
77 |
$meta_data = $this->get_meta_data( $user_id );
|
78 |
|
79 |
$indexable->object_id = $user_id;
|
@@ -190,4 +198,35 @@ class Indexable_Author_Builder {
|
|
190 |
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- We are using wpdb prepare.
|
191 |
return $this->wpdb->get_row( $this->wpdb->prepare( $sql, $replacements ) );
|
192 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
}
|
3 |
namespace Yoast\WP\SEO\Builders;
|
4 |
|
5 |
use wpdb;
|
6 |
+
use Yoast\WP\SEO\Exceptions\Indexable\Author_Not_Built_Exception;
|
7 |
use Yoast\WP\SEO\Helpers\Author_Archive_Helper;
|
8 |
use Yoast\WP\SEO\Helpers\Post_Helper;
|
9 |
use Yoast\WP\SEO\Models\Indexable;
|
73 |
* @param Indexable $indexable The indexable to format.
|
74 |
*
|
75 |
* @return Indexable The extended indexable.
|
76 |
+
*
|
77 |
+
* @throws Author_Not_Built_Exception When author is not built.
|
78 |
*/
|
79 |
public function build( $user_id, Indexable $indexable ) {
|
80 |
+
$exception = $this->check_if_user_should_be_indexed( $user_id );
|
81 |
+
if ( $exception ) {
|
82 |
+
throw $exception;
|
83 |
+
}
|
84 |
+
|
85 |
$meta_data = $this->get_meta_data( $user_id );
|
86 |
|
87 |
$indexable->object_id = $user_id;
|
198 |
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- We are using wpdb prepare.
|
199 |
return $this->wpdb->get_row( $this->wpdb->prepare( $sql, $replacements ) );
|
200 |
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Checks if the user should be indexed.
|
204 |
+
* Returns an exception with an appropriate message if not.
|
205 |
+
*
|
206 |
+
* @param string $user_id The user id.
|
207 |
+
*
|
208 |
+
* @return Author_Not_Built_Exception|null The exception if it should not be indexed, or `null` if it should.
|
209 |
+
*/
|
210 |
+
protected function check_if_user_should_be_indexed( $user_id ) {
|
211 |
+
$exception = null;
|
212 |
+
|
213 |
+
if ( $this->author_archive->are_disabled() ) {
|
214 |
+
$exception = Author_Not_Built_Exception::author_archives_are_disabled( $user_id );
|
215 |
+
}
|
216 |
+
|
217 |
+
// We will check if the author has public posts the WP way, instead of the indexable way, to make sure we get proper results even if SEO optimization is not run.
|
218 |
+
if ( $this->author_archive->author_has_public_posts_wp( $user_id ) === false ) {
|
219 |
+
$exception = Author_Not_Built_Exception::author_archives_are_not_indexed_for_users_without_posts( $user_id );
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Filter: Include or exclude a user from being build and saved as an indexable.
|
224 |
+
* Return an `Author_Not_Built_Exception` when the indexable should not be build, with an appropriate message telling why it should not be built.
|
225 |
+
* Return `null` if the indexable should be build.
|
226 |
+
*
|
227 |
+
* @param Author_Not_Built_Exception|null $exception An exception if the indexable is not being built, `null` if the indexable should be built.
|
228 |
+
* @param string $user_id The ID of the user that should or should not be excluded.
|
229 |
+
*/
|
230 |
+
return \apply_filters( 'wpseo_should_build_and_save_user_indexable', $exception, $user_id );
|
231 |
+
}
|
232 |
}
|
src/builders/indexable-builder.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace Yoast\WP\SEO\Builders;
|
4 |
|
|
|
5 |
use Yoast\WP\SEO\Exceptions\Indexable\Source_Exception;
|
6 |
use Yoast\WP\SEO\Helpers\Indexable_Helper;
|
7 |
use Yoast\WP\SEO\Models\Indexable;
|
@@ -299,6 +300,32 @@ class Indexable_Builder {
|
|
299 |
return $indexable;
|
300 |
}
|
301 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
/**
|
303 |
* Rebuilds an Indexable from scratch.
|
304 |
*
|
@@ -315,6 +342,9 @@ class Indexable_Builder {
|
|
315 |
$indexable = $this->ensure_indexable( $indexable, $defaults );
|
316 |
|
317 |
try {
|
|
|
|
|
|
|
318 |
switch ( $indexable->object_type ) {
|
319 |
|
320 |
case 'post':
|
@@ -330,19 +360,11 @@ class Indexable_Builder {
|
|
330 |
// Always rebuild the hierarchy; this needs the primary term to run correctly.
|
331 |
$this->hierarchy_builder->build( $indexable );
|
332 |
|
333 |
-
//
|
334 |
-
$
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
);
|
339 |
-
if ( ! $author_indexable || $this->version_manager->indexable_needs_upgrade( $author_indexable ) ) {
|
340 |
-
$author_defaults = [
|
341 |
-
'object_type' => 'user',
|
342 |
-
'object_id' => $indexable->author_id,
|
343 |
-
];
|
344 |
-
$this->build( $author_indexable, $author_defaults );
|
345 |
-
}
|
346 |
break;
|
347 |
|
348 |
case 'user':
|
@@ -351,6 +373,7 @@ class Indexable_Builder {
|
|
351 |
|
352 |
case 'term':
|
353 |
$indexable = $this->term_builder->build( $indexable->object_id, $indexable );
|
|
|
354 |
$this->hierarchy_builder->build( $indexable );
|
355 |
break;
|
356 |
|
@@ -380,20 +403,26 @@ class Indexable_Builder {
|
|
380 |
*
|
381 |
* @var Indexable $indexable
|
382 |
*/
|
383 |
-
$indexable = $this->
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
|
|
393 |
// Make sure that the indexing process doesn't get stuck in a loop on this broken indexable.
|
394 |
$indexable = $this->version_manager->set_latest( $indexable );
|
395 |
|
396 |
return $this->save_indexable( $indexable, $indexable_before );
|
397 |
}
|
|
|
|
|
|
|
398 |
}
|
|
|
|
|
399 |
}
|
2 |
|
3 |
namespace Yoast\WP\SEO\Builders;
|
4 |
|
5 |
+
use Yoast\WP\SEO\Exceptions\Indexable\Not_Built_Exception;
|
6 |
use Yoast\WP\SEO\Exceptions\Indexable\Source_Exception;
|
7 |
use Yoast\WP\SEO\Helpers\Indexable_Helper;
|
8 |
use Yoast\WP\SEO\Models\Indexable;
|
300 |
return $indexable;
|
301 |
}
|
302 |
|
303 |
+
/**
|
304 |
+
* Build and author indexable from an author id if it does not exist yet, or if the author indexable needs to be upgraded.
|
305 |
+
*
|
306 |
+
* @param int $author_id The author id.
|
307 |
+
*
|
308 |
+
* @return Indexable|false The author indexable if it has been built, `false` if it could not be built.
|
309 |
+
*/
|
310 |
+
protected function maybe_build_author_indexable( $author_id ) {
|
311 |
+
$author_indexable = $this->indexable_repository->find_by_id_and_type(
|
312 |
+
$author_id,
|
313 |
+
'user',
|
314 |
+
false
|
315 |
+
);
|
316 |
+
if ( ! $author_indexable || $this->version_manager->indexable_needs_upgrade( $author_indexable ) ) {
|
317 |
+
// Try to build the author.
|
318 |
+
$author_defaults = [
|
319 |
+
'object_type' => 'user',
|
320 |
+
'object_id' => $author_id,
|
321 |
+
];
|
322 |
+
$author_indexable = $this->build( $author_indexable, $author_defaults );
|
323 |
+
}
|
324 |
+
return $author_indexable;
|
325 |
+
}
|
326 |
+
|
327 |
+
// phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.Missing -- Exceptions are handled by the catch statement in the method.
|
328 |
+
|
329 |
/**
|
330 |
* Rebuilds an Indexable from scratch.
|
331 |
*
|
342 |
$indexable = $this->ensure_indexable( $indexable, $defaults );
|
343 |
|
344 |
try {
|
345 |
+
if ( $indexable->object_id === 0 ) {
|
346 |
+
throw Not_Built_Exception::invalid_object_id( $indexable->object_id );
|
347 |
+
}
|
348 |
switch ( $indexable->object_type ) {
|
349 |
|
350 |
case 'post':
|
360 |
// Always rebuild the hierarchy; this needs the primary term to run correctly.
|
361 |
$this->hierarchy_builder->build( $indexable );
|
362 |
|
363 |
+
// Save indexable, to make sure that it can be queried when determining if an author has public posts.
|
364 |
+
$indexable = $this->save_indexable( $indexable, $indexable_before );
|
365 |
+
|
366 |
+
$this->maybe_build_author_indexable( $indexable->author_id );
|
367 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
break;
|
369 |
|
370 |
case 'user':
|
373 |
|
374 |
case 'term':
|
375 |
$indexable = $this->term_builder->build( $indexable->object_id, $indexable );
|
376 |
+
|
377 |
$this->hierarchy_builder->build( $indexable );
|
378 |
break;
|
379 |
|
403 |
*
|
404 |
* @var Indexable $indexable
|
405 |
*/
|
406 |
+
$indexable = $this->ensure_indexable(
|
407 |
+
$indexable,
|
408 |
+
[
|
409 |
+
'object_id' => $indexable->object_id,
|
410 |
+
'object_type' => $indexable->object_type,
|
411 |
+
'post_status' => 'unindexed',
|
412 |
+
'version' => 0,
|
413 |
+
]
|
414 |
+
);
|
415 |
+
// If we already had an existing indexable, mark it as unindexed. We cannot rely on its validity anymore.
|
416 |
+
$indexable->post_status = 'unindexed';
|
417 |
// Make sure that the indexing process doesn't get stuck in a loop on this broken indexable.
|
418 |
$indexable = $this->version_manager->set_latest( $indexable );
|
419 |
|
420 |
return $this->save_indexable( $indexable, $indexable_before );
|
421 |
}
|
422 |
+
catch ( Not_Built_Exception $exception ) {
|
423 |
+
return false;
|
424 |
+
}
|
425 |
}
|
426 |
+
|
427 |
+
// phpcs:enable
|
428 |
}
|
src/builders/indexable-post-builder.php
CHANGED
@@ -11,6 +11,7 @@ use Yoast\WP\SEO\Helpers\Post_Type_Helper;
|
|
11 |
use Yoast\WP\SEO\Models\Indexable;
|
12 |
use Yoast\WP\SEO\Repositories\Indexable_Repository;
|
13 |
use Yoast\WP\SEO\Values\Indexables\Indexable_Builder_Versions;
|
|
|
14 |
|
15 |
/**
|
16 |
* Post Builder for the indexables.
|
@@ -96,10 +97,11 @@ class Indexable_Post_Builder {
|
|
96 |
* @return bool|Indexable The extended indexable. False when unable to build.
|
97 |
*
|
98 |
* @throws Post_Not_Found_Exception When the post could not be found.
|
|
|
99 |
*/
|
100 |
public function build( $post_id, $indexable ) {
|
101 |
if ( ! $this->post_helper->is_post_indexable( $post_id ) ) {
|
102 |
-
|
103 |
}
|
104 |
|
105 |
$post = $this->post_helper->get_post( $post_id );
|
@@ -109,7 +111,7 @@ class Indexable_Post_Builder {
|
|
109 |
}
|
110 |
|
111 |
if ( $this->should_exclude_post( $post ) ) {
|
112 |
-
|
113 |
}
|
114 |
|
115 |
$indexable->object_id = $post_id;
|
11 |
use Yoast\WP\SEO\Models\Indexable;
|
12 |
use Yoast\WP\SEO\Repositories\Indexable_Repository;
|
13 |
use Yoast\WP\SEO\Values\Indexables\Indexable_Builder_Versions;
|
14 |
+
use Yoast\WP\SEO\Exceptions\Indexable\Post_Not_Built_Exception;
|
15 |
|
16 |
/**
|
17 |
* Post Builder for the indexables.
|
97 |
* @return bool|Indexable The extended indexable. False when unable to build.
|
98 |
*
|
99 |
* @throws Post_Not_Found_Exception When the post could not be found.
|
100 |
+
* @throws Post_Not_Built_Exception When the post should not be indexed.
|
101 |
*/
|
102 |
public function build( $post_id, $indexable ) {
|
103 |
if ( ! $this->post_helper->is_post_indexable( $post_id ) ) {
|
104 |
+
throw Post_Not_Built_Exception::because_not_indexable( $post_id );
|
105 |
}
|
106 |
|
107 |
$post = $this->post_helper->get_post( $post_id );
|
111 |
}
|
112 |
|
113 |
if ( $this->should_exclude_post( $post ) ) {
|
114 |
+
throw Post_Not_Built_Exception::because_post_type_excluded( $post_id );
|
115 |
}
|
116 |
|
117 |
$indexable->object_id = $post_id;
|
src/builders/indexable-term-builder.php
CHANGED
@@ -5,6 +5,7 @@ namespace Yoast\WP\SEO\Builders;
|
|
5 |
use wpdb;
|
6 |
use Yoast\WP\SEO\Exceptions\Indexable\Invalid_Term_Exception;
|
7 |
use Yoast\WP\SEO\Exceptions\Indexable\Term_Not_Found_Exception;
|
|
|
8 |
use Yoast\WP\SEO\Helpers\Post_Helper;
|
9 |
use Yoast\WP\SEO\Helpers\Taxonomy_Helper;
|
10 |
use Yoast\WP\SEO\Models\Indexable;
|
@@ -75,7 +76,8 @@ class Indexable_Term_Builder {
|
|
75 |
*
|
76 |
* @return bool|Indexable The extended indexable. False when unable to build.
|
77 |
*
|
78 |
-
* @throws Invalid_Term_Exception
|
|
|
79 |
* @throws Term_Not_Found_Exception When the term is not found.
|
80 |
*/
|
81 |
public function build( $term_id, $indexable ) {
|
@@ -89,6 +91,11 @@ class Indexable_Term_Builder {
|
|
89 |
throw new Invalid_Term_Exception( $term->get_error_message() );
|
90 |
}
|
91 |
|
|
|
|
|
|
|
|
|
|
|
92 |
$term_link = \get_term_link( $term, $term->taxonomy );
|
93 |
|
94 |
if ( \is_wp_error( $term_link ) ) {
|
5 |
use wpdb;
|
6 |
use Yoast\WP\SEO\Exceptions\Indexable\Invalid_Term_Exception;
|
7 |
use Yoast\WP\SEO\Exceptions\Indexable\Term_Not_Found_Exception;
|
8 |
+
use Yoast\WP\SEO\Exceptions\Indexable\Term_Not_Built_Exception;
|
9 |
use Yoast\WP\SEO\Helpers\Post_Helper;
|
10 |
use Yoast\WP\SEO\Helpers\Taxonomy_Helper;
|
11 |
use Yoast\WP\SEO\Models\Indexable;
|
76 |
*
|
77 |
* @return bool|Indexable The extended indexable. False when unable to build.
|
78 |
*
|
79 |
+
* @throws Invalid_Term_Exception When the term is invalid.
|
80 |
+
* @throws Term_Not_Built_Exception When the term is not viewable.
|
81 |
* @throws Term_Not_Found_Exception When the term is not found.
|
82 |
*/
|
83 |
public function build( $term_id, $indexable ) {
|
91 |
throw new Invalid_Term_Exception( $term->get_error_message() );
|
92 |
}
|
93 |
|
94 |
+
$indexable_taxonomies = $this->taxonomy_helper->get_indexable_taxonomies();
|
95 |
+
if ( ! \in_array( $term->taxonomy, $indexable_taxonomies, true ) ) {
|
96 |
+
throw Term_Not_Built_Exception::because_not_indexable( $term_id );
|
97 |
+
}
|
98 |
+
|
99 |
$term_link = \get_term_link( $term, $term->taxonomy );
|
100 |
|
101 |
if ( \is_wp_error( $term_link ) ) {
|
src/commands/cleanup-command.php
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Yoast\WP\SEO\Commands;
|
4 |
+
|
5 |
+
use WP_CLI\ExitException;
|
6 |
+
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
7 |
+
use Yoast\WP\SEO\Main;
|
8 |
+
use function get_sites;
|
9 |
+
use function WP_CLI\Utils\make_progress_bar;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* A WP CLI command that helps with cleaning up unwanted records from our custom tables.
|
13 |
+
*/
|
14 |
+
final class Cleanup_Command implements Command_Interface {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* The integration that cleans up on cron.
|
18 |
+
*
|
19 |
+
* @var Cleanup_Integration
|
20 |
+
*/
|
21 |
+
private $cleanup_integration;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* The constructor.
|
25 |
+
*
|
26 |
+
* @param Cleanup_Integration $cleanup_integration The integration that cleans up on cron.
|
27 |
+
*/
|
28 |
+
public function __construct( Cleanup_Integration $cleanup_integration ) {
|
29 |
+
$this->cleanup_integration = $cleanup_integration;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Returns the namespace of this command.
|
34 |
+
*
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
public static function get_namespace() {
|
38 |
+
return Main::WP_CLI_NAMESPACE;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Performs a cleanup of custom Yoast tables.
|
43 |
+
*
|
44 |
+
* This removes unused, unwanted or orphaned database records, which ensures the best performance. Including:
|
45 |
+
* - Indexables
|
46 |
+
* - Indexable hierarchy
|
47 |
+
* - SEO links
|
48 |
+
*
|
49 |
+
* ## OPTIONS
|
50 |
+
*
|
51 |
+
* [--batch-size=<batch-size>]
|
52 |
+
* : The number of database records to clean up in a single sql query.
|
53 |
+
* ---
|
54 |
+
* default: 1000
|
55 |
+
* ---
|
56 |
+
*
|
57 |
+
* [--interval=<interval>]
|
58 |
+
* : The number of microseconds (millionths of a second) to wait between cleanup batches.
|
59 |
+
* ---
|
60 |
+
* default: 500000
|
61 |
+
* ---
|
62 |
+
*
|
63 |
+
* [--network]
|
64 |
+
* : Performs the cleanup on all sites within the network.
|
65 |
+
*
|
66 |
+
* ## EXAMPLES
|
67 |
+
*
|
68 |
+
* wp yoast cleanup
|
69 |
+
*
|
70 |
+
* @when after_wp_load
|
71 |
+
*
|
72 |
+
* @param array|null $args The arguments.
|
73 |
+
* @param array|null $assoc_args The associative arguments.
|
74 |
+
*
|
75 |
+
* @return void
|
76 |
+
*
|
77 |
+
* @throws ExitException When the input args are invalid.
|
78 |
+
*/
|
79 |
+
public function cleanup( $args = null, $assoc_args = null ) {
|
80 |
+
if ( isset( $assoc_args['interval'] ) && (int) $assoc_args['interval'] < 0 ) {
|
81 |
+
\WP_CLI::error( __( 'The value for \'interval\' must be a positive integer.', 'wordpress-seo' ) );
|
82 |
+
}
|
83 |
+
if ( isset( $assoc_args['batch-size'] ) && (int) $assoc_args['batch-size'] < 1 ) {
|
84 |
+
\WP_CLI::error( __( 'The value for \'batch-size\' must be a positive integer higher than equal to 1.', 'wordpress-seo' ) );
|
85 |
+
}
|
86 |
+
|
87 |
+
if ( isset( $assoc_args['network'] ) && \is_multisite() ) {
|
88 |
+
$total_removed = $this->cleanup_network( $assoc_args );
|
89 |
+
}
|
90 |
+
else {
|
91 |
+
$total_removed = $this->cleanup_current_site( $assoc_args );
|
92 |
+
}
|
93 |
+
|
94 |
+
\WP_CLI::success(
|
95 |
+
\sprintf(
|
96 |
+
/* translators: %1$d is the number of records that are removed. */
|
97 |
+
\_n(
|
98 |
+
'Cleaned up %1$d record.',
|
99 |
+
'Cleaned up %1$d records.',
|
100 |
+
$total_removed,
|
101 |
+
'wordpress-seo'
|
102 |
+
),
|
103 |
+
$total_removed
|
104 |
+
)
|
105 |
+
);
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Performs the cleanup for the entire network.
|
110 |
+
*
|
111 |
+
* @param array|null $assoc_args The associative arguments.
|
112 |
+
*
|
113 |
+
* @return int The number of cleaned up records.
|
114 |
+
*/
|
115 |
+
private function cleanup_network( $assoc_args ) {
|
116 |
+
$criteria = [
|
117 |
+
'fields' => 'ids',
|
118 |
+
'spam' => 0,
|
119 |
+
'deleted' => 0,
|
120 |
+
'archived' => 0,
|
121 |
+
];
|
122 |
+
$blog_ids = \get_sites( $criteria );
|
123 |
+
$total_removed = 0;
|
124 |
+
foreach ( $blog_ids as $blog_id ) {
|
125 |
+
\switch_to_blog( $blog_id );
|
126 |
+
$total_removed += $this->cleanup_current_site( $assoc_args );
|
127 |
+
\restore_current_blog();
|
128 |
+
}
|
129 |
+
|
130 |
+
return $total_removed;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Performs the cleanup for a single site.
|
135 |
+
*
|
136 |
+
* @param array|null $assoc_args The associative arguments.
|
137 |
+
*
|
138 |
+
* @return int The number of cleaned up records.
|
139 |
+
*/
|
140 |
+
private function cleanup_current_site( $assoc_args ) {
|
141 |
+
$site_url = \site_url();
|
142 |
+
$total_removed = 0;
|
143 |
+
|
144 |
+
if ( ! \is_plugin_active( WPSEO_BASENAME ) ) {
|
145 |
+
/* translators: %1$s is the site url of the site that is skipped. %2$s is Yoast SEO. */
|
146 |
+
\WP_CLI::warning( \sprintf( \__( 'Skipping %1$s. %2$s is not active on this site.', 'wordpress-seo' ), $site_url, 'Yoast SEO' ) );
|
147 |
+
|
148 |
+
return $total_removed;
|
149 |
+
}
|
150 |
+
|
151 |
+
// Make sure the DB is up to date first.
|
152 |
+
\do_action( '_yoast_run_migrations' );
|
153 |
+
|
154 |
+
$tasks = $this->cleanup_integration->get_cleanup_tasks();
|
155 |
+
$limit = (int) $assoc_args['batch-size'];
|
156 |
+
$interval = (int) $assoc_args['interval'];
|
157 |
+
|
158 |
+
/* translators: %1$s is the site url of the site that is cleaned up. %2$s is the name of the cleanup task that is currently running. */
|
159 |
+
$progress_bar_title_format = \__( 'Cleaning up %1$s [%2$s]', 'wordpress-seo' );
|
160 |
+
$progress = make_progress_bar( \sprintf( $progress_bar_title_format, $site_url, \key( $tasks ) ), count( $tasks ) );
|
161 |
+
|
162 |
+
foreach ( $tasks as $task_name => $task ) {
|
163 |
+
// Update the progressbar title with the current task name.
|
164 |
+
$progress->tick( 0, \sprintf( $progress_bar_title_format, $site_url, $task_name ) );
|
165 |
+
do {
|
166 |
+
$items_cleaned = $task( $limit );
|
167 |
+
if ( \is_int( $items_cleaned ) ) {
|
168 |
+
$total_removed += $items_cleaned;
|
169 |
+
}
|
170 |
+
\usleep( $interval );
|
171 |
+
|
172 |
+
// Update the timer.
|
173 |
+
$progress->tick( 0 );
|
174 |
+
} while ( $items_cleaned !== false && $items_cleaned > 0 );
|
175 |
+
$progress->tick();
|
176 |
+
}
|
177 |
+
$progress->finish();
|
178 |
+
|
179 |
+
$this->cleanup_integration->reset_cleanup();
|
180 |
+
\WP_CLI::log(
|
181 |
+
\sprintf(
|
182 |
+
/* translators: %1$d is the number of records that were removed. %2$s is the site url. */
|
183 |
+
\_n(
|
184 |
+
'Cleaned up %1$d record from %2$s.',
|
185 |
+
'Cleaned up %1$d records from %2$s.',
|
186 |
+
$total_removed,
|
187 |
+
'wordpress-seo'
|
188 |
+
),
|
189 |
+
$total_removed,
|
190 |
+
$site_url
|
191 |
+
)
|
192 |
+
);
|
193 |
+
|
194 |
+
return $total_removed;
|
195 |
+
}
|
196 |
+
}
|
src/config/indexing-reasons.php
CHANGED
@@ -31,4 +31,14 @@ class Indexing_Reasons {
|
|
31 |
* Represents the reason that the home url option is changed.
|
32 |
*/
|
33 |
const REASON_HOME_URL_OPTION = 'home_url_option_changed';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
31 |
* Represents the reason that the home url option is changed.
|
32 |
*/
|
33 |
const REASON_HOME_URL_OPTION = 'home_url_option_changed';
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Represents the reason that a post type has been made public.
|
37 |
+
*/
|
38 |
+
const REASON_POST_TYPE_MADE_PUBLIC = 'post_type_made_public';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Represents the reason that a post type has been made viewable.
|
42 |
+
*/
|
43 |
+
const REASON_TAXONOMY_MADE_PUBLIC = 'taxonomy_made_public';
|
44 |
}
|
src/exceptions/indexable/author-not-built-exception.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Yoast\WP\SEO\Exceptions\Indexable;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* For when an author indexable is not being built.
|
7 |
+
*/
|
8 |
+
class Author_Not_Built_Exception extends Not_Built_Exception {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Named constructor for creating an Author_Not_Built_Exception
|
12 |
+
* when author archives are disabled for users without posts.
|
13 |
+
*
|
14 |
+
* @param string $user_id The user id.
|
15 |
+
*
|
16 |
+
* @return Author_Not_Built_Exception The exception.
|
17 |
+
*/
|
18 |
+
public static function author_archives_are_not_indexed_for_users_without_posts( $user_id ) {
|
19 |
+
return new Author_Not_Built_Exception(
|
20 |
+
'Indexable for author with id ' . $user_id . ' is not being built, since author archives are not indexed for users without posts.'
|
21 |
+
);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Named constructor for creating an Author_Not_Built_Exception
|
26 |
+
* when author archives are disabled.
|
27 |
+
*
|
28 |
+
* @param string $user_id The user id.
|
29 |
+
*
|
30 |
+
* @return Author_Not_Built_Exception The exception.
|
31 |
+
*/
|
32 |
+
public static function author_archives_are_disabled( $user_id ) {
|
33 |
+
return new Author_Not_Built_Exception(
|
34 |
+
'Indexable for author with id ' . $user_id . ' is not being built, since author archives are disabled.'
|
35 |
+
);
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Named constructor for creating an Author_Not_Build_Exception
|
40 |
+
* when an author is excluded because of the `'wpseo_should_build_and_save_user_indexable'` filter.
|
41 |
+
*
|
42 |
+
* @param string $user_id The user id.
|
43 |
+
*
|
44 |
+
* @return Author_Not_Built_Exception The exception.
|
45 |
+
*/
|
46 |
+
public static function author_not_built_because_of_filter( $user_id ) {
|
47 |
+
return new Author_Not_Built_Exception(
|
48 |
+
'Indexable for author with id ' . $user_id . ' is not being built, since it is excluded because of the \'wpseo_should_build_and_save_user_indexable\' filter.'
|
49 |
+
);
|
50 |
+
}
|
51 |
+
}
|
src/exceptions/indexable/not-built-exception.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Yoast\WP\SEO\Exceptions\Indexable;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Not_Built_Exception
|
7 |
+
*/
|
8 |
+
class Not_Built_Exception extends Indexable_Exception {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Creates an exception that should be thrown when an indexable
|
12 |
+
* was not built because of an invalid object id.
|
13 |
+
*
|
14 |
+
* @param int $object_id The invalid object id.
|
15 |
+
*
|
16 |
+
* @return Not_Built_Exception The exception.
|
17 |
+
*/
|
18 |
+
public static function invalid_object_id( $object_id ) {
|
19 |
+
return new Not_Built_Exception(
|
20 |
+
"Indexable was not built because it had an invalid object id of $object_id."
|
21 |
+
);
|
22 |
+
}
|
23 |
+
}
|
src/exceptions/indexable/post-not-built-exception.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Yoast\WP\SEO\Exceptions\Indexable;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Exception that is thrown whenever a post could not be built
|
7 |
+
* in the context of the indexables.
|
8 |
+
*/
|
9 |
+
class Post_Not_Built_Exception extends Not_Built_Exception {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Throws an exception if the post is not indexable.
|
13 |
+
*
|
14 |
+
* @param int $post_id ID of the post.
|
15 |
+
*
|
16 |
+
* @throws Post_Not_Built_Exception When the post is not indexable.
|
17 |
+
*/
|
18 |
+
public static function because_not_indexable( $post_id ) {
|
19 |
+
/* translators: %s: expands to the post id */
|
20 |
+
return new Post_Not_Built_Exception( sprintf( __( 'The post %s could not be indexed because it does not meet indexing requirements.', 'wordpress-seo' ), $post_id ) );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Throws an exception if the post type is excluded from indexing.
|
25 |
+
*
|
26 |
+
* @param int $post_id ID of the post.
|
27 |
+
*
|
28 |
+
* @throws Post_Not_Built_Exception When the post type is excluded.
|
29 |
+
*/
|
30 |
+
public static function because_post_type_excluded( $post_id ) {
|
31 |
+
/* translators: %s: expands to the post id */
|
32 |
+
return new Post_Not_Built_Exception( sprintf( __( 'The post %s could not be indexed because it\'s post type is excluded from indexing.', 'wordpress-seo' ), $post_id ) );
|
33 |
+
}
|
34 |
+
}
|
src/exceptions/indexable/term-not-built-exception.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Yoast\WP\SEO\Exceptions\Indexable;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Exception that is thrown whenever a term could not be built
|
7 |
+
* in the context of the indexables.
|
8 |
+
*/
|
9 |
+
class Term_Not_Built_Exception extends Not_Built_Exception {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Throws an exception if the term is not indexable.
|
13 |
+
*
|
14 |
+
* @param int $term_id ID of the term.
|
15 |
+
*
|
16 |
+
* @throws Term_Not_Built_Exception When the term is not built.
|
17 |
+
*/
|
18 |
+
public static function because_not_indexable( $term_id ) {
|
19 |
+
/* translators: %s: expands to the term id */
|
20 |
+
return new Term_Not_Built_Exception( sprintf( __( 'The term %s could not be built because it\'s not indexable.', 'wordpress-seo' ), $term_id ) );
|
21 |
+
}
|
22 |
+
}
|
src/generated/container.php
CHANGED
@@ -75,6 +75,7 @@ class Cached_Container extends Container
|
|
75 |
'yoast\\wp\\seo\\builders\\indexable_system_page_builder' => 'Yoast\\WP\\SEO\\Builders\\Indexable_System_Page_Builder',
|
76 |
'yoast\\wp\\seo\\builders\\indexable_term_builder' => 'Yoast\\WP\\SEO\\Builders\\Indexable_Term_Builder',
|
77 |
'yoast\\wp\\seo\\builders\\primary_term_builder' => 'Yoast\\WP\\SEO\\Builders\\Primary_Term_Builder',
|
|
|
78 |
'yoast\\wp\\seo\\commands\\index_command' => 'Yoast\\WP\\SEO\\Commands\\Index_Command',
|
79 |
'yoast\\wp\\seo\\conditionals\\addon_installation_conditional' => 'Yoast\\WP\\SEO\\Conditionals\\Addon_Installation_Conditional',
|
80 |
'yoast\\wp\\seo\\conditionals\\admin\\doing_post_quick_edit_save_conditional' => 'Yoast\\WP\\SEO\\Conditionals\\Admin\\Doing_Post_Quick_Edit_Save_Conditional',
|
@@ -256,6 +257,7 @@ class Cached_Container extends Container
|
|
256 |
'yoast\\wp\\seo\\integrations\\admin\\health_check_integration' => 'Yoast\\WP\\SEO\\Integrations\\Admin\\Health_Check_Integration',
|
257 |
'yoast\\wp\\seo\\integrations\\admin\\helpscout_beacon' => 'Yoast\\WP\\SEO\\Integrations\\Admin\\HelpScout_Beacon',
|
258 |
'yoast\\wp\\seo\\integrations\\admin\\import_integration' => 'Yoast\\WP\\SEO\\Integrations\\Admin\\Import_Integration',
|
|
|
259 |
'yoast\\wp\\seo\\integrations\\admin\\indexables_page_integration' => 'Yoast\\WP\\SEO\\Integrations\\Admin\\Indexables_Page_Integration',
|
260 |
'yoast\\wp\\seo\\integrations\\admin\\indexing_notification_integration' => 'Yoast\\WP\\SEO\\Integrations\\Admin\\Indexing_Notification_Integration',
|
261 |
'yoast\\wp\\seo\\integrations\\admin\\indexing_tool_integration' => 'Yoast\\WP\\SEO\\Integrations\\Admin\\Indexing_Tool_Integration',
|
@@ -321,6 +323,7 @@ class Cached_Container extends Container
|
|
321 |
'yoast\\wp\\seo\\integrations\\watchers\\addon_update_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Addon_Update_Watcher',
|
322 |
'yoast\\wp\\seo\\integrations\\watchers\\auto_update_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Auto_Update_Watcher',
|
323 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_ancestor_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Ancestor_Watcher',
|
|
|
324 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_author_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Author_Watcher',
|
325 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_category_permalink_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Category_Permalink_Watcher',
|
326 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_date_archive_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Date_Archive_Watcher',
|
@@ -329,9 +332,11 @@ class Cached_Container extends Container
|
|
329 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_permalink_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Permalink_Watcher',
|
330 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_post_meta_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Post_Meta_Watcher',
|
331 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_post_type_archive_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Post_Type_Archive_Watcher',
|
|
|
332 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_post_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Post_Watcher',
|
333 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_static_home_page_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Static_Home_Page_Watcher',
|
334 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_system_page_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_System_Page_Watcher',
|
|
|
335 |
'yoast\\wp\\seo\\integrations\\watchers\\indexable_term_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Term_Watcher',
|
336 |
'yoast\\wp\\seo\\integrations\\watchers\\option_titles_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Option_Titles_Watcher',
|
337 |
'yoast\\wp\\seo\\integrations\\watchers\\option_wpseo_watcher' => 'Yoast\\WP\\SEO\\Integrations\\Watchers\\Option_Wpseo_Watcher',
|
@@ -462,6 +467,7 @@ class Cached_Container extends Container
|
|
462 |
'Yoast\\WP\\SEO\\Builders\\Indexable_System_Page_Builder' => 'getIndexableSystemPageBuilderService',
|
463 |
'Yoast\\WP\\SEO\\Builders\\Indexable_Term_Builder' => 'getIndexableTermBuilderService',
|
464 |
'Yoast\\WP\\SEO\\Builders\\Primary_Term_Builder' => 'getPrimaryTermBuilderService',
|
|
|
465 |
'Yoast\\WP\\SEO\\Commands\\Index_Command' => 'getIndexCommandService',
|
466 |
'Yoast\\WP\\SEO\\Conditionals\\Addon_Installation_Conditional' => 'getAddonInstallationConditionalService',
|
467 |
'Yoast\\WP\\SEO\\Conditionals\\Admin\\Doing_Post_Quick_Edit_Save_Conditional' => 'getDoingPostQuickEditSaveConditionalService',
|
@@ -643,6 +649,7 @@ class Cached_Container extends Container
|
|
643 |
'Yoast\\WP\\SEO\\Integrations\\Admin\\Health_Check_Integration' => 'getHealthCheckIntegrationService',
|
644 |
'Yoast\\WP\\SEO\\Integrations\\Admin\\HelpScout_Beacon' => 'getHelpScoutBeaconService',
|
645 |
'Yoast\\WP\\SEO\\Integrations\\Admin\\Import_Integration' => 'getImportIntegrationService',
|
|
|
646 |
'Yoast\\WP\\SEO\\Integrations\\Admin\\Indexables_Page_Integration' => 'getIndexablesPageIntegrationService',
|
647 |
'Yoast\\WP\\SEO\\Integrations\\Admin\\Indexing_Notification_Integration' => 'getIndexingNotificationIntegrationService',
|
648 |
'Yoast\\WP\\SEO\\Integrations\\Admin\\Indexing_Tool_Integration' => 'getIndexingToolIntegrationService',
|
@@ -708,6 +715,7 @@ class Cached_Container extends Container
|
|
708 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Addon_Update_Watcher' => 'getAddonUpdateWatcherService',
|
709 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Auto_Update_Watcher' => 'getAutoUpdateWatcherService',
|
710 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Ancestor_Watcher' => 'getIndexableAncestorWatcherService',
|
|
|
711 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Author_Watcher' => 'getIndexableAuthorWatcherService',
|
712 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Category_Permalink_Watcher' => 'getIndexableCategoryPermalinkWatcherService',
|
713 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Date_Archive_Watcher' => 'getIndexableDateArchiveWatcherService',
|
@@ -716,9 +724,11 @@ class Cached_Container extends Container
|
|
716 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Permalink_Watcher' => 'getIndexablePermalinkWatcherService',
|
717 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Post_Meta_Watcher' => 'getIndexablePostMetaWatcherService',
|
718 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Post_Type_Archive_Watcher' => 'getIndexablePostTypeArchiveWatcherService',
|
|
|
719 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Post_Watcher' => 'getIndexablePostWatcherService',
|
720 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Static_Home_Page_Watcher' => 'getIndexableStaticHomePageWatcherService',
|
721 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_System_Page_Watcher' => 'getIndexableSystemPageWatcherService',
|
|
|
722 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Indexable_Term_Watcher' => 'getIndexableTermWatcherService',
|
723 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Option_Titles_Watcher' => 'getOptionTitlesWatcherService',
|
724 |
'Yoast\\WP\\SEO\\Integrations\\Watchers\\Option_Wpseo_Watcher' => 'getOptionWpseoWatcherService',
|
@@ -813,7 +823,6 @@ class Cached_Container extends Container
|
|
813 |
'Psr\\Container\\ContainerInterface' => true,
|
814 |
'YoastSEO_Vendor\\Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
815 |
'YoastSEO_Vendor\\YoastSEO_Vendor\\Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
816 |
-
'Yoast\\WP\\SEO\\Commands\\Command_Interface' => true,
|
817 |
'wpdb' => true,
|
818 |
];
|
819 |
}
|
@@ -1343,7 +1352,7 @@ class Cached_Container extends Container
|
|
1343 |
return $this->services['Yoast\\WP\\SEO\\Builders\\Indexable_Author_Builder'];
|
1344 |
}
|
1345 |
|
1346 |
-
$this->services['Yoast\\WP\\SEO\\Builders\\Indexable_Author_Builder'] = $instance = new \Yoast\WP\SEO\Builders\Indexable_Author_Builder(${($_ = isset($this->services['Yoast\\WP\\SEO\\Helpers\\Author_Archive_Helper']) ? $this->services['Yoast\\WP\\SEO\\Helpers\\Author_Archive_Helper'] :
|
1347 |
|
1348 |
$instance->set_social_image_helpers(${($_ = isset($this->services['Yoast\\WP\\SEO\\Helpers\\Image_Helper']) ? $this->services['Yoast\\WP\\SEO\\Helpers\\Image_Helper'] : $this->getImageHelperService()) && false ?: '_'}, ${($_ = isset($this->services['Yoast\\WP\\SEO\\Helpers\\Open_Graph\\Image_Helper']) ? $this->services['Yoast\\WP\\SEO\\Helpers\\Open_Graph\\Image_Helper'] : $this->getImageHelper2Service()) && false ?: '_'}, ${($_ = isset($this->services['Yoast\\WP\\SEO\\Helpers\\Twitter\\Image_Helper']) ? $this->services['Yoast\\WP\\SEO\\Helpers\\Twitter\\Image_Helper'] : $this->getImageHelper4Service()) && false ?: '_'});
|
1349 |
|
@@ -1552,6 +1561,16 @@ class Cached_Container extends Container
|
|
1552 |
return $this->services['Yoast\\WP\\SEO\\Builders\\Primary_Term_Builder'] = new \Yoast\WP\SEO\Builders\Primary_Term_Builder(${($_ = isset($this->services['Yoast\\WP\\SEO\\Repositories\\Primary_Term_Repository']) ? $this->services['Yoast\\WP\\SEO\\Repositories\\Primary_Term_Repository'] : ($this->services['Yoast\\WP\\SEO\\Repositories\\Primary_Term_Repository'] = new \Yoast\WP\SEO\Repositories\Primary_Term_Repository())) && false ?: '_'}, ${($_ = isset($this->services['Yoast\\WP\\SEO\\Helpers\\Primary_Term_Helper']) ? $this->services['Yoast\\WP\\SEO\\Helpers\\Primary_Term_Helper'] : ($this->services['Yoast\\WP\\SEO\\Helpers\\Primary_Term_Helper'] = new \Yoast\WP\SEO\Helpers\Primary_Term_Helper())) && false ?: '_'}, ${($_ = isset($this->services['Yoast\\WP\\SEO\\Helpers\\Meta_Helper']) ? $this->services['Yoast\\WP\\SEO\\Helpers\\Meta_Helper'] : ($this->services['Yoast\\WP\\SEO\\Helpers\\Meta_Helper'] = new \Yoast\WP\SEO\Helpers\Meta_Helper())) && false ?: '_'});
|
1553 |
}
|
1554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1555 |
/**
|
1556 |
* Gets the public 'Yoast\WP\SEO\Commands\Index_Command' shared autowired service.
|
1557 |
*
|
@@ -2673,7 +2692,7 @@ class Cached_Container extends Container
|
|
2673 |
*/
|
2674 |
protected function getAuthorArchiveHelperService()
|
2675 |
{
|