wpdb = $wpdb ?? $GLOBALS['wpdb']; } /** * Enqueue an event. * * @param string $event_name Event name (e.g. order_created). * @param string $payload_json JSON-encoded payload. * @return int|false Insert ID or false. */ public function enqueue( string $event_name, string $payload_json ) { $table = QueueTable::getTableName( $this->wpdb ); $result = $this->wpdb->insert( $table, array( 'event_name' => $event_name, 'payload_json' => $payload_json, 'status' => QueueTable::STATUS_PENDING, 'created_at' => current_time( 'mysql' ), ), array( '%s', '%s', '%s', '%s' ) ); return $result ? (int) $this->wpdb->insert_id : false; } /** * Fetch pending events for processing. * * @param int $limit Max events to fetch. * @return array */ public function fetchPending( int $limit = 20 ): array { $table = QueueTable::getTableName( $this->wpdb ); $pending = QueueTable::STATUS_PENDING; $wpdb = $this->wpdb; $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i WHERE status = %s ORDER BY created_at ASC LIMIT %d", $table, $pending, $limit, ) ); return is_array( $results ) ? $results : array(); } /** * Whether any events are waiting to be processed. * * @return bool */ public function hasPending(): bool { $wpdb = $this->wpdb; $table = QueueTable::getTableName( $wpdb ); $found = $wpdb->get_var( $wpdb->prepare( 'SELECT id FROM %i WHERE status = %s LIMIT 1', $table, QueueTable::STATUS_PENDING ) ); return null !== $found && '' !== (string) $found; } /** * Mark event as processing (claim for worker). * * @param int $id Event ID. * @return bool */ public function markProcessing( int $id ): bool { return $this->updateStatus( $id, QueueTable::STATUS_PROCESSING ); } /** * Mark event as processed. * * @param int $id Event ID. * @return bool */ public function markProcessed( int $id ): bool { $table = QueueTable::getTableName( $this->wpdb ); return (bool) $this->wpdb->update( $table, array( 'status' => QueueTable::STATUS_PROCESSED, 'processed_at' => current_time( 'mysql' ), ), array( 'id' => $id ), array( '%s', '%s' ), array( '%d' ) ); } /** * Mark event as failed. * * @param int $id Event ID. * @return bool */ public function markFailed( int $id ): bool { return $this->updateStatus( $id, QueueTable::STATUS_FAILED ); } /** * Release an event back to pending for a later retry. * * @param int $id Event ID. * @return bool */ public function releaseForRetry( int $id ): bool { return $this->updateStatus( $id, QueueTable::STATUS_PENDING ); } /** * Update event status. * * @param int $id Event ID. * @param string $status Status. * @return bool */ private function updateStatus( int $id, string $status ): bool { $table = QueueTable::getTableName( $this->wpdb ); return (bool) $this->wpdb->update( $table, array( 'status' => $status ), array( 'id' => $id ), array( '%s' ), array( '%d' ) ); } }