ction count_indexables_for_authors_archive_disabled() {
if ( ! $this->author_archive->are_disabled() ) {
return 0;
}
return $this
->query()
->where( 'object_type', 'user' )
->count();
}
/**
* Cleans up any indexables that belong to users that have their author archives disabled.
*
* @param int $limit The limit we'll apply to the queries.
*
* @return bool|int The number of deleted rows, false if the query fails.
*/
public function clean_indexables_for_authors_without_archive( $limit ) {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
$author_archive_post_types = $this->author_archive->get_author_archive_post_types();
$viewable_post_stati = \array_filter( \get_post_stati(), 'is_post_status_viewable' );
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber -- Reason: we're passing an array instead.
$delete_query = $wpdb->prepare(
"DELETE FROM $indexable_table
WHERE object_type = 'user'
AND object_id NOT IN (
SELECT DISTINCT post_author
FROM $wpdb->posts
WHERE post_type IN ( " . \implode( ', ', \array_fill( 0, \count( $author_archive_post_types ), '%s' ) ) . ' )
AND post_status IN ( ' . \implode( ', ', \array_fill( 0, \count( $viewable_post_stati ), '%s' ) ) . ' )
) LIMIT %d',
\array_merge( $author_archive_post_types, $viewable_post_stati, [ $limit ] )
);
// 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.
return $wpdb->query( $delete_query );
// phpcs:enable
}
/**
* Counts total amount of indexables for authors without archives.
*
* @return bool|int|mysqli_result|resource|null
*/
public function count_indexables_for_authors_without_archive() {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
$author_archive_post_types = $this->author_archive->get_author_archive_post_types();
$viewable_post_stati = \array_filter( \get_post_stati(), 'is_post_status_viewable' );
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber -- Reason: we're passing an array instead.
$count_query = $wpdb->prepare(
"SELECT count(*) FROM $indexable_table
WHERE object_type = 'user'
AND object_id NOT IN (
SELECT DISTINCT post_author
FROM $wpdb->posts
WHERE post_type IN ( " . \implode( ', ', \array_fill( 0, \count( $author_archive_post_types ), '%s' ) ) . ' )
AND post_status IN ( ' . \implode( ', ', \array_fill( 0, \count( $viewable_post_stati ), '%s' ) ) . ' )
)',
\array_merge( $author_archive_post_types, $viewable_post_stati )
);
// 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.
return $wpdb->get_col( $count_query )[0];
// phpcs:enable
}
/**
* Deletes rows from the indexable table where the source is no longer there.
*
* @param string $source_table The source table which we need to check the indexables against.
* @param string $source_identifier The identifier which the indexables are matched to.
* @param string $object_type The indexable object type.
* @param int $limit The limit we'll apply to the delete query.
*
* @return int|bool The number of rows that was deleted or false if the query failed.
*/
public function clean_indexables_for_object_type_and_source_table( $source_table, $source_identifier, $object_type, $limit ) {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
$source_table = $wpdb->prefix . $source_table;
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: There is no unescaped user input.
$query = $wpdb->prepare(
"
SELECT indexable_table.object_id
FROM {$indexable_table} indexable_table
LEFT JOIN {$source_table} AS source_table
ON indexable_table.object_id = source_table.{$source_identifier}
WHERE source_table.{$source_identifier} IS NULL
AND indexable_table.object_id IS NOT NULL
AND indexable_table.object_type = '{$object_type}'
LIMIT %d",
$limit
);
// phpcs:enable
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
$orphans = $wpdb->get_col( $query );
if ( empty( $orphans ) ) {
return 0;
}
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
return $wpdb->query( "DELETE FROM $indexable_table WHERE object_type = '{$object_type}' AND object_id IN( " . \implode( ',', $orphans ) . ' )' );
}
/**
* Deletes rows from the indexable table where the source is no longer there.
*
* @param int $limit The limit we'll apply to the delete query.
*
* @return int|bool The number of rows that was deleted or false if the query failed.
*/
public function clean_indexables_for_orphaned_users( $limit ) {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
$source_table = $wpdb->users;
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: There is no unescaped user input.
$query = $wpdb->prepare(
"
SELECT indexable_table.object_id
FROM {$indexable_table} indexable_table
LEFT JOIN {$source_table} AS source_table
ON indexable_table.object_id = source_table.ID
WHERE source_table.ID IS NULL
AND indexable_table.object_id IS NOT NULL
AND indexable_table.object_type = 'user'
LIMIT %d",
$limit
);
// phpcs:enable
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
$orphans = $wpdb->get_col( $query );
if ( empty( $orphans ) ) {
return 0;
}
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
return $wpdb->query( "DELETE FROM $indexable_table WHERE object_type = 'user' AND object_id IN( " . \implode( ',', $orphans ) . ' )' );
}
/**
* Counts indexables for given source table + source identifier + object type.
*
* @param string $source_table The source table.
* @param string $source_identifier The source identifier.
* @param string $object_type The object type.
*
* @return mixed
*/
public function count_indexables_for_object_type_and_source_table( string $source_table, string $source_identifier, string $object_type ) {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
$source_table = $wpdb->prefix . $source_table;
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
return $wpdb->get_col(
"
SELECT count(*)
FROM {$indexable_table} indexable_table
LEFT JOIN {$source_table} AS source_table
ON indexable_table.object_id = source_table.{$source_identifier}
WHERE source_table.{$source_identifier} IS NULL
AND indexable_table.object_id IS NOT NULL
AND indexable_table.object_type = '{$object_type}'"
)[0];
// phpcs:enable
}
/**
* Counts indexables for orphaned users.
*
* @return mixed
*/
public function count_indexables_for_orphaned_users() {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
$source_table = $wpdb->users;
//phpcs:disable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
return $wpdb->get_col(
"
SELECT count(*)
FROM {$indexable_table} indexable_table
LEFT JOIN {$source_table} AS source_table
ON indexable_table.object_id = source_table.ID
WHERE source_table.ID IS NULL
AND indexable_table.object_id IS NOT NULL
AND indexable_table.object_type = 'user'"
)[0];
// phpcs:enable
}
/**
* Cleans orphaned rows from a yoast table.
*
* @param string $table The table to clean up.
* @param string $column The table column the cleanup will rely on.
* @param int $limit The limit we'll apply to the queries.
*
* @return int|bool The number of deleted rows, false if the query fails.
*/
public function cleanup_orphaned_from_table( $table, $column, $limit ) {
global $wpdb;
$table = Model::get_table_name( $table );
$indexable_table = Model::get_table_name( 'Indexable' );
// Warning: If this query is changed, make sure to update the query in cleanup_orphaned_from_table in Premium as well.
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: There is no unescaped user input.
$query = $wpdb->prepare(
"
SELECT table_to_clean.{$column}
FROM {$table} table_to_clean
LEFT JOIN {$indexable_table} AS indexable_table
ON table_to_clean.{$column} = indexable_table.id
WHERE indexable_table.id IS NULL
AND table_to_clean.{$column} IS NOT NULL
LIMIT %d",
$limit
);
// phpcs:enable
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
$orphans = $wpdb->get_col( $query );
if ( empty( $orphans ) ) {
return 0;
}
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
return $wpdb->query( "DELETE FROM $table WHERE {$column} IN( " . \implode( ',', $orphans ) . ' )' );
}
/**
* Counts orphaned rows from a yoast table.
*
* @param string $table The table to clean up.
* @param string $column The table column the cleanup will rely on.
*
* @return int|bool The number of deleted rows, false if the query fails.
*/
public function count_orphaned_from_table( string $table, string $column ) {
global $wpdb;
$table = Model::get_table_name( $table );
$indexable_table = Model::get_table_name( 'Indexable' );
// Warning: If this query is changed, make sure to update the query in cleanup_orphaned_from_table in Premium as well.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
return $wpdb->get_col(
"
SELECT count(*)
FROM {$table} table_to_clean
LEFT JOIN {$indexable_table} AS indexable_table
ON table_to_clean.{$column} = indexable_table.id
WHERE indexable_table.id IS NULL
AND table_to_clean.{$column} IS NOT NULL"
)[0];
// phpcs:enable
}
/**
* Updates the author_id of indexables which author_id is not in the wp_users table with the id of the reassingned
* user.
*
* @param int $limit The limit we'll apply to the queries.
*
* @return int|bool The number of updated rows, false if query to get data fails.
*/
public function update_indexables_author_to_reassigned( $limit ) {
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
$reassigned_authors_objs = $this->get_reassigned_authors( $limit );
if ( $reassigned_authors_objs === false ) {
return false;
}
return $this->update_indexable_authors( $reassigned_authors_objs, $limit );
}
/**
* Fetches pairs of old_id -> new_id indexed by old_id.
* By using the old_id (i.e. the id of the user that has been deleted) as key of the associative array, we can
* easily compose an array of unique pairs of old_id -> new_id.
*
* @param int $limit The limit we'll apply to the queries.
*
* @return int|bool The associative array with shape [ old_id => [ old_id, new_author ] ] or false if query to get
* data fails.
*/
private function get_reassigned_authors( $limit ) {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
$posts_table = $wpdb->posts;
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: There is no unescaped user input.
$query = $wpdb->prepare(
"
SELECT {$indexable_table}.author_id, {$posts_table}.post_author
FROM {$indexable_table} JOIN {$posts_table} on {$indexable_table}.object_id = {$posts_table}.id
WHERE object_type='post'
AND {$indexable_table}.author_id <> {$posts_table}.post_author
ORDER BY {$indexable_table}.author_id
LIMIT %d",
$limit
);
// phpcs:enable
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
return $wpdb->get_results( $query, \OBJECT_K );
}
/**
* Updates the indexable's author_id referring to a deleted author with the id of the reassigned user.
*
* @param array $reassigned_authors_objs The array of objects with shape [ old_id => [ old_id, new_id ] ].
* @param int $limit The limit we'll apply to the queries.
*
* @return int|bool The associative array with shape [ old_id => [ old_id, new_author ] ] or false if query to get
* data fails.
*/
private function update_indexable_authors( $reassigned_authors_objs, $limit ) {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );
// This is a workaround for the fact that the array_column function does not work on objects in PHP 5.6.
$reassigned_authors_array = \array_map(
static function ( $obj ) {
return (array) $obj;
},
$reassigned_authors_objs
);
$reassigned_authors = \array_combine( \array_column( $reassigned_authors_array, 'author_id' ), \array_column( $reassigned_authors_array, 'post_author' ) );
foreach ( $reassigned_authors as $old_author_id => $new_author_id ) {
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: There is no unescaped user input.
$query = $wpdb->prepare(
"
UPDATE {$indexable_table}
SET {$indexable_table}.author_id = {$new_author_id}
WHERE {$indexable_table}.author_id = {$old_author_id}
AND object_type='post'
LIMIT %d",
$limit
);
// phpcs:enable
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: Already prepared.
$wpdb->query( $query );
}
return \count( $reassigned_authors );
}
}
رد السفير السعودي في بغداد، ثامر السبهان، على تصريح زعيم ائتلاف دولة القانون نوري المالكي الذي قال قبل أيام، إن السعودية “مصدر للإرهاب في المنطقة والعالم”، ويجب وضعها تحت وصاية …
كان الملعب الأولمبي في ريو دي جانيرو مسرحا لقمة نارية بين الاسطورة الجامايكي بولت والنجم السابق الاميركي جاستن غاتلين العائد من جحيم المنشطات، وذلك في سباق لاستعراض العضلات يتجاوز المنافسة …
حظرت السلطات في مدينة كان الفرنسية ارتداء “البوركيني” على شواطئ المدينة الشهيرة التي تحتضن سنويا أكبر مهرجان سينمائي في العالم، فيما تضامن مع كان عمدة بلدة فيلينيوف لوبيت الفرنسية، وحظر ارتداء …
بعد إحرازه 22 #ميدالية بينها 18 ذهبية، في أربع مشاركات ضمن #الألعابالأولمبية بين 2000 و2012، أعاد #فيلبس كتابة نهاية ملحمته الأولمبية بخمس ذهبيات وفضية أحرزها في غضون أسبوع في المسبح …
استمع إلى ما قاله السيد حسن نصر الله إلى الجماعات المسلحة في سوريا و العراق شدد الأمين العام لحزب الله السيد حسن نصرالله على أن الجماعات المسلحة في سوريا والعراق …
نصر الله: ترمب على حق نصر الله: ترامب على حق في أن إدارة أوباما صنعت “داعش” أعرب الأمين العام لـ”حزب الله” اللبناني، حسن نصر الله، عن دعمه لتصريحات السياسي الأمريكي …
مقتل إمام ومساعده بالرصاص في مدينة نيويورك قال زعماء الجالية المسلمة في نيويورك إن قتل إمام مسجد ومساعده يأتي على خلفية الحملة الانتخابية للمرشح الجمهوري، دونالد ترامب، “الذي يوصف خطابه …
أثارت فتوى «زواج الركاض»، التي عادت إلى الواجهة، جدلاً واسعاً في مواقع التواصل الاجتماعي، إذ انضم «زواج الركاض» إلى قائمة المسميات الجديدة لـ«الزيجات الشرعية»، التي تعاود الظهور بين فترة وأخرى، …
نشر الكاتب جمال خاشقجي مقالا مخصصا للرد على “ادعاءات دم السعودية للإرهاب مقالا تحت عنوان: شبهات في واشنطن، مخصص بأكلمه لرد التهمة بطريقة “كلاسيكية” إعلاميا، باتهام الآخر بالتهمة نفسها الموجهة …
تسببت نزهة قام بها حاكم دبي الشيخ محمد بن راشد آل مكتوم في محمية طبيعية بألمانيا في شهر تموز/يوليو في كثير من النقاشات والزخم الإعلامي في ألمانيا. يأتي ذلك بعد …
اهالي الاطفال الذين ماتوا حرقا في مستشفى اليرموك يتحدثون عن مأساتهم تحدث أهالي الاطفال المواليد الخدج الذين ماتوا في الحريق الذي اندلع في وحدة الولادة والامراض النسائية في مستشفى اليرموك …
إندلاع حريق في مستشفى اليرموك قسم الولادة وانباء عن اصابات ووفيات بين الأطفال الخدج أحد الأصدقاء أبلغنا أنه اتصل بصديق وهو طبيب هنام وقال أنه طلع من العمليات وشاف جهال …
This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.
Strictly Necessary Cookies
Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.
If you disable this cookie, we will not be able to save your preferences. This means that every time you visit this website you will need to enable or disable cookies again.