Files
folio/src/ReactionManager.php
T

64 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
class ReactionManager
{
public const TYPES = ['useful', 'important', 'interesting'];
public function __construct(private PDO $pdo)
{
}
/** Ajoute ou retire une réaction. Retourne true si ajoutée, false si retirée. */
public function toggle(string $uuid, string $type, string $visitorHash): bool
{
if (!in_array($type, self::TYPES, true)) {
return false;
}
$st = $this->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<string, int> */
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');
}
}