prefix . 'aimention_events'; } /** * Create the queue table (idempotent via dbDelta). * * @return void */ public static function create_table() { global $wpdb; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $table = self::table(); $charset = $wpdb->get_charset_collate(); $sql = "CREATE TABLE {$table} ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, event_id CHAR(36) NOT NULL, path VARCHAR(512) NOT NULL DEFAULT '', agent_id VARCHAR(64) NOT NULL DEFAULT '', operator VARCHAR(64) NOT NULL DEFAULT '', agent_purpose VARCHAR(32) NOT NULL DEFAULT '', raw_ip VARCHAR(45) NOT NULL DEFAULT '', created_at INT UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (id), UNIQUE KEY event_id (event_id), KEY created_at (created_at) ) {$charset};"; dbDelta( $sql ); } /** * Insert a pending event (raw IP held transiently until processing). * * @param array $event Row fields (event_id, path, agent_id, operator, agent_purpose, raw_ip, created_at). * @return void */ public static function enqueue( array $event ) { global $wpdb; // Insert-ignore semantics via the unique event_id; a duplicate is a no-op. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom plugin table (aimention_events); a write-queue has nothing to cache. $wpdb->query( $wpdb->prepare( 'INSERT IGNORE INTO %i' . ' (event_id, path, agent_id, operator, agent_purpose, raw_ip, created_at)' . ' VALUES (%s, %s, %s, %s, %s, %s, %d)', self::table(), $event['event_id'], $event['path'], $event['agent_id'], $event['operator'], $event['agent_purpose'], $event['raw_ip'], $event['created_at'] ) ); } /** * Fetch the oldest pending rows for processing. * * @param int $limit Maximum rows to return. * @return array List of associative row arrays. */ public static function take_batch( $limit = 50 ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom plugin table; the queue is drained in real time, caching would defeat it. return $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %i ORDER BY id ASC LIMIT %d', self::table(), $limit ), ARRAY_A ); } /** * Delete a processed row. * * @param int $id Row id. * @return void */ public static function delete( $id ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom plugin table; removing a processed queue row. $wpdb->delete( self::table(), array( 'id' => (int) $id ), array( '%d' ) ); } /** * Drop any row past the raw-IP retention cap, sent or not. * * @return void */ public static function purge_expired() { global $wpdb; $cutoff = time() - self::RAW_IP_MAX_AGE; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom plugin table; retention purge. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE created_at < %d', self::table(), $cutoff ) ); } /** * Drop the queue table entirely. * * @return void */ public static function drop_table() { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- custom plugin table teardown. $wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', self::table() ) ); } }