0, 'demo_data' => 0, 'transients' => 0, 'orphan_post_meta' => 0, 'total' => 0, ); if ( self::target_includes( $target, self::TARGET_WXR_IMPORT ) ) { $counts['wxr_import'] = self::count_wxr_import(); } if ( self::target_includes( $target, self::TARGET_DEMO_DATA ) ) { $counts['demo_data'] = self::count_demo_data(); } if ( self::target_includes( $target, self::TARGET_TRANSIENTS ) ) { $counts['transients'] = self::count_transients(); } if ( self::target_includes( $target, self::TARGET_ORPHAN_POST_META ) ) { $counts['orphan_post_meta'] = self::count_orphan_post_meta(); } $counts['total'] = $counts['wxr_import'] + $counts['demo_data'] + $counts['transients'] + $counts['orphan_post_meta']; return $counts; } /** * Delete garbage rows for the given target. * * @param string $target One of TARGET_* constants. * @return array{wxr_import:int, demo_data:int, transients:int, orphan_post_meta:int, total:int} * @throws InvalidArgumentException When $target is not a valid target. */ public static function delete_garbage( string $target = self::TARGET_ALL ): array { self::assert_valid_target( $target ); $deleted = array( 'wxr_import' => 0, 'demo_data' => 0, 'transients' => 0, 'orphan_post_meta' => 0, 'total' => 0, ); if ( self::target_includes( $target, self::TARGET_WXR_IMPORT ) ) { $deleted['wxr_import'] = self::delete_wxr_import(); } if ( self::target_includes( $target, self::TARGET_DEMO_DATA ) ) { $deleted['demo_data'] = self::delete_demo_data(); } if ( self::target_includes( $target, self::TARGET_TRANSIENTS ) ) { $deleted['transients'] = self::delete_transients(); } if ( self::target_includes( $target, self::TARGET_ORPHAN_POST_META ) ) { $deleted['orphan_post_meta'] = self::delete_orphan_post_meta(); } $deleted['total'] = $deleted['wxr_import'] + $deleted['demo_data'] + $deleted['transients'] + $deleted['orphan_post_meta']; return $deleted; } /** * Whether $target selects $bucket (i.e. target=all or target=bucket). * * @param string $target Selected target. * @param string $bucket Bucket constant. * @return bool */ private static function target_includes( string $target, string $bucket ): bool { return self::TARGET_ALL === $target || $bucket === $target; } /** * Validate target parameter. * * @param string $target Target to validate. * @return void * @throws InvalidArgumentException When $target is not in VALID_TARGETS. */ private static function assert_valid_target( string $target ): void { if ( in_array( $target, self::VALID_TARGETS, true ) ) { return; } $msg = sprintf( 'Invalid target "%s". Valid: %s', $target, implode( ', ', self::VALID_TARGETS ) ); throw new InvalidArgumentException( $msg ); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped } // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Internal cleanup class: $wpdb->commentmeta is WP-managed; meta_key patterns are static class constants. /** * Count `_wxr_import_*` rows in wp_commentmeta. * * @return int */ private static function count_wxr_import(): int { global $wpdb; $table = $wpdb->commentmeta; return (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$table}` WHERE meta_key LIKE '\\_wxr\\_import\\_%'" ); } /** * Delete `_wxr_import_*` rows from wp_commentmeta. * * @return int Affected row count. */ private static function delete_wxr_import(): int { global $wpdb; $table = $wpdb->commentmeta; return (int) $wpdb->query( "DELETE FROM `{$table}` WHERE meta_key LIKE '\\_wxr\\_import\\_%'" ); } /** * Count `_2meet_demo_*` rows in wp_commentmeta. * * @return int */ private static function count_demo_data(): int { global $wpdb; $table = $wpdb->commentmeta; return (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$table}` WHERE meta_key LIKE '\\_2meet\\_demo\\_%'" ); } /** * Delete `_2meet_demo_*` rows from wp_commentmeta. * * @return int Affected row count. */ private static function delete_demo_data(): int { global $wpdb; $table = $wpdb->commentmeta; return (int) $wpdb->query( "DELETE FROM `{$table}` WHERE meta_key LIKE '\\_2meet\\_demo\\_%'" ); } /** * Count rows matching transient meta_key patterns in wp_commentmeta. * * @return int */ private static function count_transients(): int { global $wpdb; $table = $wpdb->commentmeta; return (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$table}` WHERE meta_key LIKE '\\_transient\\_%' OR meta_key LIKE '\\_transient\\_timeout\\_%'" ); } /** * Delete rows matching transient meta_key patterns from wp_commentmeta. * * @return int Affected row count. */ private static function delete_transients(): int { global $wpdb; $table = $wpdb->commentmeta; return (int) $wpdb->query( "DELETE FROM `{$table}` WHERE meta_key LIKE '\\_transient\\_%' OR meta_key LIKE '\\_transient\\_timeout\\_%'" ); } /** * Count orphan post-meta keys in wp_commentmeta. * * @return int */ private static function count_orphan_post_meta(): int { global $wpdb; $table = $wpdb->commentmeta; $placeholders = implode( ',', array_fill( 0, count( self::ORPHAN_POST_META_KEYS ), '%s' ) ); return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$table}` WHERE meta_key IN ({$placeholders})", ...self::ORPHAN_POST_META_KEYS ) ); } /** * Delete orphan post-meta keys from wp_commentmeta. * * @return int Affected row count. */ private static function delete_orphan_post_meta(): int { global $wpdb; $table = $wpdb->commentmeta; $placeholders = implode( ',', array_fill( 0, count( self::ORPHAN_POST_META_KEYS ), '%s' ) ); return (int) $wpdb->query( $wpdb->prepare( "DELETE FROM `{$table}` WHERE meta_key IN ({$placeholders})", ...self::ORPHAN_POST_META_KEYS ) ); } // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared }