Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
54.39% covered (warning)
54.39%
31 / 57
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
NoteComment
54.39% covered (warning)
54.39%
31 / 57
40.00% covered (danger)
40.00%
2 / 5
40.30
0.00% covered (danger)
0.00%
0 / 1
 save
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 getForNote
78.57% covered (warning)
78.57%
11 / 14
0.00% covered (danger)
0.00%
0 / 1
3.09
 delete
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 toArray
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 fromArray
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3namespace BuyerKiosk\Workbook;
4
5use \PDO;
6use \PDOException;
7
8/**
9 * NoteComment - Model for comments on notes
10 *
11 * Manages comments on workbook notes, allowing employees to discuss
12 * and add context to notes.
13 */
14class NoteComment
15{
16    /**
17     * @var int|null Comment ID
18     */
19    public $id;
20
21    /**
22     * @var int Note ID
23     */
24    public $noteId;
25
26    /**
27     * @var int Employee ID who created the comment
28     */
29    public $employeeId;
30
31    /**
32     * @var string Comment text
33     */
34    public $comment;
35
36    /**
37     * @var string Created timestamp
38     */
39    public $createdAt;
40
41    /**
42     * @var string|null Employee first name (joined from employees)
43     */
44    public $employeeFirstName;
45
46    /**
47     * @var string|null Employee last name (joined from employees)
48     */
49    public $employeeLastName;
50
51    /**
52     * Save note comment (insert)
53     *
54     * @param PDO $db Database connection
55     * @return int The ID of the created comment
56     * @throws \Exception If required fields are missing or insert fails
57     */
58    public function save(PDO $db): int
59    {
60        if (!isset($this->noteId) || !isset($this->employeeId) || !isset($this->comment)) {
61            throw new \Exception('noteId, employeeId, and comment are required');
62        }
63
64        try {
65            $stmt = $db->prepare("
66                INSERT INTO workbook_note_comments
67                (noteId, employeeId, comment)
68                VALUES
69                (:noteId, :employeeId, :comment)
70            ");
71
72            $stmt->execute([
73                ':noteId' => $this->noteId,
74                ':employeeId' => $this->employeeId,
75                ':comment' => $this->comment
76            ]);
77
78            $this->id = (int) $db->lastInsertId();
79            return $this->id;
80        } catch (PDOException $e) {
81            error_log("NoteComment::save error: " . $e->getMessage());
82            throw new \Exception('Failed to save note comment: ' . $e->getMessage());
83        }
84    }
85
86    /**
87     * Get all comments for a specific note
88     *
89     * Includes employee first and last name via JOIN (LEFT JOIN to support anonymous comments)
90     *
91     * @param PDO $db Database connection
92     * @param int $noteId Note ID
93     * @return array Array of comment data with employee names
94     */
95    public static function getForNote(PDO $db, int $noteId): array
96    {
97        try {
98            $stmt = $db->prepare("
99                SELECT dnc.*, e.employeeFirstName, e.employeeLastName
100                FROM workbook_note_comments dnc
101                LEFT JOIN employees e ON dnc.employeeId = e.employeeID
102                WHERE dnc.noteId = :noteId
103                ORDER BY dnc.createdAt ASC
104            ");
105
106            $stmt->execute([':noteId' => $noteId]);
107
108            $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
109            $comments = [];
110
111            foreach ($rows as $row) {
112                $comment = self::fromArray($row);
113                $comment->employeeFirstName = $row['employeeFirstName'];
114                $comment->employeeLastName = $row['employeeLastName'];
115                $comments[] = $comment->toArray();
116            }
117
118            return $comments;
119        } catch (PDOException $e) {
120            error_log("NoteComment::getForNote error: " . $e->getMessage());
121            return [];
122        }
123    }
124
125    /**
126     * Delete a note comment
127     *
128     * @param PDO $db Database connection
129     * @return bool True if successful
130     */
131    public function delete(PDO $db): bool
132    {
133        if (!isset($this->id)) {
134            error_log("NoteComment::delete error: id is required");
135            return false;
136        }
137
138        try {
139            $stmt = $db->prepare("
140                DELETE FROM workbook_note_comments
141                WHERE id = :id
142            ");
143
144            return $stmt->execute([':id' => $this->id]);
145        } catch (PDOException $e) {
146            error_log("NoteComment::delete error: " . $e->getMessage());
147            return false;
148        }
149    }
150
151    /**
152     * Convert NoteComment to array
153     *
154     * @return array Associative array representation
155     */
156    public function toArray(): array
157    {
158        return [
159            'id' => $this->id,
160            'noteId' => $this->noteId,
161            'employeeId' => $this->employeeId,
162            'employeeFirstName' => $this->employeeFirstName ?? null,
163            'employeeLastName' => $this->employeeLastName ?? null,
164            'comment' => $this->comment,
165            'createdAt' => $this->createdAt
166        ];
167    }
168
169    /**
170     * Create a NoteComment object from an array
171     *
172     * @param array $data Associative array of note comment data
173     * @return self
174     */
175    public static function fromArray(array $data): self
176    {
177        $comment = new self();
178        $comment->id = isset($data['id']) ? (int) $data['id'] : null;
179        $comment->noteId = (int) $data['noteId'];
180        $comment->employeeId = (int) $data['employeeId'];
181        $comment->comment = $data['comment'];
182        $comment->createdAt = $data['createdAt'] ?? null;
183
184        if (isset($data['employeeFirstName'])) {
185            $comment->employeeFirstName = $data['employeeFirstName'];
186        }
187        if (isset($data['employeeLastName'])) {
188            $comment->employeeLastName = $data['employeeLastName'];
189        }
190
191        return $comment;
192    }
193}