*/ public function all_enabled(): array { $sql = $this->db->prepare( 'SELECT * FROM %i WHERE `is_enabled` = %d ORDER BY `id` ASC', $this->table( 'reminders' ), 1 ); return $this->hydrate_many( is_string( $sql ) ? $this->db->get_results( $sql, ARRAY_A ) : [] ); } /** * {@inheritDoc} * * @return list */ public function all(): array { $sql = $this->db->prepare( 'SELECT * FROM %i ORDER BY `id` ASC', $this->table( 'reminders' ) ); return $this->hydrate_many( is_string( $sql ) ? $this->db->get_results( $sql, ARRAY_A ) : [] ); } /** * {@inheritDoc} * * @param ReminderRule $rule Rule. */ public function save( ReminderRule $rule ): void { $targets = $rule->target_ids(); $statuses = $rule->booking_statuses(); $data = [ 'uuid' => $rule->uuid()->to_string(), 'name' => $rule->name(), 'template_key' => $rule->template_key(), 'channel' => $rule->channel(), 'offset_minutes' => $rule->offset_minutes(), 'applies_to' => $rule->applies_to(), 'target_ids' => $this->encode_int_list( $targets ), 'booking_statuses' => $this->encode_string_list( $statuses ), 'is_enabled' => $rule->is_enabled() ? 1 : 0, 'created_at' => $this->format_datetime( $rule->created_at() ), 'updated_at' => $this->format_datetime( $rule->updated_at() ), ]; if ( null === $rule->id() ) { $this->db->insert( $this->table( 'reminders' ), $data ); $rule->assign_id( $this->last_insert_id() ); return; } $this->db->update( $this->table( 'reminders' ), $data, [ 'id' => $rule->id() ] ); } /** * {@inheritDoc} * * @param int $id Id. */ public function find_by_id( int $id ): ?ReminderRule { $sql = $this->db->prepare( 'SELECT * FROM %i WHERE `id` = %d LIMIT 1', $this->table( 'reminders' ), $id ); $row = is_string( $sql ) ? $this->db->get_row( $sql, ARRAY_A ) : null; return is_array( $row ) ? $this->hydrate( $row ) : null; } /** * {@inheritDoc} * * @param int $id Id. */ public function delete( int $id ): void { $this->db->delete( $this->table( 'reminders' ), [ 'id' => $id ], [ '%d' ] ); } /** * Hydrate many rows. * * @param mixed $rows Rows. * @return list */ private function hydrate_many( mixed $rows ): array { if ( ! is_array( $rows ) ) { return []; } $out = []; foreach ( $rows as $row ) { if ( is_array( $row ) ) { $out[] = $this->hydrate( $row ); } } return $out; } /** * Hydrate one row. * * @param array $row Row. */ private function hydrate( array $row ): ReminderRule { return new ReminderRule( (int) $row['id'], new Uuid( (string) $row['uuid'] ), (string) $row['name'], (string) $row['template_key'], (string) $row['channel'], (int) $row['offset_minutes'], (string) $row['applies_to'], $this->decode_int_list( is_string( $row['target_ids'] ?? null ) ? (string) $row['target_ids'] : null ), $this->decode_string_list( is_string( $row['booking_statuses'] ?? null ) ? (string) $row['booking_statuses'] : null ), (bool) $row['is_enabled'], $this->parse_datetime( (string) $row['created_at'] ), $this->parse_datetime( (string) $row['updated_at'] ), ); } /** * Encode integer ids. * * @param list|null $ids Ids. */ private function encode_int_list( ?array $ids ): ?string { if ( null === $ids ) { return null; } return $this->encode_meta( [ 'ids' => $ids ] ); } /** * Encode string list. * * @param list|null $values Values. */ private function encode_string_list( ?array $values ): ?string { if ( null === $values ) { return null; } return $this->encode_meta( [ 'values' => $values ] ); } /** * Decode integer ids. * * @param string|null $json JSON. * @return list|null */ private function decode_int_list( ?string $json ): ?array { $decoded = $this->decode_meta( $json ); if ( null === $decoded ) { return null; } $raw = $decoded['ids'] ?? $decoded; if ( ! is_array( $raw ) ) { return null; } $out = []; foreach ( $raw as $id ) { if ( is_numeric( $id ) ) { $out[] = (int) $id; } } return $out; } /** * Decode string list. * * @param string|null $json JSON. * @return list|null */ private function decode_string_list( ?string $json ): ?array { $decoded = $this->decode_meta( $json ); if ( null === $decoded ) { return null; } $raw = $decoded['values'] ?? $decoded; if ( ! is_array( $raw ) ) { return null; } $out = []; foreach ( $raw as $value ) { if ( is_string( $value ) ) { $out[] = $value; } } return $out; } }