Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
9.09% covered (danger)
9.09%
4 / 44
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
NoteReaction
9.09% covered (danger)
9.09%
4 / 44
0.00% covered (danger)
0.00%
0 / 5
101.91
0.00% covered (danger)
0.00%
0 / 1
 add
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 remove
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 getCount
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 hasReacted
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 getReactors
57.14% covered (warning)
57.14%
4 / 7
0.00% covered (danger)
0.00%
0 / 1
2.31
1<?php
2
3namespace BuyerKiosk\Workbook;
4
5use \PDO;
6use \PDOException;
7
8/**
9 * NoteReaction - Model for note reactions (likes)
10 *
11 * Simple static methods for managing reactions on notes.
12 * Uses UNIQUE constraint on (noteId, employeeId) to prevent duplicate reactions.
13 */
14class NoteReaction
15{
16    /**
17     * Add a reaction to a note
18     *
19     * Uses INSERT IGNORE to handle duplicate reactions gracefully
20     *
21     * @param PDO $db Database connection
22     * @param int $noteId Note ID
23     * @param int $employeeId Employee ID
24     * @param string $reactionType Reaction type (default: 'like')
25     * @return bool True if reaction was added (or already exists)
26     */
27    public static function add(PDO $db, int $noteId, int $employeeId, string $reactionType = 'like'): bool
28    {
29        try {
30            $stmt = $db->prepare("
31                INSERT IGNORE INTO workbook_note_reactions
32                (noteId, employeeId, reactionType)
33                VALUES
34                (:noteId, :employeeId, :reactionType)
35            ");
36
37            return $stmt->execute([
38                ':noteId' => $noteId,
39                ':employeeId' => $employeeId,
40                ':reactionType' => $reactionType
41            ]);
42        } catch (PDOException $e) {
43            error_log("NoteReaction::add error: " . $e->getMessage());
44            return false;
45        }
46    }
47
48    /**
49     * Remove a reaction from a note
50     *
51     * @param PDO $db Database connection
52     * @param int $noteId Note ID
53     * @param int $employeeId Employee ID
54     * @return bool True if reaction was removed (or didn't exist)
55     */
56    public static function remove(PDO $db, int $noteId, int $employeeId): bool
57    {
58        try {
59            $stmt = $db->prepare("
60                DELETE FROM workbook_note_reactions
61                WHERE noteId = :noteId AND employeeId = :employeeId
62            ");
63
64            return $stmt->execute([
65                ':noteId' => $noteId,
66                ':employeeId' => $employeeId
67            ]);
68        } catch (PDOException $e) {
69            error_log("NoteReaction::remove error: " . $e->getMessage());
70            return false;
71        }
72    }
73
74    /**
75     * Get reaction count for a note
76     *
77     * @param PDO $db Database connection
78     * @param int $noteId Note ID
79     * @return int Reaction count
80     */
81    public static function getCount(PDO $db, int $noteId): int
82    {
83        try {
84            $stmt = $db->prepare("
85                SELECT COUNT(*) as count
86                FROM workbook_note_reactions
87                WHERE noteId = :noteId
88            ");
89
90            $stmt->execute([':noteId' => $noteId]);
91            $row = $stmt->fetch(PDO::FETCH_ASSOC);
92
93            return $row ? (int) $row['count'] : 0;
94        } catch (PDOException $e) {
95            error_log("NoteReaction::getCount error: " . $e->getMessage());
96            return 0;
97        }
98    }
99
100    /**
101     * Check if an employee has reacted to a note
102     *
103     * @param PDO $db Database connection
104     * @param int $noteId Note ID
105     * @param int $employeeId Employee ID
106     * @return bool True if employee has reacted
107     */
108    public static function hasReacted(PDO $db, int $noteId, int $employeeId): bool
109    {
110        try {
111            $stmt = $db->prepare("
112                SELECT id
113                FROM workbook_note_reactions
114                WHERE noteId = :noteId AND employeeId = :employeeId
115                LIMIT 1
116            ");
117
118            $stmt->execute([
119                ':noteId' => $noteId,
120                ':employeeId' => $employeeId
121            ]);
122
123            return (bool) $stmt->fetch();
124        } catch (PDOException $e) {
125            error_log("NoteReaction::hasReacted error: " . $e->getMessage());
126            return false;
127        }
128    }
129
130    /**
131     * Get all employees who reacted to a note
132     *
133     * @param PDO $db Database connection
134     * @param int $noteId Note ID
135     * @return array Array of employee data with reaction info
136     */
137    public static function getReactors(PDO $db, int $noteId): array
138    {
139        try {
140            $stmt = $db->prepare("
141                SELECT
142                    dnr.id,
143                    dnr.employeeId,
144                    dnr.reactionType,
145                    dnr.createdAt,
146                    e.employeeFirstName,
147                    e.employeeLastName
148                FROM workbook_note_reactions dnr
149                INNER JOIN employees e ON dnr.employeeId = e.employeeID
150                WHERE dnr.noteId = :noteId
151                ORDER BY dnr.createdAt DESC
152            ");
153
154            $stmt->execute([':noteId' => $noteId]);
155            return $stmt->fetchAll(PDO::FETCH_ASSOC);
156        } catch (PDOException $e) {
157            error_log("NoteReaction::getReactors error: " . $e->getMessage());
158            return [];
159        }
160    }
161}