pdo->prepare( 'SELECT id FROM article_reactions WHERE article_uuid = :uuid AND reaction_type = :type AND visitor_hash = :hash' ); $st->execute([':uuid' => $uuid, ':type' => $type, ':hash' => $visitorHash]); if ($st->fetchColumn() !== false) { $this->pdo->prepare( 'DELETE FROM article_reactions WHERE article_uuid = :uuid AND reaction_type = :type AND visitor_hash = :hash' )->execute([':uuid' => $uuid, ':type' => $type, ':hash' => $visitorHash]); return false; } $this->pdo->prepare( 'INSERT INTO article_reactions (article_uuid, reaction_type, visitor_hash) VALUES (:uuid, :type, :hash) ON CONFLICT DO NOTHING' )->execute([':uuid' => $uuid, ':type' => $type, ':hash' => $visitorHash]); return true; } /** @return array */ public function statsForArticle(string $uuid): array { $st = $this->pdo->prepare( 'SELECT reaction_type, COUNT(*) AS cnt FROM article_reactions WHERE article_uuid = :uuid GROUP BY reaction_type' ); $st->execute([':uuid' => $uuid]); $stats = array_fill_keys(self::TYPES, 0); foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $row) { $stats[$row['reaction_type']] = (int) $row['cnt']; } return $stats; } /** @return string[] */ public function visitorReactions(string $uuid, string $visitorHash): array { $st = $this->pdo->prepare( 'SELECT reaction_type FROM article_reactions WHERE article_uuid = :uuid AND visitor_hash = :hash' ); $st->execute([':uuid' => $uuid, ':hash' => $visitorHash]); return array_column($st->fetchAll(PDO::FETCH_ASSOC), 'reaction_type'); } }