start = $calendarStart; } public function find( ?int $subscriberId, int $door ): ?array { if ( null === $subscriberId ) { return null; } global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom table, must be fresh. $row = $wpdb->get_row( $wpdb->prepare( "SELECT coupon_id FROM {$wpdb->prefix}advently_opens WHERE calendar_start = %s AND subscriber_id = %d AND door = %d", $this->start, $subscriberId, $door ), ARRAY_A ); if ( ! $row ) { return null; } return [ 'coupon_id' => null === $row['coupon_id'] ? null : (int) $row['coupon_id'] ]; } public function record( ?int $subscriberId, int $door, ?int $couponId ): bool { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom table write. $inserted = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->prefix}advently_opens (calendar_start, subscriber_id, door, coupon_id, opened_at) VALUES (%s, NULLIF(%d, 0), %d, NULLIF(%d, 0), %s)", $this->start, (int) $subscriberId, $door, (int) $couponId, current_time( 'mysql', true ) ) ); return 1 === $inserted; } /** * Door numbers this subscriber has already opened in this run. * * @return int[] */ public function openedBy( int $subscriberId ): array { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom table, per-visitor state. $doors = $wpdb->get_col( $wpdb->prepare( "SELECT door FROM {$wpdb->prefix}advently_opens WHERE calendar_start = %s AND subscriber_id = %d ORDER BY door", $this->start, $subscriberId ) ); return array_map( 'intval', $doors ); } }