auto-patch 638-dev-dev01-2024-05-14T20_44_36

This commit is contained in:
root
2024-05-14 20:44:36 +00:00
parent a941559057
commit 5dbb0b284e
1812 changed files with 29671 additions and 14588 deletions

View File

@@ -90,6 +90,7 @@ class WPSEO_Upgrade {
'20.5-RC0' => 'upgrade_205',
'20.7-RC0' => 'upgrade_207',
'20.8-RC0' => 'upgrade_208',
'22.6-RC0' => 'upgrade_226',
];
array_walk( $routines, [ $this, 'run_upgrade_routine' ], $version );
@@ -252,6 +253,8 @@ class WPSEO_Upgrade {
* @return void
*/
public function upgrade_23_query() {
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: executed only during the upgrade routine.
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Reason: executed only during the upgrade routine.
$wp_query = new WP_Query( 'post_type=any&meta_key=_yoast_wpseo_sitemap-include&meta_value=never&order=ASC' );
if ( ! empty( $wp_query->posts ) ) {
@@ -304,11 +307,18 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function upgrade_36() {
protected function upgrade_36() {
global $wpdb;
// Between 3.2 and 3.4 the sitemap options were saved with autoloading enabled.
$wpdb->query( 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE "wpseo_sitemap_%" AND autoload = "yes"' );
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
'DELETE FROM %i WHERE %i LIKE %s AND autoload IN ("on", "yes")',
[ $wpdb->options, 'option_name', 'wpseo_sitemap_%' ]
)
);
}
/**
@@ -345,6 +355,8 @@ class WPSEO_Upgrade {
global $wpdb;
// The meta key has to be private, so prefix it.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
'UPDATE ' . $wpdb->postmeta . ' SET meta_key = %s WHERE meta_key = "yst_is_cornerstone"',
@@ -358,7 +370,7 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function upgrade_49() {
protected function upgrade_49() {
global $wpdb;
/*
@@ -371,15 +383,16 @@ class WPSEO_Upgrade {
$meta_key = $wpdb->get_blog_prefix() . Yoast_Notification_Center::STORAGE_KEY;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$usermetas = $wpdb->get_results(
$wpdb->prepare(
'
SELECT user_id, meta_value
FROM ' . $wpdb->usermeta . '
WHERE meta_key = %s AND meta_value LIKE %s
SELECT %i, %i
FROM %i
WHERE %i = %s AND %i LIKE %s
',
$meta_key,
'%wpseo-dismiss-about%'
[ 'user_id', 'meta_value', $wpdb->usermeta, 'meta_key', $meta_key, 'meta_value', '%wpseo-dismiss-about%' ]
),
ARRAY_A
);
@@ -423,11 +436,19 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function upgrade_50() {
protected function upgrade_50() {
global $wpdb;
// Deletes the post meta value, which might created in the RC.
$wpdb->query( 'DELETE FROM ' . $wpdb->postmeta . ' WHERE meta_key = "_yst_content_links_processed"' );
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM %i
WHERE %i = '_yst_content_links_processed'",
[ $wpdb->postmeta, 'meta_key' ]
)
);
}
/**
@@ -520,6 +541,8 @@ class WPSEO_Upgrade {
// Moves the user meta for excluding from the XML sitemap to a noindex.
global $wpdb;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query( "UPDATE $wpdb->usermeta SET meta_key = 'wpseo_noindex_author' WHERE meta_key = 'wpseo_excludeauthorsitemap'" );
}
@@ -549,6 +572,8 @@ class WPSEO_Upgrade {
private function upgrade_73() {
global $wpdb;
// We've moved the cornerstone checkbox to our proper namespace.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_yoast_wpseo_is_cornerstone' WHERE meta_key = '_yst_is_cornerstone'" );
// Remove the previous Whip dismissed message, as this is a new one regarding PHP 5.2.
@@ -560,7 +585,7 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function upgrade_74() {
protected function upgrade_74() {
$this->remove_sitemap_validators();
}
@@ -612,7 +637,7 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function upgrade_90() {
protected function upgrade_90() {
global $wpdb;
// Invalidate all sitemap cache transients.
@@ -621,7 +646,15 @@ class WPSEO_Upgrade {
// Removes all scheduled tasks for hitting the sitemap index.
wp_clear_scheduled_hook( 'wpseo_hit_sitemap_index' );
$wpdb->query( 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE "wpseo_sitemap_%"' );
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
'DELETE FROM %i
WHERE %i LIKE %s',
[ $wpdb->options, 'option_name', 'wpseo_sitemap_%' ]
)
);
}
/**
@@ -698,7 +731,15 @@ class WPSEO_Upgrade {
}
global $wpdb;
$wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'wp_yoast_promo_hide_premium_upsell_admin_block'" );
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
'DELETE FROM %i
WHERE %i = %s',
[ $wpdb->usermeta, 'meta_key', 'wp_yoast_promo_hide_premium_upsell_admin_block' ]
)
);
// Removes the WordPress update notification, because it is no longer necessary when WordPress 5.3 is released.
$center = Yoast_Notification_Center::get();
@@ -1096,6 +1137,19 @@ class WPSEO_Upgrade {
}
}
/**
* Performs the 22.6 upgrade routine.
* Schedules another cleanup scheduled action, but starting from the last cleanup action we just added (if there aren't any running cleanups already).
*
* @return void
*/
private function upgrade_226() {
if ( get_option( Cleanup_Integration::CURRENT_TASK_OPTION ) === false ) {
$cleanup_integration = YoastSEO()->classes->get( Cleanup_Integration::class );
$cleanup_integration->start_cron_job( 'clean_selected_empty_usermeta', DAY_IN_SECONDS );
}
}
/**
* Sets the home_url option for the 15.1 upgrade routine.
*
@@ -1150,19 +1204,20 @@ class WPSEO_Upgrade {
return;
}
$indexable_table = Model::get_table_name( 'Indexable' );
$replacements = array_merge( [ Model::get_table_name( 'Indexable' ), 'object_type', 'object_sub_type' ], $private_taxonomies );
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
$query = $wpdb->prepare(
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
"DELETE FROM $indexable_table
WHERE object_type = 'term'
AND object_sub_type IN ("
. implode( ', ', array_fill( 0, count( $private_taxonomies ), '%s' ) )
. ')',
$private_taxonomies
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM %i
WHERE %i = 'term'
AND %i IN ("
. implode( ', ', array_fill( 0, count( $private_taxonomies ), '%s' ) )
. ')',
$replacements
)
);
$wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
$wpdb->show_errors = $show_errors;
}
@@ -1180,9 +1235,14 @@ class WPSEO_Upgrade {
$wpdb->show_errors = false;
// Reset the permalinks of the attachments in the indexable table.
$indexable_table = Model::get_table_name( 'Indexable' );
$query = "UPDATE $indexable_table SET permalink = NULL WHERE object_type = 'post' AND object_sub_type = 'attachment'";
$wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: There is no user input.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
"UPDATE %i SET %i = NULL WHERE %i = 'post' AND %i = 'attachment'",
[ Model::get_table_name( 'Indexable' ), 'permalink', 'object_type', 'object_sub_type' ]
)
);
$wpdb->show_errors = $show_errors;
}
@@ -1254,7 +1314,14 @@ class WPSEO_Upgrade {
global $wpdb;
// Remove all sitemap validators.
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'wpseo_sitemap%validator%'" );
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
'DELETE FROM %i WHERE %i LIKE %s',
[ $wpdb->options, 'option_name', 'wpseo_sitemap%validator%' ]
)
);
}
/**
@@ -1262,14 +1329,22 @@ class WPSEO_Upgrade {
*
* @param string $option_name Option to retrieve.
*
* @return array|mixed The content of the option if exists, otherwise an empty array.
* @return int|string|bool|float|array<string|int|bool|float> The content of the option if exists, otherwise an empty array.
*/
protected function get_option_from_database( $option_name ) {
global $wpdb;
// Load option directly from the database, to avoid filtering and sanitization.
$sql = $wpdb->prepare( 'SELECT option_value FROM ' . $wpdb->options . ' WHERE option_name = %s', $option_name );
$results = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is is already prepared.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$results = $wpdb->get_results(
$wpdb->prepare(
'SELECT %i FROM %i WHERE %i = %s',
[ 'option_value', $wpdb->options, 'option_name', $option_name ]
),
ARRAY_A
);
if ( ! empty( $results ) ) {
return maybe_unserialize( $results[0]['option_value'] );
}
@@ -1302,9 +1377,9 @@ class WPSEO_Upgrade {
/**
* Saves an option setting to where it should be stored.
*
* @param array $source_data The option containing the value to be migrated.
* @param string $source_setting Name of the key in the "from" option.
* @param string|null $target_setting Name of the key in the "to" option.
* @param int|string|bool|float|array<string|int|bool|float> $source_data The option containing the value to be migrated.
* @param string $source_setting Name of the key in the "from" option.
* @param string|null $target_setting Name of the key in the "to" option.
*
* @return void
*/
@@ -1513,29 +1588,31 @@ class WPSEO_Upgrade {
$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 ) ) {
$delete_query = "
DELETE FROM $indexable_table
WHERE object_type = 'post'
AND object_sub_type IS NOT NULL";
}
else {
$delete_query = $wpdb->prepare(
"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' ) ) . ' )',
$included_post_types
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM %i
WHERE %i = 'post'
AND %i IS NOT NULL",
[ $indexable_table, 'object_type', 'object_sub_type' ]
)
);
}
else {
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM %i
WHERE %i = 'post'
AND %i IS NOT NULL
AND %i NOT IN ( " . implode( ', ', array_fill( 0, count( $included_post_types ), '%s' ) ) . ' )',
array_merge( [ $indexable_table, 'object_type', 'object_sub_type', 'object_sub_type' ], $included_post_types )
)
);
}
// phpcs:enable
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
$wpdb->query( $delete_query );
// phpcs:enable
$wpdb->show_errors = $show_errors;
}
@@ -1557,28 +1634,31 @@ class WPSEO_Upgrade {
$included_taxonomies = YoastSEO()->helpers->taxonomy->get_indexable_taxonomies();
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
if ( empty( $included_taxonomies ) ) {
$delete_query = "DELETE FROM $indexable_table
WHERE object_type = 'term'
AND object_sub_type IS NOT NULL";
}
else {
$delete_query = $wpdb->prepare(
"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' ) ) . ' )',
$included_taxonomies
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM %i
WHERE %i = 'term'
AND %i IS NOT NULL",
[ $indexable_table, 'object_type', 'object_sub_type' ]
)
);
}
else {
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM %i
WHERE %i = 'term'
AND %i IS NOT NULL
AND %i NOT IN ( " . implode( ', ', array_fill( 0, count( $included_taxonomies ), '%s' ) ) . ' )',
array_merge( [ $indexable_table, 'object_type', 'object_sub_type', 'object_sub_type' ], $included_taxonomies )
)
);
}
// phpcs:enable
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
$wpdb->query( $delete_query );
// phpcs:enable
$wpdb->show_errors = $show_errors;
}
@@ -1588,22 +1668,24 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function deduplicate_unindexed_indexable_rows() {
protected function deduplicate_unindexed_indexable_rows() {
global $wpdb;
// If migrations haven't been completed successfully the following may give false errors. So suppress them.
$show_errors = $wpdb->show_errors;
$wpdb->show_errors = false;
$indexable_table = Model::get_table_name( 'Indexable' );
$query = "
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$duplicates = $wpdb->get_results(
$wpdb->prepare(
"
SELECT
MAX(id) as newest_id,
object_id,
object_type
FROM
$indexable_table
%i
WHERE
post_status = 'unindexed'
AND object_type IN ( 'term', 'post', 'user' )
@@ -1611,13 +1693,11 @@ class WPSEO_Upgrade {
object_id,
object_type
HAVING
count(*) > 1";
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
$duplicates = $wpdb->get_results( $query, ARRAY_A );
// phpcs:enable
count(*) > 1",
[ Model::get_table_name( 'Indexable' ) ]
),
ARRAY_A
);
if ( empty( $duplicates ) ) {
$wpdb->show_errors = $show_errors;
@@ -1650,25 +1730,24 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function clean_unindexed_indexable_rows_with_no_object_id() {
protected function clean_unindexed_indexable_rows_with_no_object_id() {
global $wpdb;
// If migrations haven't been completed successfully the following may give false errors. So suppress them.
$show_errors = $wpdb->show_errors;
$wpdb->show_errors = false;
$indexable_table = Model::get_table_name( 'Indexable' );
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: No user input, just a table name.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
$wpdb->query(
"DELETE FROM $indexable_table
WHERE post_status = 'unindexed'
AND object_type NOT IN ( 'home-page', 'date-archive', 'post-type-archive', 'system-page' )
AND object_id IS NULL"
$wpdb->prepare(
"DELETE FROM %i
WHERE %i = 'unindexed'
AND %i NOT IN ( 'home-page', 'date-archive', 'post-type-archive', 'system-page' )
AND %i IS NULL",
[ Model::get_table_name( 'Indexable' ), 'post_status', 'object_type', 'object_id' ]
)
);
// phpcs:enable
$wpdb->show_errors = $show_errors;
}
@@ -1678,7 +1757,7 @@ class WPSEO_Upgrade {
*
* @return void
*/
private function remove_indexable_rows_for_disabled_authors_archive() {
protected function remove_indexable_rows_for_disabled_authors_archive() {
global $wpdb;
if ( ! YoastSEO()->helpers->author_archive->are_disabled() ) {
@@ -1689,16 +1768,14 @@ class WPSEO_Upgrade {
$show_errors = $wpdb->show_errors;
$wpdb->show_errors = false;
$indexable_table = Model::get_table_name( 'Indexable' );
$delete_query = "DELETE FROM $indexable_table WHERE object_type = 'user'";
// phpcs:enable
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
$wpdb->query( $delete_query );
// phpcs:enable
$wpdb->query(
$wpdb->prepare(
"DELETE FROM %i WHERE %i = 'user'",
[ Model::get_table_name( 'Indexable' ), 'object_type' ]
)
);
$wpdb->show_errors = $show_errors;
}
@@ -1706,15 +1783,13 @@ class WPSEO_Upgrade {
/**
* Creates a query for de-duplicating indexables for a particular type.
*
* @param string $object_type The object type to deduplicate.
* @param array $duplicates The result of the duplicate query.
* @param wpdb $wpdb The wpdb object.
* @param string $object_type The object type to deduplicate.
* @param string|array<array<int,int,string>> $duplicates The result of the duplicate query.
* @param wpdb $wpdb The wpdb object.
*
* @return string The query that removes all but one duplicate for each object of the object type.
*/
private function get_indexable_deduplication_query_for_type( $object_type, $duplicates, $wpdb ) {
$indexable_table = Model::get_table_name( 'Indexable' );
protected function get_indexable_deduplication_query_for_type( $object_type, $duplicates, $wpdb ) {
$filtered_duplicates = array_filter(
$duplicates,
static function ( $duplicate ) use ( $object_type ) {
@@ -1729,18 +1804,20 @@ class WPSEO_Upgrade {
$object_ids = wp_list_pluck( $filtered_duplicates, 'object_id' );
$newest_indexable_ids = wp_list_pluck( $filtered_duplicates, 'newest_id' );
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber -- Reason: we're passing an array instead.
$replacements = array_merge( [ Model::get_table_name( 'Indexable' ), 'object_id' ], array_values( $object_ids ), array_values( $newest_indexable_ids ) );
$replacements[] = $object_type;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
return $wpdb->prepare(
"DELETE FROM
$indexable_table
'DELETE FROM
%i
WHERE
object_id IN ( " . implode( ', ', array_fill( 0, count( $filtered_duplicates ), '%d' ) ) . ' )
%i 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 ] )
$replacements
);
// phpcs:enable
}
/**