Merged in feature/314-dev-dev01 (pull request #24)
auto-patch 314-dev-dev01-2024-01-25T04_09_02 * auto-patch 314-dev-dev01-2024-01-25T04_09_02
This commit is contained in:
@@ -17,56 +17,56 @@ class WPSEO_Addon_Manager {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SITE_INFORMATION_TRANSIENT = 'wpseo_site_information';
|
||||
public const SITE_INFORMATION_TRANSIENT = 'wpseo_site_information';
|
||||
|
||||
/**
|
||||
* Holds the name of the transient.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SITE_INFORMATION_TRANSIENT_QUICK = 'wpseo_site_information_quick';
|
||||
public const SITE_INFORMATION_TRANSIENT_QUICK = 'wpseo_site_information_quick';
|
||||
|
||||
/**
|
||||
* Holds the slug for YoastSEO free.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FREE_SLUG = 'yoast-seo-wordpress';
|
||||
public const FREE_SLUG = 'yoast-seo-wordpress';
|
||||
|
||||
/**
|
||||
* Holds the slug for YoastSEO Premium.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PREMIUM_SLUG = 'yoast-seo-wordpress-premium';
|
||||
public const PREMIUM_SLUG = 'yoast-seo-wordpress-premium';
|
||||
|
||||
/**
|
||||
* Holds the slug for Yoast News.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const NEWS_SLUG = 'yoast-seo-news';
|
||||
public const NEWS_SLUG = 'yoast-seo-news';
|
||||
|
||||
/**
|
||||
* Holds the slug for Video.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VIDEO_SLUG = 'yoast-seo-video';
|
||||
public const VIDEO_SLUG = 'yoast-seo-video';
|
||||
|
||||
/**
|
||||
* Holds the slug for WooCommerce.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const WOOCOMMERCE_SLUG = 'yoast-seo-woocommerce';
|
||||
public const WOOCOMMERCE_SLUG = 'yoast-seo-woocommerce';
|
||||
|
||||
/**
|
||||
* Holds the slug for Local.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const LOCAL_SLUG = 'yoast-seo-local';
|
||||
public const LOCAL_SLUG = 'yoast-seo-local';
|
||||
|
||||
/**
|
||||
* The expected addon data.
|
||||
@@ -396,6 +396,8 @@ class WPSEO_Addon_Manager {
|
||||
* If the plugin is lacking an active subscription, throw a warning.
|
||||
*
|
||||
* @param array $plugin_data The data for the plugin in this row.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function expired_subscription_warning( $plugin_data ) {
|
||||
$subscription = $this->get_subscription( $plugin_data['slug'] );
|
||||
@@ -411,16 +413,16 @@ class WPSEO_Addon_Manager {
|
||||
);
|
||||
}
|
||||
echo '<br><br>';
|
||||
echo '<strong><span class="yoast-dashicons-notice warning dashicons dashicons-warning"></span> ' .
|
||||
sprintf(
|
||||
echo '<strong><span class="yoast-dashicons-notice warning dashicons dashicons-warning"></span> '
|
||||
. sprintf(
|
||||
/* translators: %1$s is the plugin name, %2$s and %3$s are a link. */
|
||||
esc_html__( '%1$s can\'t be updated because your product subscription is expired. %2$sRenew your product subscription%3$s to get updates again and use all the features of %1$s.', 'wordpress-seo' ),
|
||||
esc_html( $plugin_data['name'] ),
|
||||
'<a href="' . esc_url( WPSEO_Shortlinker::get( $addon_link ) ) . '">',
|
||||
'</a>'
|
||||
) .
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is escaped above.
|
||||
$sale_copy
|
||||
)
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is escaped above.
|
||||
. $sale_copy
|
||||
. '</strong>';
|
||||
}
|
||||
}
|
||||
@@ -461,6 +463,8 @@ class WPSEO_Addon_Manager {
|
||||
|
||||
/**
|
||||
* Validates the addons and show a notice for the ones that are invalid.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validate_addons() {
|
||||
$notification_center = Yoast_Notification_Center::get();
|
||||
@@ -579,7 +583,7 @@ class WPSEO_Addon_Manager {
|
||||
'banners' => $this->get_banners( $subscription->product->slug ),
|
||||
// If we have extracted Yoast Free's data before, use that. If not, resort to the defaults.
|
||||
'tested' => YOAST_SEO_WP_TESTED,
|
||||
'requires' => isset( $yoast_free_data->requires ) ? $yoast_free_data->requires : $defaults['requires'],
|
||||
'requires' => ( $yoast_free_data->requires ?? $defaults['requires'] ),
|
||||
'requires_php' => YOAST_SEO_PHP_REQUIRED,
|
||||
];
|
||||
}
|
||||
@@ -726,7 +730,7 @@ class WPSEO_Addon_Manager {
|
||||
$current_page = null;
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
|
||||
if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, We are only strictly comparing and thus no need to sanitize.
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, We are only strictly comparing and thus no need to sanitize.
|
||||
$current_page = wp_unslash( $_GET['page'] );
|
||||
}
|
||||
|
||||
@@ -833,7 +837,7 @@ class WPSEO_Addon_Manager {
|
||||
'last_updated' => $subscription->product->lastUpdated,
|
||||
'store_url' => $subscription->product->storeUrl,
|
||||
// Ternary operator is necessary because download can be undefined.
|
||||
'download' => isset( $subscription->product->download ) ? $subscription->product->download : null,
|
||||
'download' => ( $subscription->product->download ?? null ),
|
||||
'changelog' => $subscription->product->changelog,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -28,6 +28,8 @@ class WPSEO_Rewrite {
|
||||
* Trigger a rewrite_rule flush on shutdown.
|
||||
*
|
||||
* @since 1.2.8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function schedule_flush() {
|
||||
add_action( 'shutdown', 'flush_rewrite_rules' );
|
||||
|
||||
@@ -50,6 +50,8 @@ class WPSEO_Upgrade_History {
|
||||
* @param string $old_version The version we are upgrading from.
|
||||
* @param string $new_version The version we are upgrading to.
|
||||
* @param array $option_names The options that need to be stored.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add( $old_version, $new_version, array $option_names ) {
|
||||
$option_data = [];
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
use Yoast\WP\Lib\Model;
|
||||
use Yoast\WP\SEO\Helpers\Taxonomy_Helper;
|
||||
use Yoast\WP\SEO\Integrations\Cleanup_Integration;
|
||||
use Yoast\WP\SEO\Integrations\Watchers\Addon_Update_Watcher;
|
||||
|
||||
/**
|
||||
* This code handles the option upgrades.
|
||||
@@ -108,7 +109,7 @@ class WPSEO_Upgrade {
|
||||
/**
|
||||
* Filter: 'wpseo_run_upgrade' - Runs the upgrade hook which are dependent on Yoast SEO.
|
||||
*
|
||||
* @api string - The current version of Yoast SEO
|
||||
* @param string $version The current version of Yoast SEO
|
||||
*/
|
||||
do_action( 'wpseo_run_upgrade', $version );
|
||||
|
||||
@@ -135,6 +136,8 @@ class WPSEO_Upgrade {
|
||||
*
|
||||
* @param string $current_version The old version from which we are upgrading.
|
||||
* @param string $new_version The version we are upgrading to.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function add_upgrade_history( $current_version, $new_version ) {
|
||||
$upgrade_history = new WPSEO_Upgrade_History();
|
||||
@@ -168,6 +171,8 @@ class WPSEO_Upgrade {
|
||||
* Run the Yoast SEO 1.5 upgrade routine.
|
||||
*
|
||||
* @param string $version Current plugin version.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_15( $version ) {
|
||||
// Clean up options and meta.
|
||||
@@ -177,6 +182,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Moves options that moved position in WPSEO 2.0.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_20() {
|
||||
/**
|
||||
@@ -194,6 +201,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Detects if taxonomy terms were split and updates the corresponding taxonomy meta's accordingly.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_21() {
|
||||
$taxonomies = get_option( 'wpseo_taxonomy_meta', [] );
|
||||
@@ -217,6 +226,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs upgrade functions to Yoast SEO 2.2.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_22() {
|
||||
// Unschedule our tracking.
|
||||
@@ -227,6 +238,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Schedules upgrade function to Yoast SEO 2.3.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_23() {
|
||||
add_action( 'wp', [ $this, 'upgrade_23_query' ], 90 );
|
||||
@@ -235,6 +248,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs upgrade query to Yoast SEO 2.3.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function upgrade_23_query() {
|
||||
$wp_query = new WP_Query( 'post_type=any&meta_key=_yoast_wpseo_sitemap-include&meta_value=never&order=ASC' );
|
||||
@@ -266,6 +281,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs upgrade functions to Yoast SEO 3.0.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_30() {
|
||||
// Remove the meta fields for sitemap prio.
|
||||
@@ -274,6 +291,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs upgrade functions to Yoast SEO 3.3.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_33() {
|
||||
// Notification dismissals have been moved to User Meta instead of global option.
|
||||
@@ -282,6 +301,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs upgrade functions to Yoast SEO 3.6.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_36() {
|
||||
global $wpdb;
|
||||
@@ -292,6 +313,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Removes the about notice when its still in the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_40() {
|
||||
$center = Yoast_Notification_Center::get();
|
||||
@@ -300,6 +323,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Moves the content-analysis-active and keyword-analysis-acive options from wpseo-titles to wpseo.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_44() {
|
||||
$wpseo_titles = $this->get_option_from_database( 'wpseo_titles' );
|
||||
@@ -313,6 +338,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Renames the meta name for the cornerstone content. It was a public meta field and it has to be private.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_47() {
|
||||
global $wpdb;
|
||||
@@ -328,6 +355,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Removes the 'wpseo-dismiss-about' notice for every user that still has it.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_49() {
|
||||
global $wpdb;
|
||||
@@ -391,6 +420,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Adds the yoast_seo_links table to the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_50() {
|
||||
global $wpdb;
|
||||
@@ -401,6 +432,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Register new capabilities and roles.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_55() {
|
||||
// Register roles.
|
||||
@@ -623,6 +656,8 @@ class WPSEO_Upgrade {
|
||||
* Performs the 12.3 upgrade.
|
||||
*
|
||||
* Removes the about notice when its still in the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_123() {
|
||||
$plugins = [
|
||||
@@ -644,6 +679,8 @@ class WPSEO_Upgrade {
|
||||
* Performs the 12.4 upgrade.
|
||||
*
|
||||
* Removes the Google plus defaults from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_124() {
|
||||
$this->cleanup_option_data( 'wpseo_social' );
|
||||
@@ -651,6 +688,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 12.5 upgrade.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function upgrade_125() {
|
||||
// Disables the force rewrite title when the theme supports it through WordPress.
|
||||
@@ -668,6 +707,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 12.8 upgrade.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_128() {
|
||||
// Re-save wpseo to make sure bf_banner_2019_dismissed key is gone.
|
||||
@@ -679,6 +720,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 13.2 upgrade.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_132() {
|
||||
Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-tagline-notice' );
|
||||
@@ -715,6 +758,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Perform the 14.0.3 upgrade.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_1403() {
|
||||
WPSEO_Options::set( 'ignore_indexation_warning', false );
|
||||
@@ -722,6 +767,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 14.1 upgrade.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_141() {
|
||||
/*
|
||||
@@ -738,6 +785,8 @@ class WPSEO_Upgrade {
|
||||
* Performs the 14.2 upgrade.
|
||||
*
|
||||
* Removes the yoast-acf-analysis notice when it's still in the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_142() {
|
||||
add_action( 'init', [ $this, 'remove_acf_notification_for_142' ] );
|
||||
@@ -745,6 +794,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 14.5 upgrade.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_145() {
|
||||
add_action( 'init', [ $this, 'set_indexation_completed_option_for_145' ] );
|
||||
@@ -752,6 +803,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 14.9 upgrade.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_149() {
|
||||
$version = get_option( 'wpseo_license_server_version', 2 );
|
||||
@@ -815,19 +868,23 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 15.9.1 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_1591() {
|
||||
$enabled_auto_updates = \get_option( 'auto_update_plugins' );
|
||||
$addon_update_watcher = YoastSEO()->classes->get( \Yoast\WP\SEO\Integrations\Watchers\Addon_Update_Watcher::class );
|
||||
$enabled_auto_updates = get_option( 'auto_update_plugins' );
|
||||
$addon_update_watcher = YoastSEO()->classes->get( Addon_Update_Watcher::class );
|
||||
$addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', [], $enabled_auto_updates );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the 16.2 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_162() {
|
||||
$enabled_auto_updates = \get_site_option( 'auto_update_plugins' );
|
||||
$addon_update_watcher = YoastSEO()->classes->get( \Yoast\WP\SEO\Integrations\Watchers\Addon_Update_Watcher::class );
|
||||
$enabled_auto_updates = get_site_option( 'auto_update_plugins' );
|
||||
$addon_update_watcher = YoastSEO()->classes->get( Addon_Update_Watcher::class );
|
||||
$addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', $enabled_auto_updates, [] );
|
||||
}
|
||||
|
||||
@@ -849,25 +906,29 @@ class WPSEO_Upgrade {
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_172() {
|
||||
\wp_unschedule_hook( 'wpseo_cleanup_orphaned_indexables' );
|
||||
\wp_unschedule_hook( 'wpseo_cleanup_indexables' );
|
||||
wp_unschedule_hook( 'wpseo_cleanup_orphaned_indexables' );
|
||||
wp_unschedule_hook( 'wpseo_cleanup_indexables' );
|
||||
|
||||
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the 17.7.1 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_1771() {
|
||||
$enabled_auto_updates = \get_site_option( 'auto_update_plugins' );
|
||||
$addon_update_watcher = YoastSEO()->classes->get( \Yoast\WP\SEO\Integrations\Watchers\Addon_Update_Watcher::class );
|
||||
$enabled_auto_updates = get_site_option( 'auto_update_plugins' );
|
||||
$addon_update_watcher = YoastSEO()->classes->get( Addon_Update_Watcher::class );
|
||||
$addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', $enabled_auto_updates, [] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the 17.9 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_179() {
|
||||
WPSEO_Options::set( 'wincher_integration_active', true );
|
||||
@@ -875,6 +936,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 18.3 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_183() {
|
||||
$this->delete_post_meta( 'yoast-structured-data-blocks-images-cache' );
|
||||
@@ -882,6 +945,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 18.6 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_186() {
|
||||
if ( is_multisite() ) {
|
||||
@@ -891,6 +956,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 18.9 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_189() {
|
||||
// Make old users not get the Installation Success page after upgrading.
|
||||
@@ -912,7 +979,7 @@ class WPSEO_Upgrade {
|
||||
|
||||
// Transfer the progress of the old Configuration Workout.
|
||||
$workout_data = WPSEO_Options::get( 'workouts_data' );
|
||||
$old_conf_progress = isset( $workout_data['configuration']['finishedSteps'] ) ? $workout_data['configuration']['finishedSteps'] : [];
|
||||
$old_conf_progress = ( $workout_data['configuration']['finishedSteps'] ?? [] );
|
||||
|
||||
if ( in_array( 'optimizeSeoData', $old_conf_progress, true ) && in_array( 'siteRepresentation', $old_conf_progress, true ) ) {
|
||||
// If completed ‘SEO optimization’ and ‘Site representation’ step, we assume the workout was completed.
|
||||
@@ -927,6 +994,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 19.1 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_191() {
|
||||
if ( is_multisite() ) {
|
||||
@@ -936,6 +1005,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 19.3 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_193() {
|
||||
if ( empty( get_option( 'wpseo_premium', [] ) ) ) {
|
||||
@@ -946,6 +1017,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 19.6 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_196() {
|
||||
WPSEO_Options::set( 'ryte_indexability', false );
|
||||
@@ -955,19 +1028,23 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Performs the 19.11 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_1911() {
|
||||
\add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_post_types' ] );
|
||||
\add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_taxonomies' ] );
|
||||
add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_post_types' ] );
|
||||
add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_taxonomies' ] );
|
||||
$this->deduplicate_unindexed_indexable_rows();
|
||||
$this->remove_indexable_rows_for_disabled_authors_archive();
|
||||
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the 20.2 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_202() {
|
||||
if ( WPSEO_Options::get( 'disable-attachment', true ) ) {
|
||||
@@ -979,18 +1056,20 @@ class WPSEO_Upgrade {
|
||||
|
||||
$this->clean_unindexed_indexable_rows_with_no_object_id();
|
||||
|
||||
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
// This schedules the cleanup routine cron again, since in combination of premium cleans up the prominent words table. We also want to cleanup possible orphaned hierarchies from the above cleanups.
|
||||
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the 20.5 upgrade routine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_205() {
|
||||
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -998,6 +1077,8 @@ class WPSEO_Upgrade {
|
||||
* Performs the 20.7 upgrade routine.
|
||||
* Removes the metadata related to the settings page introduction modal for all the users.
|
||||
* Also, schedules another cleanup scheduled action.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_207() {
|
||||
add_action( 'shutdown', [ $this, 'delete_user_introduction_meta' ] );
|
||||
@@ -1006,10 +1087,12 @@ class WPSEO_Upgrade {
|
||||
/**
|
||||
* Performs the 20.8 upgrade routine.
|
||||
* Schedules another cleanup scheduled action.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function upgrade_208() {
|
||||
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
|
||||
wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,6 +1124,8 @@ class WPSEO_Upgrade {
|
||||
* Checks if the indexable indexation is completed.
|
||||
* If so, sets the `indexables_indexation_completed` option to `true`,
|
||||
* else to `false`.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_indexation_completed_option_for_145() {
|
||||
WPSEO_Options::set( 'indexables_indexation_completed', YoastSEO()->helpers->indexing->get_limited_filtered_unindexed_count( 1 ) === 0 );
|
||||
@@ -1048,6 +1133,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Cleans up the private taxonomies from the indexables table for the upgrade routine to 14.1.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clean_up_private_taxonomies_for_141() {
|
||||
global $wpdb;
|
||||
@@ -1057,7 +1144,7 @@ class WPSEO_Upgrade {
|
||||
$wpdb->show_errors = false;
|
||||
|
||||
// Clean up indexables of private taxonomies.
|
||||
$private_taxonomies = \get_taxonomies( [ 'public' => false ], 'names' );
|
||||
$private_taxonomies = get_taxonomies( [ 'public' => false ], 'names' );
|
||||
|
||||
if ( empty( $private_taxonomies ) ) {
|
||||
return;
|
||||
@@ -1071,7 +1158,7 @@ class WPSEO_Upgrade {
|
||||
"DELETE FROM $indexable_table
|
||||
WHERE object_type = 'term'
|
||||
AND object_sub_type IN ("
|
||||
. \implode( ', ', \array_fill( 0, \count( $private_taxonomies ), '%s' ) )
|
||||
. implode( ', ', array_fill( 0, count( $private_taxonomies ), '%s' ) )
|
||||
. ')',
|
||||
$private_taxonomies
|
||||
);
|
||||
@@ -1082,6 +1169,8 @@ class WPSEO_Upgrade {
|
||||
|
||||
/**
|
||||
* Resets the permalinks of attachments to `null` in the indexable table for the upgrade routine to 14.1.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function reset_permalinks_of_attachments_for_141() {
|
||||
global $wpdb;
|
||||
@@ -1422,7 +1511,7 @@ class WPSEO_Upgrade {
|
||||
|
||||
$indexable_table = Model::get_table_name( 'Indexable' );
|
||||
|
||||
$included_post_types = \YoastSEO()->helpers->post_type->get_indexable_post_types();
|
||||
$included_post_types = YoastSEO()->helpers->post_type->get_indexable_post_types();
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
|
||||
if ( empty( $included_post_types ) ) {
|
||||
@@ -1436,7 +1525,7 @@ class WPSEO_Upgrade {
|
||||
"DELETE FROM $indexable_table
|
||||
WHERE object_type = 'post'
|
||||
AND object_sub_type IS NOT NULL
|
||||
AND object_sub_type NOT IN ( " . \implode( ', ', \array_fill( 0, \count( $included_post_types ), '%s' ) ) . ' )',
|
||||
AND object_sub_type NOT IN ( " . implode( ', ', array_fill( 0, count( $included_post_types ), '%s' ) ) . ' )',
|
||||
$included_post_types
|
||||
);
|
||||
}
|
||||
@@ -1466,7 +1555,7 @@ class WPSEO_Upgrade {
|
||||
|
||||
$indexable_table = Model::get_table_name( 'Indexable' );
|
||||
|
||||
$included_taxonomies = \YoastSEO()->helpers->taxonomy->get_indexable_taxonomies();
|
||||
$included_taxonomies = YoastSEO()->helpers->taxonomy->get_indexable_taxonomies();
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
|
||||
if ( empty( $included_taxonomies ) ) {
|
||||
@@ -1479,7 +1568,7 @@ class WPSEO_Upgrade {
|
||||
"DELETE FROM $indexable_table
|
||||
WHERE object_type = 'term'
|
||||
AND object_sub_type IS NOT NULL
|
||||
AND object_sub_type NOT IN ( " . \implode( ', ', \array_fill( 0, \count( $included_taxonomies ), '%s' ) ) . ' )',
|
||||
AND object_sub_type NOT IN ( " . implode( ', ', array_fill( 0, count( $included_taxonomies ), '%s' ) ) . ' )',
|
||||
$included_taxonomies
|
||||
);
|
||||
}
|
||||
@@ -1592,7 +1681,7 @@ class WPSEO_Upgrade {
|
||||
private function remove_indexable_rows_for_disabled_authors_archive() {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! \YoastSEO()->helpers->author_archive->are_disabled() ) {
|
||||
if ( ! YoastSEO()->helpers->author_archive->are_disabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1626,7 +1715,7 @@ class WPSEO_Upgrade {
|
||||
private function get_indexable_deduplication_query_for_type( $object_type, $duplicates, $wpdb ) {
|
||||
$indexable_table = Model::get_table_name( 'Indexable' );
|
||||
|
||||
$filtered_duplicates = \array_filter(
|
||||
$filtered_duplicates = array_filter(
|
||||
$duplicates,
|
||||
static function ( $duplicate ) use ( $object_type ) {
|
||||
return $duplicate['object_type'] === $object_type;
|
||||
@@ -1646,8 +1735,8 @@ class WPSEO_Upgrade {
|
||||
"DELETE FROM
|
||||
$indexable_table
|
||||
WHERE
|
||||
object_id IN ( " . \implode( ', ', \array_fill( 0, \count( $filtered_duplicates ), '%d' ) ) . ' )
|
||||
AND id NOT IN ( ' . \implode( ', ', \array_fill( 0, \count( $filtered_duplicates ), '%d' ) ) . ' )
|
||||
object_id IN ( " . implode( ', ', array_fill( 0, count( $filtered_duplicates ), '%d' ) ) . ' )
|
||||
AND id NOT IN ( ' . implode( ', ', array_fill( 0, count( $filtered_duplicates ), '%d' ) ) . ' )
|
||||
AND object_type = %s',
|
||||
array_merge( array_values( $object_ids ), array_values( $newest_indexable_ids ), [ $object_type ] )
|
||||
);
|
||||
|
||||
@@ -23,35 +23,35 @@ class WPSEO_Admin_Bar_Menu implements WPSEO_WordPress_Integration {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MENU_IDENTIFIER = 'wpseo-menu';
|
||||
public const MENU_IDENTIFIER = 'wpseo-menu';
|
||||
|
||||
/**
|
||||
* The identifier used for the Keyword Research submenu.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const KEYWORD_RESEARCH_SUBMENU_IDENTIFIER = 'wpseo-kwresearch';
|
||||
public const KEYWORD_RESEARCH_SUBMENU_IDENTIFIER = 'wpseo-kwresearch';
|
||||
|
||||
/**
|
||||
* The identifier used for the Analysis submenu.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ANALYSIS_SUBMENU_IDENTIFIER = 'wpseo-analysis';
|
||||
public const ANALYSIS_SUBMENU_IDENTIFIER = 'wpseo-analysis';
|
||||
|
||||
/**
|
||||
* The identifier used for the Settings submenu.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SETTINGS_SUBMENU_IDENTIFIER = 'wpseo-settings';
|
||||
public const SETTINGS_SUBMENU_IDENTIFIER = 'wpseo-settings';
|
||||
|
||||
/**
|
||||
* The identifier used for the Network Settings submenu.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const NETWORK_SETTINGS_SUBMENU_IDENTIFIER = 'wpseo-network-settings';
|
||||
public const NETWORK_SETTINGS_SUBMENU_IDENTIFIER = 'wpseo-network-settings';
|
||||
|
||||
/**
|
||||
* Asset manager instance.
|
||||
@@ -119,11 +119,11 @@ class WPSEO_Admin_Bar_Menu implements WPSEO_WordPress_Integration {
|
||||
* @param WPSEO_Shortlinker|null $shortlinker The shortlinker.
|
||||
*/
|
||||
public function __construct(
|
||||
WPSEO_Admin_Asset_Manager $asset_manager = null,
|
||||
Indexable_Repository $indexable_repository = null,
|
||||
Score_Icon_Helper $score_icon_helper = null,
|
||||
Product_Helper $product_helper = null,
|
||||
WPSEO_Shortlinker $shortlinker = null
|
||||
?WPSEO_Admin_Asset_Manager $asset_manager = null,
|
||||
?Indexable_Repository $indexable_repository = null,
|
||||
?Score_Icon_Helper $score_icon_helper = null,
|
||||
?Product_Helper $product_helper = null,
|
||||
?WPSEO_Shortlinker $shortlinker = null
|
||||
) {
|
||||
if ( ! $asset_manager ) {
|
||||
$asset_manager = new WPSEO_Admin_Asset_Manager();
|
||||
@@ -753,7 +753,7 @@ class WPSEO_Admin_Bar_Menu implements WPSEO_WordPress_Integration {
|
||||
/**
|
||||
* Filter: 'wpseo_use_page_analysis' Determines if the analysis should be enabled.
|
||||
*
|
||||
* @api bool Determines if the analysis should be enabled.
|
||||
* @param bool $enabled Determines if the analysis should be enabled.
|
||||
*/
|
||||
if ( apply_filters( 'wpseo_use_page_analysis', true ) !== true ) {
|
||||
return '';
|
||||
|
||||
@@ -13,8 +13,8 @@ class WPSEO_Content_Images {
|
||||
/**
|
||||
* Retrieves images from the post content.
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param \WP_Post|null $post The post object.
|
||||
* @param int $post_id The post ID.
|
||||
* @param WP_Post|null $post The post object.
|
||||
*
|
||||
* @return array An array of images found in this post.
|
||||
*/
|
||||
@@ -98,7 +98,8 @@ class WPSEO_Content_Images {
|
||||
/**
|
||||
* Filter: 'wpseo_pre_analysis_post_content' - Allow filtering the content before analysis.
|
||||
*
|
||||
* @api string $post_content The Post content string.
|
||||
* @param string $post_content The Post content string.
|
||||
* @param WP_Post $post The current post.
|
||||
*/
|
||||
$content = apply_filters( 'wpseo_pre_analysis_post_content', $post->post_content, $post );
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ class WPSEO_Image_Utils {
|
||||
*
|
||||
* Elements with keys not listed in the section will be discarded.
|
||||
*
|
||||
* @api array {
|
||||
* @param array $image_data {
|
||||
* Array of image data
|
||||
*
|
||||
* @type int id Image's ID as an attachment.
|
||||
@@ -162,7 +162,7 @@ class WPSEO_Image_Utils {
|
||||
* @type string url Image's URL.
|
||||
* @type int filesize The file size in bytes, if already set.
|
||||
* }
|
||||
* @api int Attachment ID.
|
||||
* @param int $attachment_id Attachment ID.
|
||||
*/
|
||||
$image = apply_filters( 'wpseo_image_data', $image, $attachment_id );
|
||||
|
||||
@@ -186,7 +186,7 @@ class WPSEO_Image_Utils {
|
||||
* Filter: 'wpseo_image_image_weight_limit' - Determines what the maximum weight
|
||||
* (in bytes) of an image is allowed to be, default is 2 MB.
|
||||
*
|
||||
* @api int - The maximum weight (in bytes) of an image.
|
||||
* @param int $max_bytes The maximum weight (in bytes) of an image.
|
||||
*/
|
||||
$max_size = apply_filters( 'wpseo_image_image_weight_limit', 2097152 );
|
||||
|
||||
@@ -404,7 +404,7 @@ class WPSEO_Image_Utils {
|
||||
/**
|
||||
* Filter: 'wpseo_image_sizes' - Determines which image sizes we'll loop through to get an appropriate image.
|
||||
*
|
||||
* @api array - The array of image sizes to loop through.
|
||||
* @param array<string> $sizes The array of image sizes to loop through.
|
||||
*/
|
||||
return apply_filters( 'wpseo_image_sizes', [ 'full', 'large', 'medium_large' ] );
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ class WPSEO_Installation {
|
||||
|
||||
/**
|
||||
* Sets the options on first install for showing the installation notice and disabling of the settings pages.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_first_install_options() {
|
||||
$options = get_option( 'wpseo' );
|
||||
|
||||
@@ -304,7 +304,7 @@ class WPSEO_Meta {
|
||||
register_meta(
|
||||
'post',
|
||||
self::$meta_prefix . $key,
|
||||
[ 'sanitize_callback' => [ __CLASS__, 'sanitize_post_meta' ] ]
|
||||
[ 'sanitize_callback' => [ self::class, 'sanitize_post_meta' ] ]
|
||||
);
|
||||
|
||||
// Set the $fields_index property for efficiency.
|
||||
@@ -327,8 +327,8 @@ class WPSEO_Meta {
|
||||
|
||||
self::filter_schema_article_types();
|
||||
|
||||
add_filter( 'update_post_metadata', [ __CLASS__, 'remove_meta_if_default' ], 10, 5 );
|
||||
add_filter( 'add_post_metadata', [ __CLASS__, 'dont_save_meta_if_default' ], 10, 4 );
|
||||
add_filter( 'update_post_metadata', [ self::class, 'remove_meta_if_default' ], 10, 5 );
|
||||
add_filter( 'add_post_metadata', [ self::class, 'dont_save_meta_if_default' ], 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -402,7 +402,7 @@ class WPSEO_Meta {
|
||||
/** This filter is documented in inc/options/class-wpseo-option-titles.php */
|
||||
$allowed_article_types = apply_filters( 'wpseo_schema_article_types', Schema_Types::ARTICLE_TYPES );
|
||||
|
||||
if ( ! \array_key_exists( $default_schema_article_type, $allowed_article_types ) ) {
|
||||
if ( ! array_key_exists( $default_schema_article_type, $allowed_article_types ) ) {
|
||||
$default_schema_article_type = WPSEO_Options::get_default( 'wpseo_titles', 'schema-article-type-' . $post_type );
|
||||
}
|
||||
$field_defs['schema_article_type']['default'] = $default_schema_article_type;
|
||||
|
||||
@@ -61,6 +61,8 @@ class WPSEO_Primary_Term {
|
||||
* Sets the new primary term ID.
|
||||
*
|
||||
* @param int $new_primary_term New primary term ID.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_primary_term( $new_primary_term ) {
|
||||
update_post_meta( $this->post_ID, WPSEO_Meta::$meta_prefix . 'primary_' . $this->taxonomy_name, $new_primary_term );
|
||||
|
||||
@@ -15,35 +15,35 @@ class WPSEO_Rank {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const BAD = 'bad';
|
||||
public const BAD = 'bad';
|
||||
|
||||
/**
|
||||
* Constant used for determining an OK SEO rating.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const OK = 'ok';
|
||||
public const OK = 'ok';
|
||||
|
||||
/**
|
||||
* Constant used for determining a good SEO rating.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const GOOD = 'good';
|
||||
public const GOOD = 'good';
|
||||
|
||||
/**
|
||||
* Constant used for determining that no focus keyphrase is set.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const NO_FOCUS = 'na';
|
||||
public const NO_FOCUS = 'na';
|
||||
|
||||
/**
|
||||
* Constant used for determining that this content is not indexed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const NO_INDEX = 'noindex';
|
||||
public const NO_INDEX = 'noindex';
|
||||
|
||||
/**
|
||||
* All possible ranks.
|
||||
|
||||
@@ -63,6 +63,8 @@ class WPSEO_Replace_Vars {
|
||||
|
||||
/**
|
||||
* Setup the help texts and external replacements as statics so they will be available to all instances.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setup_statics_once() {
|
||||
if ( self::$help_texts === [] ) {
|
||||
@@ -107,7 +109,7 @@ class WPSEO_Replace_Vars {
|
||||
elseif ( strpos( $var_to_replace, 'cf_' ) === 0 || strpos( $var_to_replace, 'ct_' ) === 0 ) {
|
||||
trigger_error( esc_html__( 'A replacement variable can not start with "%%cf_" or "%%ct_" as these are reserved for the WPSEO standard variable variables for custom fields and custom taxonomies. Try making your variable name unique.', 'wordpress-seo' ), E_USER_WARNING );
|
||||
}
|
||||
elseif ( ! method_exists( __CLASS__, 'retrieve_' . $var_to_replace ) ) {
|
||||
elseif ( ! method_exists( self::class, 'retrieve_' . $var_to_replace ) ) {
|
||||
if ( $var_to_replace !== '' && ! isset( self::$external_replacements[ $var_to_replace ] ) ) {
|
||||
self::$external_replacements[ $var_to_replace ] = $replace_function;
|
||||
$replacement_variable = new WPSEO_Replacement_Variable( $var_to_replace, $var_to_replace, $help_text );
|
||||
@@ -156,7 +158,7 @@ class WPSEO_Replace_Vars {
|
||||
|
||||
// Clean $omit array.
|
||||
if ( is_array( $omit ) && $omit !== [] ) {
|
||||
$omit = array_map( [ __CLASS__, 'remove_var_delimiter' ], $omit );
|
||||
$omit = array_map( [ self::class, 'remove_var_delimiter' ], $omit );
|
||||
}
|
||||
|
||||
$replacements = [];
|
||||
@@ -167,10 +169,9 @@ class WPSEO_Replace_Vars {
|
||||
/**
|
||||
* Filter: 'wpseo_replacements' - Allow customization of the replacements before they are applied.
|
||||
*
|
||||
* @api array $replacements The replacements.
|
||||
*
|
||||
* @param array $args The object some of the replacement values might come from,
|
||||
* could be a post, taxonomy or term.
|
||||
* @param array $replacements The replacements.
|
||||
* @param array $args The object some of the replacement values might come from,
|
||||
* could be a post, taxonomy or term.
|
||||
*/
|
||||
$replacements = apply_filters( 'wpseo_replacements', $replacements, $this->args );
|
||||
|
||||
@@ -190,12 +191,12 @@ class WPSEO_Replace_Vars {
|
||||
*
|
||||
* @example <code>add_filter( 'wpseo_replacements_final', '__return_false' );</code>
|
||||
*
|
||||
* @api bool $final
|
||||
* @param bool $final
|
||||
*/
|
||||
if ( apply_filters( 'wpseo_replacements_final', true ) === true && ( isset( $matches[1] ) && is_array( $matches[1] ) ) ) {
|
||||
// Remove non-replaced variables.
|
||||
$remove = array_diff( $matches[1], $omit ); // Make sure the $omit variables do not get removed.
|
||||
$remove = array_map( [ __CLASS__, 'add_var_delimiter' ], $remove );
|
||||
$remove = array_map( [ self::class, 'add_var_delimiter' ], $remove );
|
||||
$text = str_replace( $remove, '', $text );
|
||||
}
|
||||
|
||||
@@ -366,21 +367,17 @@ class WPSEO_Replace_Vars {
|
||||
// Returns a string.
|
||||
$replacement = YoastSEO()->helpers->date->format_translated( $this->args->post_date, get_option( 'date_format' ) );
|
||||
}
|
||||
else {
|
||||
if ( get_query_var( 'day' ) && get_query_var( 'day' ) !== '' ) {
|
||||
// Returns a string.
|
||||
$replacement = get_the_date();
|
||||
}
|
||||
else {
|
||||
if ( single_month_title( ' ', false ) && single_month_title( ' ', false ) !== '' ) {
|
||||
// Returns a string.
|
||||
$replacement = single_month_title( ' ', false );
|
||||
}
|
||||
elseif ( get_query_var( 'year' ) !== '' ) {
|
||||
// Returns an integer, let's cast to string.
|
||||
$replacement = (string) get_query_var( 'year' );
|
||||
}
|
||||
}
|
||||
elseif ( get_query_var( 'day' ) && get_query_var( 'day' ) !== '' ) {
|
||||
// Returns a string.
|
||||
$replacement = get_the_date();
|
||||
}
|
||||
elseif ( single_month_title( ' ', false ) && single_month_title( ' ', false ) !== '' ) {
|
||||
// Returns a string.
|
||||
$replacement = single_month_title( ' ', false );
|
||||
}
|
||||
elseif ( get_query_var( 'year' ) !== '' ) {
|
||||
// Returns an integer, let's cast to string.
|
||||
$replacement = (string) get_query_var( 'year' );
|
||||
}
|
||||
|
||||
return $replacement;
|
||||
@@ -394,7 +391,7 @@ class WPSEO_Replace_Vars {
|
||||
*/
|
||||
private function retrieve_excerpt() {
|
||||
$replacement = null;
|
||||
$locale = \get_locale();
|
||||
$locale = get_locale();
|
||||
|
||||
// Japanese doesn't have a jp_JP variant in WP.
|
||||
$limit = ( $locale === 'ja' ) ? 80 : 156;
|
||||
@@ -1148,7 +1145,7 @@ class WPSEO_Replace_Vars {
|
||||
return null;
|
||||
}
|
||||
|
||||
return \get_the_date( 'Y', $this->args->ID );
|
||||
return get_the_date( 'Y', $this->args->ID );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1161,7 +1158,7 @@ class WPSEO_Replace_Vars {
|
||||
return null;
|
||||
}
|
||||
|
||||
return \get_the_date( 'F', $this->args->ID );
|
||||
return get_the_date( 'F', $this->args->ID );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1174,7 +1171,7 @@ class WPSEO_Replace_Vars {
|
||||
return null;
|
||||
}
|
||||
|
||||
return \get_the_date( 'd', $this->args->ID );
|
||||
return get_the_date( 'd', $this->args->ID );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1221,7 +1218,7 @@ class WPSEO_Replace_Vars {
|
||||
return null;
|
||||
}
|
||||
|
||||
return \get_permalink( $this->args->ID );
|
||||
return get_permalink( $this->args->ID );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1280,6 +1277,8 @@ class WPSEO_Replace_Vars {
|
||||
*
|
||||
* @param string $type Type of variable: 'basic' or 'advanced'.
|
||||
* @param WPSEO_Replacement_Variable $replacement_variable The replacement variable to register.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function register_help_text( $type, WPSEO_Replacement_Variable $replacement_variable ) {
|
||||
$identifier = $replacement_variable->get_variable();
|
||||
@@ -1455,6 +1454,8 @@ class WPSEO_Replace_Vars {
|
||||
|
||||
/**
|
||||
* Set/translate the help texts for the WPSEO standard basic variables.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function set_basic_help_texts() {
|
||||
/* translators: %s: wp_title() function. */
|
||||
@@ -1505,6 +1506,8 @@ class WPSEO_Replace_Vars {
|
||||
|
||||
/**
|
||||
* Set/translate the help texts for the WPSEO standard advanced variables.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function set_advanced_help_texts() {
|
||||
$replacement_variables = [
|
||||
@@ -1591,8 +1594,8 @@ class WPSEO_Replace_Vars {
|
||||
* Allows filtering of the terms list used to replace %%category%%, %%tag%%
|
||||
* and %%ct_<custom-tax-name>%% variables.
|
||||
*
|
||||
* @api string $output Comma-delimited string containing the terms.
|
||||
* @api string $taxonomy The taxonomy of the terms.
|
||||
* @param string $output Comma-delimited string containing the terms.
|
||||
* @param string $taxonomy The taxonomy of the terms.
|
||||
*/
|
||||
return apply_filters( 'wpseo_terms', $output, $taxonomy );
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ class WPSEO_Shortlinker {
|
||||
* Echoes a version of the URL with a utm_content with the current version.
|
||||
*
|
||||
* @param string $url The URL to build upon.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function show( $url ) {
|
||||
YoastSEO()->helpers->short_link->show( $url );
|
||||
|
||||
@@ -43,7 +43,7 @@ class WPSEO_Utils {
|
||||
* Filter: 'wpseo_allow_system_file_edit' - Allow developers to change whether the editing of
|
||||
* .htaccess and robots.txt is allowed.
|
||||
*
|
||||
* @api bool $allowed Whether file editing is allowed.
|
||||
* @param bool $allowed Whether file editing is allowed.
|
||||
*/
|
||||
return apply_filters( 'wpseo_allow_system_file_edit', $allowed );
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class WPSEO_Utils {
|
||||
$value = trim( $value );
|
||||
}
|
||||
elseif ( is_array( $value ) ) {
|
||||
$value = array_map( [ __CLASS__, 'trim_recursive' ], $value );
|
||||
$value = array_map( [ self::class, 'trim_recursive' ], $value );
|
||||
}
|
||||
|
||||
return $value;
|
||||
@@ -232,7 +232,7 @@ class WPSEO_Utils {
|
||||
if ( strpos( $url, '%' ) !== false ) {
|
||||
$url = preg_replace_callback(
|
||||
'`%[a-fA-F0-9]{2}`',
|
||||
static function( $octects ) {
|
||||
static function ( $octects ) {
|
||||
return strtolower( $octects[0] );
|
||||
},
|
||||
$url
|
||||
@@ -253,7 +253,7 @@ class WPSEO_Utils {
|
||||
*/
|
||||
public static function sanitize_encoded_text_field( $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
return array_map( [ __CLASS__, 'sanitize_encoded_text_field' ], $value );
|
||||
return array_map( [ self::class, 'sanitize_encoded_text_field' ], $value );
|
||||
}
|
||||
|
||||
return rawurlencode( sanitize_text_field( rawurldecode( $value ) ) );
|
||||
@@ -381,7 +381,7 @@ class WPSEO_Utils {
|
||||
return $value;
|
||||
}
|
||||
elseif ( is_float( $value ) ) {
|
||||
// phpcs:ignore WordPress.PHP.StrictComparisons -- Purposeful loose comparison.
|
||||
// phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison.
|
||||
if ( (int) $value == $value && ! is_nan( $value ) ) {
|
||||
return (int) $value;
|
||||
}
|
||||
@@ -412,6 +412,8 @@ class WPSEO_Utils {
|
||||
* Clears the WP or W3TC cache depending on which is used.
|
||||
*
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clear_cache() {
|
||||
if ( function_exists( 'w3tc_pgcache_flush' ) ) {
|
||||
@@ -426,6 +428,8 @@ class WPSEO_Utils {
|
||||
* Clear rewrite rules.
|
||||
*
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clear_rewrites() {
|
||||
update_option( 'rewrite_rules', '' );
|
||||
@@ -506,7 +510,7 @@ class WPSEO_Utils {
|
||||
if ( $bc ) {
|
||||
$result = bcdiv( $number1, $number2, $precision ); // String, or NULL if right_operand is 0.
|
||||
}
|
||||
elseif ( $number2 != 0 ) { // phpcs:ignore WordPress.PHP.StrictComparisons -- Purposeful loose comparison.
|
||||
elseif ( $number2 != 0 ) { // phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison.
|
||||
$result = ( $number1 / $number2 );
|
||||
}
|
||||
|
||||
@@ -521,7 +525,7 @@ class WPSEO_Utils {
|
||||
if ( $bc ) {
|
||||
$result = bcmod( $number1, $number2 ); // String, or NULL if modulus is 0.
|
||||
}
|
||||
elseif ( $number2 != 0 ) { // phpcs:ignore WordPress.PHP.StrictComparisons -- Purposeful loose comparison.
|
||||
elseif ( $number2 != 0 ) { // phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison.
|
||||
$result = ( $number1 % $number2 );
|
||||
}
|
||||
|
||||
@@ -538,7 +542,7 @@ class WPSEO_Utils {
|
||||
$result = bccomp( $number1, $number2, $precision ); // Returns int 0, 1 or -1.
|
||||
}
|
||||
else {
|
||||
// phpcs:ignore WordPress.PHP.StrictComparisons -- Purposeful loose comparison.
|
||||
// phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison.
|
||||
$result = ( $number1 == $number2 ) ? 0 : ( ( $number1 > $number2 ) ? 1 : -1 );
|
||||
}
|
||||
break;
|
||||
@@ -553,7 +557,7 @@ class WPSEO_Utils {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// phpcs:ignore WordPress.PHP.StrictComparisons -- Purposeful loose comparison.
|
||||
// phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison.
|
||||
$result = ( intval( $result ) == $result ) ? intval( $result ) : floatval( $result );
|
||||
}
|
||||
}
|
||||
@@ -802,7 +806,7 @@ class WPSEO_Utils {
|
||||
* @return string The post type, or an empty string.
|
||||
*/
|
||||
public static function get_post_type() {
|
||||
$wp_screen = \get_current_screen();
|
||||
$wp_screen = get_current_screen();
|
||||
|
||||
if ( $wp_screen !== null && ! empty( $wp_screen->post_type ) ) {
|
||||
return $wp_screen->post_type;
|
||||
@@ -843,7 +847,7 @@ class WPSEO_Utils {
|
||||
else {
|
||||
$label_object = WPSEO_Taxonomy::get_labels();
|
||||
|
||||
$wp_screen = \get_current_screen();
|
||||
$wp_screen = get_current_screen();
|
||||
|
||||
if ( $wp_screen !== null && ! empty( $wp_screen->taxonomy ) ) {
|
||||
$taxonomy_slug = $wp_screen->taxonomy;
|
||||
@@ -920,12 +924,12 @@ class WPSEO_Utils {
|
||||
/**
|
||||
* Filter the Yoast SEO development mode.
|
||||
*
|
||||
* @api array $data Allows filtering of the JSON data for debug purposes.
|
||||
* @param array $data Allows filtering of the JSON data for debug purposes.
|
||||
*/
|
||||
$data = apply_filters( 'wpseo_debug_json_data', $data );
|
||||
}
|
||||
|
||||
// phpcs:ignore Yoast.Yoast.AlternativeFunctions.json_encode_wp_json_encodeWithAdditionalParams -- This is the definition of format_json_encode.
|
||||
// phpcs:ignore Yoast.Yoast.JsonEncodeAlternative.FoundWithAdditionalParams -- This is the definition of format_json_encode.
|
||||
return wp_json_encode( $data, $flags );
|
||||
}
|
||||
|
||||
@@ -1095,30 +1099,4 @@ class WPSEO_Utils {
|
||||
$feature_flag_integration = YoastSEO()->classes->get( Feature_Flag_Integration::class );
|
||||
return $feature_flag_integration->get_enabled_features();
|
||||
}
|
||||
|
||||
/* ********************* DEPRECATED METHODS ********************* */
|
||||
|
||||
/**
|
||||
* Translates a decimal analysis score into a textual one.
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @deprecated 19.5
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param int $val The decimal score to translate.
|
||||
* @param bool $css_value Whether to return the i18n translated score or the CSS class value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function translate_score( $val, $css_value = true ) {
|
||||
_deprecated_function( __METHOD__, 'Yoast SEO 19.5', 'YoastSEO()->helpers->score_icon' );
|
||||
|
||||
$seo_rank = WPSEO_Rank::from_numeric_score( $val );
|
||||
|
||||
if ( $css_value ) {
|
||||
return $seo_rank->get_css_class();
|
||||
}
|
||||
|
||||
return $seo_rank->get_label();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
/**
|
||||
* WPSEO plugin file.
|
||||
*
|
||||
* @package WPSEO\Internals
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class containing an alternative rewrite rules API for handling them dynamically without requiring flushing rules.
|
||||
*/
|
||||
class Yoast_Dynamic_Rewrites implements WPSEO_WordPress_Integration {
|
||||
|
||||
/**
|
||||
* Additional rewrite rules with high priority.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extra_rules_top = [];
|
||||
|
||||
/**
|
||||
* Additional rewrite rules with low priority.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extra_rules_bottom = [];
|
||||
|
||||
/**
|
||||
* Main instance holder.
|
||||
*
|
||||
* @var self|null
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* WP_Rewrite instance to use.
|
||||
*
|
||||
* @var WP_Rewrite
|
||||
*/
|
||||
public $wp_rewrite;
|
||||
|
||||
/**
|
||||
* Gets the main instance of the class.
|
||||
*
|
||||
* @return self Dynamic rewrites main instance.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( self::$instance === null ) {
|
||||
self::$instance = new self();
|
||||
self::$instance->register_hooks();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets the WP_Rewrite instance to use.
|
||||
*
|
||||
* @param WP_Rewrite|null $rewrite Optional. WP_Rewrite instance to use. Default is the $wp_rewrite global.
|
||||
* @throws RuntimeException Throws an exception if the $wp_rewrite global is not set.
|
||||
*/
|
||||
public function __construct( $rewrite = null ) {
|
||||
if ( ! $rewrite ) {
|
||||
if ( empty( $GLOBALS['wp_rewrite'] ) ) {
|
||||
/* translators: 1: PHP class name, 2: PHP variable name */
|
||||
throw new RuntimeException( sprintf( __( 'The %1$s class must not be instantiated before the %2$s global is set.', 'wordpress-seo' ), self::class, '$wp_rewrite' ) );
|
||||
}
|
||||
|
||||
$rewrite = $GLOBALS['wp_rewrite'];
|
||||
}
|
||||
|
||||
$this->wp_rewrite = $rewrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all necessary hooks with WordPress.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks() {
|
||||
add_action( 'init', [ $this, 'trigger_dynamic_rewrite_rules_hook' ], 1 );
|
||||
add_filter( 'option_rewrite_rules', [ $this, 'filter_rewrite_rules_option' ] );
|
||||
add_filter( 'sanitize_option_rewrite_rules', [ $this, 'sanitize_rewrite_rules_option' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dynamic rewrite rule that transforms a URL structure to a set of query vars.
|
||||
*
|
||||
* Rules registered with this method are applied dynamically and do not require the rewrite rules
|
||||
* to be flushed in order to become active, which is a benefit over the regular WordPress core API.
|
||||
* Note however that the dynamic application only works for rules that correspond to index.php.
|
||||
* Non-WordPress rewrite rules still require flushing.
|
||||
*
|
||||
* Any value in the $after parameter that isn't 'bottom' will result in the rule
|
||||
* being placed at the top of the rewrite rules.
|
||||
*
|
||||
* @param string $regex Regular expression to match request against.
|
||||
* @param string|array $query The corresponding query vars for this rewrite rule.
|
||||
* @param string $priority Optional. Priority of the new rule. Accepts 'top'
|
||||
* or 'bottom'. Default 'bottom'.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_rule( $regex, $query, $priority = 'bottom' ) {
|
||||
if ( is_array( $query ) ) {
|
||||
$query = add_query_arg( $query, 'index.php' );
|
||||
}
|
||||
|
||||
$this->wp_rewrite->add_rule( $regex, $query, $priority );
|
||||
|
||||
// Do not further handle external rules.
|
||||
if ( substr( $query, 0, strlen( $this->wp_rewrite->index . '?' ) ) !== $this->wp_rewrite->index . '?' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $priority === 'bottom' ) {
|
||||
$this->extra_rules_bottom[ $regex ] = $query;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->extra_rules_top[ $regex ] = $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the hook on which rewrite rules should be added.
|
||||
*
|
||||
* This allows for a more specific point in time from the generic `init` hook where this is
|
||||
* otherwise handled.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function trigger_dynamic_rewrite_rules_hook() {
|
||||
|
||||
/**
|
||||
* Fires when the plugin's dynamic rewrite rules should be added.
|
||||
*
|
||||
* @param self $dynamic_rewrites Dynamic rewrites handler instance. Use its `add_rule()` method
|
||||
* to add dynamic rewrite rules.
|
||||
*/
|
||||
do_action( 'yoast_add_dynamic_rewrite_rules', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the rewrite rules option to dynamically add additional rewrite rules.
|
||||
*
|
||||
* @param array|string $rewrite_rules Array of rewrite rule $regex => $query pairs, or empty string
|
||||
* if currently not set.
|
||||
*
|
||||
* @return array|string Filtered value of $rewrite_rules.
|
||||
*/
|
||||
public function filter_rewrite_rules_option( $rewrite_rules ) {
|
||||
// Do not add extra rewrite rules if the rules need to be flushed.
|
||||
if ( empty( $rewrite_rules ) ) {
|
||||
return $rewrite_rules;
|
||||
}
|
||||
|
||||
return array_merge( $this->extra_rules_top, $rewrite_rules, $this->extra_rules_bottom );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the rewrite rules option prior to writing it to the database.
|
||||
*
|
||||
* This method ensures that the dynamic rewrite rules do not become part of the actual option.
|
||||
*
|
||||
* @param array|string $rewrite_rules Array pf rewrite rule $regex => $query pairs, or empty string
|
||||
* in order to unset.
|
||||
*
|
||||
* @return array|string Filtered value of $rewrite_rules before writing the option.
|
||||
*/
|
||||
public function sanitize_rewrite_rules_option( $rewrite_rules ) {
|
||||
if ( empty( $rewrite_rules ) ) {
|
||||
return $rewrite_rules;
|
||||
}
|
||||
|
||||
return array_diff_key( $rewrite_rules, $this->extra_rules_top, $this->extra_rules_bottom );
|
||||
}
|
||||
}
|
||||
@@ -182,6 +182,8 @@ class WPSEO_Option_Titles extends WPSEO_Option {
|
||||
|
||||
/**
|
||||
* Make sure we can recognize the right action for the double cleaning.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function end_of_init() {
|
||||
do_action( 'wpseo_double_clean_titles' );
|
||||
@@ -211,7 +213,7 @@ class WPSEO_Option_Titles extends WPSEO_Option {
|
||||
/**
|
||||
* Allow altering the array with separator options.
|
||||
*
|
||||
* @api array $separator_options Array with the separator options.
|
||||
* @param array $separator_options Array with the separator options.
|
||||
*/
|
||||
$filtered_separators = apply_filters( 'wpseo_separator_options', $separators );
|
||||
|
||||
@@ -234,7 +236,7 @@ class WPSEO_Option_Titles extends WPSEO_Option {
|
||||
$separator_options = [];
|
||||
|
||||
foreach ( $separators as $key => $label ) {
|
||||
$aria_label = isset( $separator_list[ $key ]['label'] ) ? $separator_list[ $key ]['label'] : '';
|
||||
$aria_label = ( $separator_list[ $key ]['label'] ?? '' );
|
||||
|
||||
$separator_options[ $key ] = [
|
||||
'label' => $label,
|
||||
@@ -640,7 +642,7 @@ class WPSEO_Option_Titles extends WPSEO_Option {
|
||||
*
|
||||
* Make sure when you filter this to also filter `wpseo_schema_article_types_labels`.
|
||||
*
|
||||
* @api array $schema_article_types The available schema article types.
|
||||
* @param array $schema_article_types The available schema article types.
|
||||
*/
|
||||
if ( array_key_exists( $dirty[ $key ], apply_filters( 'wpseo_schema_article_types', Schema_Types::ARTICLE_TYPES ) ) ) {
|
||||
$clean[ $key ] = $dirty[ $key ];
|
||||
@@ -845,10 +847,8 @@ class WPSEO_Option_Titles extends WPSEO_Option {
|
||||
if ( ! isset( $post_type_names[ $tax ] ) && isset( $option_value[ $old_prefix . $tax ] ) ) {
|
||||
unset( $option_value[ $old_prefix . $tax ] );
|
||||
}
|
||||
else {
|
||||
if ( isset( $post_type_names[ $tax ] ) && ! isset( $option_value[ $old_prefix . $tax ] ) ) {
|
||||
$option_value[ $old_prefix . $tax ] = $original[ $old_prefix . $tax ];
|
||||
}
|
||||
elseif ( isset( $post_type_names[ $tax ] ) && ! isset( $option_value[ $old_prefix . $tax ] ) ) {
|
||||
$option_value[ $old_prefix . $tax ] = $original[ $old_prefix . $tax ];
|
||||
}
|
||||
|
||||
if ( $old_prefix === 'tax-hideeditbox-' ) {
|
||||
@@ -929,7 +929,7 @@ class WPSEO_Option_Titles extends WPSEO_Option {
|
||||
/**
|
||||
* Allow altering the array with variable array key patterns.
|
||||
*
|
||||
* @api array $patterns Array with the variable array key patterns.
|
||||
* @param array $patterns Array with the variable array key patterns.
|
||||
*/
|
||||
$patterns = apply_filters( 'wpseo_option_titles_variable_array_key_patterns', $patterns );
|
||||
|
||||
@@ -1020,7 +1020,7 @@ class WPSEO_Option_Titles extends WPSEO_Option {
|
||||
/**
|
||||
* Allows altering the separator options array.
|
||||
*
|
||||
* @api array $separators Array with the separator options.
|
||||
* @param array $separators Array with the separator options.
|
||||
*/
|
||||
$separator_list = apply_filters( 'wpseo_separator_option_list', $separators );
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ class WPSEO_Option_Wpseo extends WPSEO_Option {
|
||||
/**
|
||||
* Filter: 'wpseo_enable_tracking' - Enables the data tracking of Yoast SEO Premium.
|
||||
*
|
||||
* @api string $is_enabled The enabled state. Default is false.
|
||||
* @param string $is_enabled The enabled state. Default is false.
|
||||
*/
|
||||
$this->defaults['tracking'] = apply_filters( 'wpseo_enable_tracking', false );
|
||||
|
||||
@@ -469,7 +469,7 @@ class WPSEO_Option_Wpseo extends WPSEO_Option {
|
||||
|
||||
if ( is_array( $items ) ) {
|
||||
foreach ( $items as $item_key => $item ) {
|
||||
if ( ! \is_string( $item_key ) || ! \is_numeric( $item ) ) {
|
||||
if ( ! is_string( $item_key ) || ! is_numeric( $item ) ) {
|
||||
unset( $items[ $item_key ] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ abstract class WPSEO_Option {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ALLOW_KEY_PREFIX = 'allow_';
|
||||
public const ALLOW_KEY_PREFIX = 'allow_';
|
||||
|
||||
/**
|
||||
* Option name - MUST be set in concrete class and set to public.
|
||||
@@ -186,9 +186,6 @@ abstract class WPSEO_Option {
|
||||
*/
|
||||
add_filter( 'sanitize_option_' . $this->option_name, [ $this, 'validate' ] );
|
||||
|
||||
// Flushes the rewrite rules when option is updated.
|
||||
add_action( 'update_option_' . $this->option_name, [ 'WPSEO_Utils', 'clear_rewrites' ] );
|
||||
|
||||
/* Register our option for the admin pages */
|
||||
add_action( 'admin_init', [ $this, 'register_setting' ] );
|
||||
|
||||
@@ -296,6 +293,8 @@ abstract class WPSEO_Option {
|
||||
* @param array $dirty Dirty data with the new values.
|
||||
* @param array $old Old data.
|
||||
* @param array $clean Clean data by reference, normally the default values.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validate_verification_string( $key, $dirty, $old, &$clean ) {
|
||||
if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) {
|
||||
@@ -371,6 +370,8 @@ abstract class WPSEO_Option {
|
||||
* @param array $dirty Dirty data with the new values.
|
||||
* @param array $old Old data.
|
||||
* @param array $clean Clean data by reference, normally the default values.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validate_url( $key, $dirty, $old, &$clean ) {
|
||||
if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) {
|
||||
@@ -870,7 +871,7 @@ abstract class WPSEO_Option {
|
||||
/**
|
||||
* Check whether a given array key conforms to one of the variable array key patterns for this option.
|
||||
*
|
||||
* @usedby validate_option() methods for options with variable array keys.
|
||||
* @used-by validate_option() methods for options with variable array keys.
|
||||
*
|
||||
* @param string $key Array key to check.
|
||||
*
|
||||
|
||||
@@ -66,6 +66,8 @@ class WPSEO_Options {
|
||||
|
||||
/**
|
||||
* Register our hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_hooks() {
|
||||
add_action( 'registered_taxonomy', [ $this, 'clear_cache' ] );
|
||||
@@ -91,6 +93,8 @@ class WPSEO_Options {
|
||||
* Registers an option to the options list.
|
||||
*
|
||||
* @param WPSEO_Option $option_instance Instance of the option.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_option( WPSEO_Option $option_instance ) {
|
||||
$option_name = $option_instance->get_option_name();
|
||||
@@ -200,7 +204,7 @@ class WPSEO_Options {
|
||||
/**
|
||||
* Filter: wpseo_options - Allow developers to change the option name to include.
|
||||
*
|
||||
* @api array The option names to include in get_all and reset().
|
||||
* @param array $option_names The option names to include in get_all and reset().
|
||||
*/
|
||||
return apply_filters( 'wpseo_options', $option_names );
|
||||
}
|
||||
@@ -283,6 +287,8 @@ class WPSEO_Options {
|
||||
|
||||
/**
|
||||
* Resets the cache to null.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clear_cache() {
|
||||
static::$option_values = null;
|
||||
@@ -290,6 +296,8 @@ class WPSEO_Options {
|
||||
|
||||
/**
|
||||
* Primes our cache.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function prime_cache() {
|
||||
static::$option_values = static::get_all();
|
||||
|
||||
@@ -119,6 +119,8 @@ class WPSEO_Taxonomy_Meta extends WPSEO_Option {
|
||||
|
||||
/**
|
||||
* Add extra default options received from a filter.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enrich_defaults() {
|
||||
$extra_defaults_per_term = apply_filters( 'wpseo_add_extra_taxmeta_term_defaults', [] );
|
||||
@@ -291,7 +293,7 @@ class WPSEO_Taxonomy_Meta extends WPSEO_Option {
|
||||
break;
|
||||
}
|
||||
|
||||
$clean[ $key ] = apply_filters( 'wpseo_sanitize_tax_meta_' . $key, $clean[ $key ], ( isset( $meta_data[ $key ] ) ? $meta_data[ $key ] : null ), ( isset( $old_meta[ $key ] ) ? $old_meta[ $key ] : null ) );
|
||||
$clean[ $key ] = apply_filters( 'wpseo_sanitize_tax_meta_' . $key, $clean[ $key ], ( $meta_data[ $key ] ?? null ), ( $old_meta[ $key ] ?? null ) );
|
||||
}
|
||||
|
||||
// Only save the non-default values.
|
||||
@@ -438,6 +440,8 @@ class WPSEO_Taxonomy_Meta extends WPSEO_Option {
|
||||
* @param int $term_id ID of the term to save data for.
|
||||
* @param string $taxonomy The taxonomy the term belongs to.
|
||||
* @param array $meta_values The values that will be saved.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function set_values( $term_id, $taxonomy, array $meta_values ) {
|
||||
/* Validate the post values */
|
||||
@@ -454,6 +458,8 @@ class WPSEO_Taxonomy_Meta extends WPSEO_Option {
|
||||
* @param string $taxonomy The taxonomy the term belongs to.
|
||||
* @param string $meta_key The target meta key to store the value in.
|
||||
* @param string $meta_value The value of the target meta key.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function set_value( $term_id, $taxonomy, $meta_key, $meta_value ) {
|
||||
|
||||
@@ -496,6 +502,8 @@ class WPSEO_Taxonomy_Meta extends WPSEO_Option {
|
||||
* @param int $term_id ID of the term to save data for.
|
||||
* @param string $taxonomy The taxonomy the term belongs to.
|
||||
* @param array $clean Array with clean values.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function save_clean_values( $term_id, $taxonomy, array $clean ) {
|
||||
$tax_meta = self::get_tax_meta();
|
||||
@@ -530,6 +538,8 @@ class WPSEO_Taxonomy_Meta extends WPSEO_Option {
|
||||
* Saving the tax meta values to the database.
|
||||
*
|
||||
* @param array $tax_meta Array with the meta values for taxonomy.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function save_tax_meta( $tax_meta ) {
|
||||
update_option( self::$name, $tax_meta );
|
||||
|
||||
@@ -115,32 +115,7 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
$all_dates = [];
|
||||
|
||||
if ( $max_pages > 1 ) {
|
||||
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) );
|
||||
|
||||
if ( version_compare( $wpdb->db_version(), '8.0', '>=' ) ) {
|
||||
$sql = "
|
||||
WITH ordering AS (SELECT ROW_NUMBER() OVER (ORDER BY post_modified_gmt) AS n, post_modified_gmt
|
||||
FROM {$wpdb->posts} USE INDEX ( type_status_date )
|
||||
WHERE post_status IN ('" . implode( "','", $post_statuses ) . "')
|
||||
AND post_type = %s
|
||||
ORDER BY post_modified_gmt)
|
||||
SELECT post_modified_gmt
|
||||
FROM ordering
|
||||
WHERE MOD(n, %d) = 0;";
|
||||
}
|
||||
else {
|
||||
$sql = "
|
||||
SELECT post_modified_gmt
|
||||
FROM ( SELECT @rownum:=0 ) init
|
||||
JOIN {$wpdb->posts} USE INDEX( type_status_date )
|
||||
WHERE post_status IN ('" . implode( "','", $post_statuses ) . "')
|
||||
AND post_type = %s
|
||||
AND ( @rownum:=@rownum+1 ) %% %d = 0
|
||||
ORDER BY post_modified_gmt ASC
|
||||
";
|
||||
}
|
||||
|
||||
$all_dates = $wpdb->get_col( $wpdb->prepare( $sql, $post_type, $max_entries ) );
|
||||
$all_dates = version_compare( $wpdb->db_version(), '8.0', '>=' ) ? $this->get_all_dates_using_with_clause( $post_type, $max_entries ) : $this->get_all_dates( $post_type, $max_entries );
|
||||
}
|
||||
|
||||
for ( $page_counter = 0; $page_counter < $max_pages; $page_counter++ ) {
|
||||
@@ -175,8 +150,9 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
* @param int $max_entries Entries per sitemap.
|
||||
* @param int $current_page Current page of the sitemap.
|
||||
*
|
||||
* @throws OutOfBoundsException When an invalid page is requested.
|
||||
* @return array
|
||||
*
|
||||
* @throws OutOfBoundsException When an invalid page is requested.
|
||||
*/
|
||||
public function get_sitemap_links( $type, $max_entries, $current_page ) {
|
||||
|
||||
@@ -262,6 +238,8 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
* Check for relevant post type before invalidation.
|
||||
*
|
||||
* @param int $post_id Post ID to possibly invalidate for.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save_post( $post_id ) {
|
||||
|
||||
@@ -313,7 +291,7 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
/**
|
||||
* Filter: 'wpseo_exclude_from_sitemap_by_post_ids' - Allow extending and modifying the posts to exclude.
|
||||
*
|
||||
* @api array $posts_to_exclude The posts to exclude.
|
||||
* @param array $posts_to_exclude The posts to exclude.
|
||||
*/
|
||||
$excluded_posts_ids = apply_filters( 'wpseo_exclude_from_sitemap_by_post_ids', $excluded_posts_ids );
|
||||
if ( ! is_array( $excluded_posts_ids ) ) {
|
||||
@@ -401,6 +379,19 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
$front_page['chf'] = 'daily';
|
||||
$front_page['pri'] = 1;
|
||||
|
||||
$images = [];
|
||||
|
||||
/**
|
||||
* Filter images to be included for the term in XML sitemap.
|
||||
*
|
||||
* @param array $images Array of image items.
|
||||
* @return array $image_list Array of image items.
|
||||
*/
|
||||
$image_list = apply_filters( 'wpseo_sitemap_urlimages_front_page', $images );
|
||||
if ( isset( $image_list ) && is_array( $image_list ) ) {
|
||||
$front_page['images'] = $image_list;
|
||||
}
|
||||
|
||||
$links[] = $front_page;
|
||||
}
|
||||
elseif ( $post_type !== 'page' ) {
|
||||
@@ -675,4 +666,101 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all dates for a post type by using the WITH clause for performance.
|
||||
*
|
||||
* @param string $post_type Post type to retrieve dates for.
|
||||
* @param int $max_entries Maximum number of entries to retrieve.
|
||||
*
|
||||
* @return array Array of dates.
|
||||
*/
|
||||
private function get_all_dates_using_with_clause( $post_type, $max_entries ) {
|
||||
global $wpdb;
|
||||
|
||||
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) );
|
||||
|
||||
$replacements = array_merge(
|
||||
[
|
||||
'ordering',
|
||||
'post_modified_gmt',
|
||||
$wpdb->posts,
|
||||
'type_status_date',
|
||||
'post_status',
|
||||
],
|
||||
$post_statuses,
|
||||
[
|
||||
'post_type',
|
||||
$post_type,
|
||||
'post_modified_gmt',
|
||||
'post_modified_gmt',
|
||||
'ordering',
|
||||
$max_entries,
|
||||
]
|
||||
);
|
||||
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
||||
return $wpdb->get_col(
|
||||
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
|
||||
$wpdb->prepare(
|
||||
'
|
||||
WITH %i AS (SELECT ROW_NUMBER() OVER (ORDER BY %i) AS n, post_modified_gmt
|
||||
FROM %i USE INDEX ( %i )
|
||||
WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ')
|
||||
AND %i = %s
|
||||
ORDER BY %i)
|
||||
SELECT %i
|
||||
FROM %i
|
||||
WHERE MOD(n, %d) = 0;
|
||||
',
|
||||
$replacements
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all dates for a post type.
|
||||
*
|
||||
* @param string $post_type Post type to retrieve dates for.
|
||||
* @param int $max_entries Maximum number of entries to retrieve.
|
||||
*
|
||||
* @return array Array of dates.
|
||||
*/
|
||||
private function get_all_dates( $post_type, $max_entries ) {
|
||||
global $wpdb;
|
||||
|
||||
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) );
|
||||
$replacements = array_merge(
|
||||
[
|
||||
'post_modified_gmt',
|
||||
$wpdb->posts,
|
||||
'type_status_date',
|
||||
'post_status',
|
||||
],
|
||||
$post_statuses,
|
||||
[
|
||||
'post_type',
|
||||
$post_type,
|
||||
$max_entries,
|
||||
'post_modified_gmt',
|
||||
]
|
||||
);
|
||||
|
||||
return $wpdb->get_col(
|
||||
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
|
||||
$wpdb->prepare(
|
||||
'
|
||||
SELECT %i
|
||||
FROM ( SELECT @rownum:=0 ) init
|
||||
JOIN %i USE INDEX( %i )
|
||||
WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ')
|
||||
AND %i = %s
|
||||
AND ( @rownum:=@rownum+1 ) %% %d = 0
|
||||
ORDER BY %i ASC
|
||||
',
|
||||
$replacements
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ class WPSEO_Sitemap_Cache_Data implements Serializable, WPSEO_Sitemap_Cache_Data
|
||||
* Set the sitemap XML data
|
||||
*
|
||||
* @param string $sitemap XML Content of the sitemap.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_sitemap( $sitemap ) {
|
||||
|
||||
|
||||
@@ -124,7 +124,10 @@ class WPSEO_Sitemap_Image_Parser {
|
||||
* @param array $images Array of image items.
|
||||
* @param int $post_id ID of the post.
|
||||
*/
|
||||
$images = apply_filters( 'wpseo_sitemap_urlimages', $images, $post->ID );
|
||||
$image_list = apply_filters( 'wpseo_sitemap_urlimages', $images, $post->ID );
|
||||
if ( isset( $image_list ) && is_array( $image_list ) ) {
|
||||
$images = $image_list;
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
@@ -147,6 +150,17 @@ class WPSEO_Sitemap_Image_Parser {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter images to be included for the term in XML sitemap.
|
||||
*
|
||||
* @param array $image_list Array of image items.
|
||||
* @param int $term_id ID of the post.
|
||||
*/
|
||||
$image_list = apply_filters( 'wpseo_sitemap_urlimages_term', $images, $term->term_id );
|
||||
if ( isset( $image_list ) && is_array( $image_list ) ) {
|
||||
$images = $image_list;
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,9 +33,11 @@ class WPSEO_Sitemaps_Admin {
|
||||
* if the post is being published, is a post type that a sitemap is built for
|
||||
* and is a post that is included in sitemaps.
|
||||
*
|
||||
* @param string $new_status New post status.
|
||||
* @param string $old_status Old post status.
|
||||
* @param \WP_Post $post Post object.
|
||||
* @param string $new_status New post status.
|
||||
* @param string $old_status Old post status.
|
||||
* @param WP_Post $post Post object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function status_transition( $new_status, $old_status, $post ) {
|
||||
if ( $new_status !== 'publish' ) {
|
||||
@@ -71,6 +73,8 @@ class WPSEO_Sitemaps_Admin {
|
||||
|
||||
/**
|
||||
* Notify Google of the updated sitemap.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ping_search_engines() {
|
||||
|
||||
@@ -81,7 +85,7 @@ class WPSEO_Sitemaps_Admin {
|
||||
/**
|
||||
* Filter: 'wpseo_allow_xml_sitemap_ping' - Check if pinging is not allowed (allowed by default).
|
||||
*
|
||||
* @api boolean $allow_ping The boolean that is set to true by default.
|
||||
* @param bool $allow_ping The boolean that is set to true by default.
|
||||
*/
|
||||
if ( apply_filters( 'wpseo_allow_xml_sitemap_ping', true ) === false ) {
|
||||
return;
|
||||
@@ -103,9 +107,11 @@ class WPSEO_Sitemaps_Admin {
|
||||
* When importing is done, if we have a post_type that is saved in the sitemap
|
||||
* try to ping the search engines.
|
||||
*
|
||||
* @param string $new_status New post status.
|
||||
* @param string $old_status Old post status.
|
||||
* @param \WP_Post $post Post object.
|
||||
* @param string $new_status New post status.
|
||||
* @param string $old_status Old post status.
|
||||
* @param WP_Post $post Post object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function status_transition_bulk( $new_status, $old_status, $post ) {
|
||||
$this->importing_post_types[] = get_post_type( $post );
|
||||
@@ -114,6 +120,8 @@ class WPSEO_Sitemaps_Admin {
|
||||
|
||||
/**
|
||||
* After import finished, walk through imported post_types and update info.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function status_transition_bulk_finished() {
|
||||
if ( ! defined( 'WP_IMPORTING' ) ) {
|
||||
|
||||
@@ -17,21 +17,21 @@ class WPSEO_Sitemaps_Cache_Validator {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const STORAGE_KEY_PREFIX = 'yst_sm_';
|
||||
public const STORAGE_KEY_PREFIX = 'yst_sm_';
|
||||
|
||||
/**
|
||||
* Name of the option that holds the global validation value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VALIDATION_GLOBAL_KEY = 'wpseo_sitemap_cache_validator_global';
|
||||
public const VALIDATION_GLOBAL_KEY = 'wpseo_sitemap_cache_validator_global';
|
||||
|
||||
/**
|
||||
* The format which creates the key of the option that holds the type validation value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VALIDATION_TYPE_KEY_FORMAT = 'wpseo_sitemap_%s_cache_validator';
|
||||
public const VALIDATION_TYPE_KEY_FORMAT = 'wpseo_sitemap_%s_cache_validator';
|
||||
|
||||
/**
|
||||
* Get the cache key for a certain type and page.
|
||||
@@ -189,8 +189,15 @@ class WPSEO_Sitemaps_Cache_Validator {
|
||||
$where[] = sprintf( "option_name LIKE '%s'", addcslashes( '_transient_timeout_' . $like, '_' ) );
|
||||
|
||||
// Delete transients.
|
||||
$query = sprintf( 'DELETE FROM %1$s WHERE %2$s', $wpdb->options, implode( ' OR ', $where ) );
|
||||
$wpdb->query( $query );
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
|
||||
'DELETE FROM %i WHERE ' . implode( ' OR', array_fill( 0, count( $where ), '%s' ) ),
|
||||
array_merge( [ $wpdb->options ], $where )
|
||||
)
|
||||
);
|
||||
|
||||
wp_cache_delete( 'alloptions', 'options' );
|
||||
}
|
||||
|
||||
@@ -47,22 +47,24 @@ class WPSEO_Sitemaps_Cache {
|
||||
|
||||
add_action( 'init', [ $this, 'init' ] );
|
||||
|
||||
add_action( 'deleted_term_relationships', [ __CLASS__, 'invalidate' ] );
|
||||
add_action( 'deleted_term_relationships', [ self::class, 'invalidate' ] );
|
||||
|
||||
add_action( 'update_option', [ __CLASS__, 'clear_on_option_update' ] );
|
||||
add_action( 'update_option', [ self::class, 'clear_on_option_update' ] );
|
||||
|
||||
add_action( 'edited_terms', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
|
||||
add_action( 'clean_term_cache', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
|
||||
add_action( 'clean_object_term_cache', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
|
||||
add_action( 'edited_terms', [ self::class, 'invalidate_helper' ], 10, 2 );
|
||||
add_action( 'clean_term_cache', [ self::class, 'invalidate_helper' ], 10, 2 );
|
||||
add_action( 'clean_object_term_cache', [ self::class, 'invalidate_helper' ], 10, 2 );
|
||||
|
||||
add_action( 'user_register', [ __CLASS__, 'invalidate_author' ] );
|
||||
add_action( 'delete_user', [ __CLASS__, 'invalidate_author' ] );
|
||||
add_action( 'user_register', [ self::class, 'invalidate_author' ] );
|
||||
add_action( 'delete_user', [ self::class, 'invalidate_author' ] );
|
||||
|
||||
add_action( 'shutdown', [ __CLASS__, 'clear_queued' ] );
|
||||
add_action( 'shutdown', [ self::class, 'clear_queued' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup context for static calls.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
@@ -294,6 +296,8 @@ class WPSEO_Sitemaps_Cache {
|
||||
|
||||
/**
|
||||
* Invalidate storage for cache types queued to clear.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clear_queued() {
|
||||
|
||||
@@ -320,6 +324,8 @@ class WPSEO_Sitemaps_Cache {
|
||||
*
|
||||
* @param string $option Option name.
|
||||
* @param string $type Sitemap type.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_clear_on_option_update( $option, $type = '' ) {
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class WPSEO_Sitemaps_Renderer {
|
||||
/**
|
||||
* Filters the `urlset` for a sitemap by type.
|
||||
*
|
||||
* @api string $urlset The output for the sitemap's `urlset`.
|
||||
* @param string $urlset The output for the sitemap's `urlset`.
|
||||
*/
|
||||
$xml = apply_filters( "wpseo_sitemap_{$type}_urlset", $urlset );
|
||||
|
||||
@@ -166,6 +166,8 @@ class WPSEO_Sitemaps_Renderer {
|
||||
* Set a custom stylesheet for this sitemap. Set to empty to just remove the default stylesheet.
|
||||
*
|
||||
* @param string $stylesheet Full XML-stylesheet declaration.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_stylesheet( $stylesheet ) {
|
||||
$this->stylesheet = $stylesheet;
|
||||
@@ -239,9 +241,8 @@ class WPSEO_Sitemaps_Renderer {
|
||||
/**
|
||||
* Filters the output for the sitemap URL tag.
|
||||
*
|
||||
* @api string $output The output for the sitemap url tag.
|
||||
*
|
||||
* @param array $url The sitemap URL array on which the output is based.
|
||||
* @param string $output The output for the sitemap url tag.
|
||||
* @param array $url The sitemap URL array on which the output is based.
|
||||
*/
|
||||
return apply_filters( 'wpseo_sitemap_url', $output, $url );
|
||||
}
|
||||
|
||||
@@ -21,24 +21,51 @@ class WPSEO_Sitemaps_Router {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'init', [ $this, 'init' ], 1 );
|
||||
add_action( 'yoast_add_dynamic_rewrite_rules', [ $this, 'add_rewrite_rules' ] );
|
||||
add_filter( 'query_vars', [ $this, 'add_query_vars' ] );
|
||||
|
||||
add_filter( 'redirect_canonical', [ $this, 'redirect_canonical' ] );
|
||||
add_action( 'template_redirect', [ $this, 'template_redirect' ], 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds rewrite routes for sitemaps.
|
||||
*
|
||||
* @param Yoast_Dynamic_Rewrites $dynamic_rewrites Dynamic rewrites handler instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_rewrite_rules( $dynamic_rewrites ) {
|
||||
$dynamic_rewrites->add_rule( 'sitemap_index\.xml$', 'index.php?sitemap=1', 'top' );
|
||||
$dynamic_rewrites->add_rule( '([^/]+?)-sitemap([0-9]+)?\.xml$', 'index.php?sitemap=$matches[1]&sitemap_n=$matches[2]', 'top' );
|
||||
$dynamic_rewrites->add_rule( '([a-z]+)?-?sitemap\.xsl$', 'index.php?yoast-sitemap-xsl=$matches[1]', 'top' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds query variables for sitemaps.
|
||||
*
|
||||
* @param array $query_vars List of query variables to filter.
|
||||
*
|
||||
* @return array Filtered query variables.
|
||||
*/
|
||||
public function add_query_vars( $query_vars ) {
|
||||
$query_vars[] = 'sitemap';
|
||||
$query_vars[] = 'sitemap_n';
|
||||
$query_vars[] = 'yoast-sitemap-xsl';
|
||||
|
||||
return $query_vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up rewrite rules.
|
||||
*
|
||||
* @deprecated 21.8
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
global $wp;
|
||||
|
||||
$wp->add_query_var( 'sitemap' );
|
||||
$wp->add_query_var( 'sitemap_n' );
|
||||
$wp->add_query_var( 'yoast-sitemap-xsl' );
|
||||
|
||||
add_rewrite_rule( 'sitemap_index\.xml$', 'index.php?sitemap=1', 'top' );
|
||||
add_rewrite_rule( '([^/]+?)-sitemap([0-9]+)?\.xml$', 'index.php?sitemap=$matches[1]&sitemap_n=$matches[2]', 'top' );
|
||||
add_rewrite_rule( '([a-z]+)?-?sitemap\.xsl$', 'index.php?yoast-sitemap-xsl=$matches[1]', 'top' );
|
||||
_deprecated_function( __METHOD__, 'Yoast SEO 21.8' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,14 +86,15 @@ class WPSEO_Sitemaps_Router {
|
||||
|
||||
/**
|
||||
* Redirects sitemap.xml to sitemap_index.xml.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function template_redirect() {
|
||||
if ( ! $this->needs_sitemap_index_redirect() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_safe_redirect( home_url( '/sitemap_index.xml' ), 301, 'Yoast SEO' );
|
||||
exit;
|
||||
YoastSEO()->helpers->redirect->do_safe_redirect( home_url( '/sitemap_index.xml' ), 301, 'Yoast SEO' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ class WPSEO_Sitemaps {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SITEMAP_INDEX_TYPE = '1';
|
||||
public const SITEMAP_INDEX_TYPE = '1';
|
||||
|
||||
/**
|
||||
* Content of the sitemap to output.
|
||||
@@ -115,6 +115,8 @@ class WPSEO_Sitemaps {
|
||||
* Initialize sitemap providers classes.
|
||||
*
|
||||
* @since 5.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init_sitemaps_providers() {
|
||||
|
||||
@@ -135,6 +137,8 @@ class WPSEO_Sitemaps {
|
||||
|
||||
/**
|
||||
* Check the current request URI, if we can determine it's probably an XML sitemap, kill loading the widgets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reduce_query_load() {
|
||||
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
@@ -153,11 +157,13 @@ class WPSEO_Sitemaps {
|
||||
* @param string $name The name of the sitemap.
|
||||
* @param callback $building_function Function to build your sitemap.
|
||||
* @param string $rewrite Optional. Regular expression to match your sitemap with.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_sitemap( $name, $building_function, $rewrite = '' ) {
|
||||
add_action( 'wpseo_do_sitemap_' . $name, $building_function );
|
||||
if ( ! empty( $rewrite ) ) {
|
||||
add_rewrite_rule( $rewrite, 'index.php?sitemap=' . $name, 'top' );
|
||||
if ( $rewrite ) {
|
||||
Yoast_Dynamic_Rewrites::instance()->add_rule( $rewrite, 'index.php?sitemap=' . $name, 'top' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,11 +175,13 @@ class WPSEO_Sitemaps {
|
||||
* @param string $name The name of the XSL file.
|
||||
* @param callback $building_function Function to build your XSL file.
|
||||
* @param string $rewrite Optional. Regular expression to match your sitemap with.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_xsl( $name, $building_function, $rewrite = '' ) {
|
||||
add_action( 'wpseo_xsl_' . $name, $building_function );
|
||||
if ( ! empty( $rewrite ) ) {
|
||||
add_rewrite_rule( $rewrite, 'index.php?yoast-sitemap-xsl=' . $name, 'top' );
|
||||
if ( $rewrite ) {
|
||||
Yoast_Dynamic_Rewrites::instance()->add_rule( $rewrite, 'index.php?yoast-sitemap-xsl=' . $name, 'top' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +190,8 @@ class WPSEO_Sitemaps {
|
||||
* in a one-off process.
|
||||
*
|
||||
* @param int $current_page The part that should be generated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_n( $current_page ) {
|
||||
if ( is_scalar( $current_page ) && intval( $current_page ) > 0 ) {
|
||||
@@ -193,6 +203,8 @@ class WPSEO_Sitemaps {
|
||||
* Set the sitemap content to display after you have generated it.
|
||||
*
|
||||
* @param string $sitemap The generated sitemap to output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_sitemap( $sitemap ) {
|
||||
$this->sitemap = $sitemap;
|
||||
@@ -202,6 +214,8 @@ class WPSEO_Sitemaps {
|
||||
* Set as true to make the request 404. Used stop the display of empty sitemaps or invalid requests.
|
||||
*
|
||||
* @param bool $is_bad Is this a bad request. True or false.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_bad_sitemap( $is_bad ) {
|
||||
$this->bad_sitemap = (bool) $is_bad;
|
||||
@@ -211,6 +225,8 @@ class WPSEO_Sitemaps {
|
||||
* Prevent stupid plugins from running shutdown scripts when we're obviously not outputting HTML.
|
||||
*
|
||||
* @since 1.4.16
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sitemap_close() {
|
||||
remove_all_actions( 'wp_footer' );
|
||||
@@ -220,7 +236,9 @@ class WPSEO_Sitemaps {
|
||||
/**
|
||||
* Hijack requests for potential sitemaps and XSL files.
|
||||
*
|
||||
* @param \WP_Query $query Main query instance.
|
||||
* @param WP_Query $query Main query instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function redirect( $query ) {
|
||||
|
||||
@@ -332,6 +350,8 @@ class WPSEO_Sitemaps {
|
||||
* Sets $bad_sitemap if this isn't for the root sitemap, a post type or taxonomy.
|
||||
*
|
||||
* @param string $type The requested sitemap's identifier.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function build_sitemap( $type ) {
|
||||
|
||||
@@ -382,6 +402,8 @@ class WPSEO_Sitemaps {
|
||||
|
||||
/**
|
||||
* Build the root sitemap (example.com/sitemap_index.xml) which lists sub-sitemaps for other content types.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function build_root_map() {
|
||||
|
||||
@@ -415,6 +437,8 @@ class WPSEO_Sitemaps {
|
||||
* @since 1.4.13
|
||||
*
|
||||
* @param string $type Type to output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function xsl_output( $type ) {
|
||||
|
||||
@@ -445,6 +469,8 @@ class WPSEO_Sitemaps {
|
||||
|
||||
/**
|
||||
* Spit out the generated sitemap.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output() {
|
||||
$this->send_headers();
|
||||
@@ -499,18 +525,41 @@ class WPSEO_Sitemaps {
|
||||
|
||||
if ( ! empty( $post_type_names ) ) {
|
||||
$post_statuses = array_map( 'esc_sql', self::get_post_statuses() );
|
||||
$replacements = array_merge(
|
||||
[
|
||||
'post_type',
|
||||
'post_modified_gmt',
|
||||
'date',
|
||||
$wpdb->posts,
|
||||
'post_status',
|
||||
],
|
||||
$post_statuses,
|
||||
[ 'post_type' ],
|
||||
array_keys( $post_type_names ),
|
||||
[
|
||||
'post_type',
|
||||
'date',
|
||||
]
|
||||
);
|
||||
|
||||
$sql = "
|
||||
SELECT post_type, MAX(post_modified_gmt) AS date
|
||||
FROM $wpdb->posts
|
||||
WHERE post_status IN ('" . implode( "','", $post_statuses ) . "')
|
||||
AND post_type IN ('" . implode( "','", $post_type_names ) . "')
|
||||
GROUP BY post_type
|
||||
ORDER BY date DESC
|
||||
";
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
||||
$dates = $wpdb->get_results(
|
||||
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
|
||||
$wpdb->prepare(
|
||||
'
|
||||
SELECT %i, MAX(%i) AS %i
|
||||
FROM %i
|
||||
WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ')
|
||||
AND %i IN (' . implode( ', ', array_fill( 0, count( $post_type_names ), '%s' ) ) . ')
|
||||
GROUP BY %i
|
||||
ORDER BY %i DESC
|
||||
',
|
||||
$replacements
|
||||
)
|
||||
);
|
||||
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- They are prepared on the lines above and a direct query is required.
|
||||
foreach ( $wpdb->get_results( $sql ) as $obj ) {
|
||||
foreach ( $dates as $obj ) {
|
||||
$post_type_dates[ $obj->post_type ] = $obj->date;
|
||||
}
|
||||
}
|
||||
@@ -592,6 +641,8 @@ class WPSEO_Sitemaps {
|
||||
|
||||
/**
|
||||
* Sends all the required HTTP Headers.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function send_headers() {
|
||||
if ( headers_sent() ) {
|
||||
|
||||
@@ -94,10 +94,11 @@ class WPSEO_Taxonomy_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
$hide_empty_tax = apply_filters( 'wpseo_sitemap_exclude_empty_terms_taxonomy', $hide_empty, $taxonomy_name );
|
||||
|
||||
$term_args = [
|
||||
'taxonomy' => $taxonomy_name,
|
||||
'hide_empty' => $hide_empty_tax,
|
||||
'fields' => 'ids',
|
||||
];
|
||||
$taxonomy_terms = get_terms( $taxonomy_name, $term_args );
|
||||
$taxonomy_terms = get_terms( $term_args );
|
||||
|
||||
if ( count( $taxonomy_terms ) > 0 ) {
|
||||
$all_taxonomies[ $taxonomy_name ] = $taxonomy_terms;
|
||||
@@ -211,24 +212,28 @@ class WPSEO_Taxonomy_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
|
||||
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses() );
|
||||
|
||||
// Grab last modified date.
|
||||
$sql = "
|
||||
SELECT MAX(p.post_modified_gmt) AS lastmod
|
||||
FROM $wpdb->posts AS p
|
||||
INNER JOIN $wpdb->term_relationships AS term_rel
|
||||
ON term_rel.object_id = p.ID
|
||||
INNER JOIN $wpdb->term_taxonomy AS term_tax
|
||||
ON term_tax.term_taxonomy_id = term_rel.term_taxonomy_id
|
||||
AND term_tax.taxonomy = %s
|
||||
AND term_tax.term_id = %d
|
||||
WHERE p.post_status IN ('" . implode( "','", $post_statuses ) . "')
|
||||
AND p.post_password = ''
|
||||
";
|
||||
$replacements = array_merge(
|
||||
[
|
||||
'post_modified_gmt',
|
||||
$wpdb->posts,
|
||||
$wpdb->term_relationships,
|
||||
'object_id',
|
||||
'ID',
|
||||
$wpdb->term_taxonomy,
|
||||
'term_taxonomy_id',
|
||||
'term_taxonomy_id',
|
||||
'taxonomy',
|
||||
'term_id',
|
||||
'post_status',
|
||||
],
|
||||
$post_statuses,
|
||||
[ 'post_password' ]
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter: 'wpseo_exclude_from_sitemap_by_term_ids' - Allow excluding terms by ID.
|
||||
*
|
||||
* @api array $terms_to_exclude The terms to exclude.
|
||||
* @param array $terms_to_exclude The terms to exclude.
|
||||
*/
|
||||
$terms_to_exclude = apply_filters( 'wpseo_exclude_from_sitemap_by_term_ids', [] );
|
||||
|
||||
@@ -253,7 +258,30 @@ class WPSEO_Taxonomy_Sitemap_Provider implements WPSEO_Sitemap_Provider {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url['mod'] = $wpdb->get_var( $wpdb->prepare( $sql, $term->taxonomy, $term->term_id ) );
|
||||
$current_replacements = $replacements;
|
||||
array_splice( $current_replacements, 9, 0, $term->taxonomy );
|
||||
array_splice( $current_replacements, 11, 0, $term->term_id );
|
||||
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
|
||||
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
|
||||
$url['mod'] = $wpdb->get_var(
|
||||
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
|
||||
$wpdb->prepare(
|
||||
'
|
||||
SELECT MAX(p.%i) AS lastmod
|
||||
FROM %i AS p
|
||||
INNER JOIN %i AS term_rel
|
||||
ON term_rel.%i = p.%i
|
||||
INNER JOIN %i AS term_tax
|
||||
ON term_tax.%i = term_rel.%i
|
||||
AND term_tax.%i = %s
|
||||
AND term_tax.%i = %d
|
||||
WHERE p.%i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ")
|
||||
AND p.%i = ''
|
||||
",
|
||||
$current_replacements
|
||||
)
|
||||
);
|
||||
|
||||
if ( $this->include_images ) {
|
||||
$url['images'] = $this->get_image_parser()->get_term_images( $term );
|
||||
|
||||
@@ -15,21 +15,21 @@ interface WPSEO_Sitemap_Cache_Data_Interface {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const OK = 'ok';
|
||||
public const OK = 'ok';
|
||||
|
||||
/**
|
||||
* Status for unusable sitemap.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const ERROR = 'error';
|
||||
public const ERROR = 'error';
|
||||
|
||||
/**
|
||||
* Status for unusable sitemap because it cannot be identified.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const UNKNOWN = 'unknown';
|
||||
public const UNKNOWN = 'unknown';
|
||||
|
||||
/**
|
||||
* Set the content of the sitemap.
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
*
|
||||
* @package WPSEO\Deprecated
|
||||
*/
|
||||
|
||||
|
||||
@@ -210,6 +210,8 @@ if ( ! function_exists( 'ctype_digit' ) ) {
|
||||
* @param string $new_term_id New term id of the taxonomy term that was splitted.
|
||||
* @param string $term_taxonomy_id Term taxonomy id for the taxonomy that was affected.
|
||||
* @param string $taxonomy The taxonomy that the taxonomy term was splitted for.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function wpseo_split_shared_term( $old_term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
|
||||
$tax_meta = get_option( 'wpseo_taxonomy_meta', [] );
|
||||
|
||||
Reference in New Issue
Block a user