← All changes
|
jetpack_vendor/automattic/jetpack-sync/src/sync-queue/class-queue-storage-table.php
+56
-45
12.7.3
→
16.3-a.1
View file →
| @@ -10,13 +10,21 @@ | ||
| 10 | 10 | */ |
| 11 | 11 | |
| 12 | 12 | namespace Automattic\Jetpack\Sync\Queue; |
| 13 | 13 | |
| 14 | +use Automattic\Jetpack\Sync\Sender; | |
| 15 | +use Automattic\Jetpack\Sync\Settings; | |
| 16 | + | |
| 14 | 17 | /** |
| 15 | 18 | * Custom Sync events table storage backend for the Queue. |
| 16 | 19 | */ |
| 17 | 20 | class Queue_Storage_Table { |
| 21 | + | |
| 18 | 22 | /** |
| 23 | + * The name of the transient to use to disable custom queue table in we get a table doesn't exist error. | |
| 24 | + */ | |
| 25 | + const CUSTOM_QUEUE_TABLE_DISABLE_WPDB_ERROR_NOT_EXIST_FLAG = 'jetpack_sync_custom_queue_table_disable_wpdb_error_not_exist'; | |
| 26 | + /** | |
| 19 | 27 | * The custom Sync events table name, without a prefix. |
| 20 | 28 | * A prefix will be added when the class is instantiated, |
| 21 | 29 | * as we fetch the prefix from `$wpdb` as is configured in |
| 22 | 30 | * the WordPress config file. |
| @@ -219,57 +227,40 @@ | ||
| 219 | 227 | /** |
| 220 | 228 | * Fetch items from the queue. |
| 221 | 229 | * |
| 222 | 230 | * @param int|null $item_count How many items to fetch from the queue. |
| 223 | - * The parameter is null-able, if no limit on the amount of items. | |
| 231 | + * Null for no limit. | |
| 232 | + * @param string $order Sort direction for the items. Accepts 'ASC' or 'DESC'. | |
| 233 | + * Any other value will be treated as 'ASC'. | |
| 224 | 234 | * |
| 225 | - * @return array|object|stdClass[]|null | |
| 235 | + * @return array|object|null Array of result objects on success, or null on failure. | |
| 226 | 236 | */ |
| 227 | - public function fetch_items( $item_count ) { | |
| 237 | + public function fetch_items( $item_count, $order = 'ASC' ) { | |
| 228 | 238 | global $wpdb; |
| 229 | 239 | |
| 230 | - /** | |
| 231 | - * Ignoring the linting warning, as there's still no placeholder replacement for DB field name, | |
| 232 | - * in this case this is `$this->table_name` | |
| 233 | - */ | |
| 234 | - // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 240 | + $order = ( 'DESC' === $order ) ? 'DESC' : 'ASC'; | |
| 241 | + $sql_order = "ORDER BY event_id {$order}"; | |
| 235 | 242 | |
| 236 | - // TODO make it more simple for the $item_count | |
| 243 | + $sql = " | |
| 244 | + SELECT | |
| 245 | + event_id AS id, | |
| 246 | + event_payload AS value | |
| 247 | + FROM {$this->table_name} | |
| 248 | + WHERE queue_id LIKE %s | |
| 249 | + {$sql_order} | |
| 250 | + "; | |
| 251 | + | |
| 252 | + $params = array( $this->queue_id ); | |
| 253 | + | |
| 237 | 254 | if ( $item_count ) { |
| 238 | - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 239 | - $items = $wpdb->get_results( | |
| 240 | - $wpdb->prepare( | |
| 241 | - " | |
| 242 | - SELECT | |
| 243 | - event_id AS id, | |
| 244 | - event_payload AS value | |
| 245 | - FROM {$this->table_name} | |
| 246 | - WHERE queue_id LIKE %s | |
| 247 | - ORDER BY event_id ASC | |
| 248 | - LIMIT %d | |
| 249 | - ", | |
| 250 | - $this->queue_id, | |
| 251 | - $item_count | |
| 252 | - ) | |
| 253 | - ); | |
| 254 | - } else { | |
| 255 | - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 256 | - $items = $wpdb->get_results( | |
| 257 | - $wpdb->prepare( | |
| 258 | - " | |
| 259 | - SELECT | |
| 260 | - event_id AS id, | |
| 261 | - event_payload AS value | |
| 262 | - FROM {$this->table_name} | |
| 263 | - WHERE queue_id LIKE %s | |
| 264 | - ORDER BY event_id ASC | |
| 265 | - ", | |
| 266 | - $this->queue_id | |
| 267 | - ) | |
| 268 | - ); | |
| 255 | + $sql .= ' LIMIT %d'; | |
| 256 | + $params[] = $item_count; | |
| 269 | 257 | } |
| 270 | 258 | |
| 271 | - // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared | |
| 259 | + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 260 | + $items = $wpdb->get_results( | |
| 261 | + $wpdb->prepare( $sql, $params ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared | |
| 262 | + ); | |
| 272 | 263 | |
| 273 | 264 | return $items; |
| 274 | 265 | } |
| 275 | 266 | |
| @@ -277,9 +268,9 @@ | ||
| 277 | 268 | * Fetches items with specific IDs from the Queue. |
| 278 | 269 | * |
| 279 | 270 | * @param array $items_ids Items IDs to fetch from the queue. |
| 280 | 271 | * |
| 281 | - * @return array|object|stdClass[]|null | |
| 272 | + * @return object[]|null | |
| 282 | 273 | */ |
| 283 | 274 | public function fetch_items_by_ids( $items_ids ) { |
| 284 | 275 | global $wpdb; |
| 285 | 276 | |
| @@ -315,9 +306,9 @@ | ||
| 315 | 306 | public function get_item_count() { |
| 316 | 307 | global $wpdb; |
| 317 | 308 | |
| 318 | 309 | // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 319 | - return (int) $wpdb->get_var( | |
| 310 | + $items_count = (int) $wpdb->get_var( | |
| 320 | 311 | $wpdb->prepare( |
| 321 | 312 | /** |
| 322 | 313 | * Ignoring the linting warning, as there's still no placeholder replacement for DB field name, |
| 323 | 314 | * in this case this is `$this->table_name` |
| @@ -322,12 +313,28 @@ | ||
| 322 | 313 | * Ignoring the linting warning, as there's still no placeholder replacement for DB field name, |
| 323 | 314 | * in this case this is `$this->table_name` |
| 324 | 315 | */ |
| 325 | 316 | // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 326 | - "SELECT count(*) FROM {$this->table_name} WHERE queue_id = %s", | |
| 317 | + "SELECT COUNT(*) FROM {$this->table_name} WHERE queue_id = %s", | |
| 327 | 318 | $this->queue_id |
| 328 | 319 | ) |
| 329 | 320 | ); |
| 321 | + // If the table does not exist, disable the custom queue table and send an error. | |
| 322 | + if ( ! empty( $wpdb->last_error ) | |
| 323 | + && str_contains( $wpdb->last_error, $this->table_name_no_prefix . "' doesn't exist" ) | |
| 324 | + && ! get_transient( self::CUSTOM_QUEUE_TABLE_DISABLE_WPDB_ERROR_NOT_EXIST_FLAG ) | |
| 325 | + ) { | |
| 326 | + set_transient( self::CUSTOM_QUEUE_TABLE_DISABLE_WPDB_ERROR_NOT_EXIST_FLAG, true, 6 * HOUR_IN_SECONDS ); | |
| 327 | + Settings::update_settings( array( 'custom_queue_table_enabled' => 0 ) ); | |
| 328 | + $data = array( | |
| 329 | + 'timestamp' => microtime( true ), | |
| 330 | + 'error' => $wpdb->last_error, | |
| 331 | + ); | |
| 332 | + $sender = Sender::get_instance(); | |
| 333 | + $sender->send_action( 'jetpack_sync_storage_error_custom_table_not_exist', $data ); | |
| 334 | + } | |
| 335 | + | |
| 336 | + return $items_count; | |
| 330 | 337 | } |
| 331 | 338 | |
| 332 | 339 | /** |
| 333 | 340 | * Clear out the queue. |
| @@ -431,9 +438,9 @@ | ||
| 431 | 438 | * Return $max_count items from the queue, including their value string length. |
| 432 | 439 | * |
| 433 | 440 | * @param int $max_count How many items to fetch from the queue. |
| 434 | 441 | * |
| 435 | - * @return array|object|stdClass[]|null | |
| 442 | + * @return object[]|null | |
| 436 | 443 | */ |
| 437 | 444 | public function get_items_ids_with_size( $max_count ) { |
| 438 | 445 | global $wpdb; |
| 439 | 446 | |
| @@ -607,8 +614,12 @@ | ||
| 607 | 614 | $custom_table_name = $queue_table_storage->table_name; |
| 608 | 615 | |
| 609 | 616 | // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 610 | 617 | $count_result = $wpdb->get_row( "SELECT COUNT(*) as item_count FROM {$custom_table_name}" ); |
| 618 | + | |
| 619 | + if ( $wpdb->last_error ) { | |
| 620 | + return; | |
| 621 | + } | |
| 611 | 622 | |
| 612 | 623 | $item_count = $count_result->item_count; |
| 613 | 624 | |
| 614 | 625 | $limit = 100; |