*/ class ProcessedMessageMapper extends QBMapper { public function __construct(IDBConnection $db) { parent::__construct($db, 'mcs_processed', ProcessedMessage::class); } /** * Check if a message has already been processed. */ public function isProcessed(string $userId, int $mailAccountId, string $messageId): bool { $qb = $this->db->getQueryBuilder(); $qb->select($qb->func()->count('*', 'count')) ->from($this->getTableName()) ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))) ->andWhere($qb->expr()->eq('mail_account_id', $qb->createNamedParameter($mailAccountId))) ->andWhere($qb->expr()->eq('message_id', $qb->createNamedParameter($messageId))); $result = $qb->executeQuery(); $count = (int)$result->fetchOne(); $result->closeCursor(); return $count > 0; } /** * Mark a message as processed. */ public function markProcessed(string $userId, int $mailAccountId, string $messageId): ProcessedMessage { $entity = new ProcessedMessage(); $entity->setUserId($userId); $entity->setMailAccountId($mailAccountId); $entity->setMessageId($messageId); $entity->setProcessedAt(date('Y-m-d H:i:s')); return $this->insert($entity); } /** * Clean up old processed message records (older than N days). */ public function cleanupOld(int $days = 90): int { $qb = $this->db->getQueryBuilder(); $cutoff = (new \DateTime("-{$days} days"))->format('Y-m-d H:i:s'); $qb->delete($this->getTableName()) ->where($qb->expr()->lt('processed_at', $qb->createNamedParameter($cutoff))); return $qb->executeStatement(); } }