value ); return $id ? (int) $id : null; } public function markSent(int $id, ?string $providerMessageId = null): bool { $result = DB::update( 'update mail_log set status = ?, sent_at = NOW(), provider_message_id = ?, error_message = NULL where id = ?', MailLogStatus::Sent->value, $providerMessageId, (string) $id ); return $result !== false; } public function markFailed(int $id, string $errorMessage): bool { $result = DB::update( 'update mail_log set status = ?, error_message = ? where id = ?', MailLogStatus::Failed->value, $errorMessage, (string) $id ); return $result !== false; } public function listPaged(array $options): array { $search = trim((string) ($options['search'] ?? '')); $status = MailLogStatus::tryNormalize((string) ($options['status'] ?? ''))->value ?? ''; $createdFrom = trim((string) ($options['created_from'] ?? '')); $createdTo = trim((string) ($options['created_to'] ?? '')); $allowedOrder = ['id', 'created_at', 'sent_at', 'to_email', 'subject', 'status']; [$limit, $offset] = RepoQuery::sanitizeLimitOffset($options); [$order, $dir] = RepoQuery::sanitizeOrder($options, $allowedOrder, 'created_at', 'desc'); $where = []; $params = []; RepoQuery::addLikeFilter($where, $params, ['to_email', 'subject', 'template'], $search); RepoQuery::addEqualsFilter($where, $params, $status, 'status = ?'); if ($createdFrom !== '') { $where[] = 'created_at >= ?'; $params[] = $createdFrom . ' 00:00:00'; } if ($createdTo !== '') { $where[] = 'created_at <= ?'; $params[] = $createdTo . ' 23:59:59'; } $whereSql = $where ? (' where ' . implode(' and ', $where)) : ''; $count = DB::selectValue('select count(*) from mail_log' . $whereSql, ...$params); $total = $count ? (int) $count : 0; $query = 'select id, to_email, subject, template, status, created_at, sent_at, error_message, provider_message_id from mail_log' . $whereSql . sprintf(' order by `%s` %s limit ? offset ?', $order, $dir); $queryParams = array_merge($params, [(string) $limit, (string) $offset]); $rows = call_user_func_array(['MintyPHP\\DB', 'select'], array_merge([$query], $queryParams)); return [ 'total' => $total, 'rows' => $this->unwrapList($rows), ]; } public function find(int $id): ?array { $row = DB::selectOne( 'select id, to_email, subject, template, status, created_at, sent_at, error_message, provider_message_id from mail_log where id = ? limit 1', (string) $id ); return $this->unwrap($row); } private function unwrap(?array $row): ?array { if (!$row) { return null; } return $row['mail_log'] ?? null; } private function unwrapList(mixed $rows): array { if (!is_array($rows)) { return []; } $list = []; foreach ($rows as $row) { $mailLog = $row['mail_log'] ?? null; if (is_array($mailLog)) { $list[] = $mailLog; } } return $list; } }