Files
CRM-IKZ/app/Controllers/CommentController.php
T
2026-07-14 08:19:56 +04:00

153 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Controllers;
use App\Core\Auth;
use App\Core\DB;
use App\Services\WebSocket\EventPublisher;
class CommentController
{
public function store(): void
{
if (!Auth::check()) {
if ($this->isAjax()) {
$this->json(['success' => false, 'message' => 'Unauthorized'], 403);
}
header('Location: /login');
exit;
}
$taskId = (int)($_POST['task_id'] ?? 0);
$text = trim((string)($_POST['text'] ?? ''));
if ($taskId <= 0 || $text === '') {
if ($this->isAjax()) {
$this->json(['success' => false, 'message' => 'Комментарий не заполнен'], 400);
}
$_SESSION['error'] = 'Комментарий не заполнен';
header('Location: /tasks');
exit;
}
$pdo = DB::connection();
// 1. Добавляем комментарий
$stmt = $pdo->prepare("
INSERT INTO task_comments (
task_id,
user_id,
text,
created_at,
updated_at
) VALUES (?, ?, ?, NOW(), NOW())
");
$stmt->execute([
$taskId,
Auth::user()['id'],
$text,
]);
// 2. Получаем мета
$stmt = $pdo->prepare("
SELECT
COUNT(*) AS comment_count,
MAX(id) AS last_comment_id
FROM task_comments
WHERE task_id = ?
");
$stmt->execute([$taskId]);
$commentMeta = $stmt->fetch();
// 3. Получаем задачу
$stmt = $pdo->prepare("
SELECT id, name, assignee_id
FROM tasks
WHERE id = ?
LIMIT 1
");
$stmt->execute([$taskId]);
$task = $stmt->fetch();
// 4. WS — обновление счетчиков
$publisher = new EventPublisher();
$publisher->publish([
'type' => 'comment_added',
'task_id' => $taskId,
'comment_count' => (int)($commentMeta['comment_count'] ?? 0),
'last_comment_id' => (int)($commentMeta['last_comment_id'] ?? 0),
'author_user_id' => (int)Auth::user()['id'],
'created_at' => date('Y-m-d H:i:s'),
]);
// 5. Уведомление ответственному
if ($task && !empty($task['assignee_id'])) {
$assigneeId = (int)$task['assignee_id'];
$currentUserId = (int)Auth::user()['id'];
if ($assigneeId !== $currentUserId) {
// запись в БД (если есть таблица notifications)
$stmt = $pdo->prepare("
INSERT INTO notifications (
user_id,
type,
title,
message,
data_json,
is_read,
created_at
) VALUES (?, ?, ?, ?, ?, 0, NOW())
");
$stmt->execute([
$assigneeId,
'task_comment_added',
'Новый комментарий',
'Задача: ' . (string)$task['name'],
json_encode(['task_id' => $taskId], JSON_UNESCAPED_UNICODE),
]);
// WS уведомление
$publisher->publish([
'type' => 'notification_created',
'user_id' => $assigneeId,
'task_id' => $taskId,
'title' => 'Новый комментарий',
'message' => 'Задача: ' . (string)$task['name'],
'created_at' => date('Y-m-d H:i:s'),
]);
}
}
// 6. Ответ
if ($this->isAjax()) {
$this->json([
'success' => true,
'task_id' => $taskId,
'comment_count' => (int)($commentMeta['comment_count'] ?? 0),
'last_comment_id' => (int)($commentMeta['last_comment_id'] ?? 0),
]);
}
header('Location: /tasks');
exit;
}
private function isAjax(): bool
{
return strtolower((string)($_SERVER['HTTP_X_REQUESTED_WITH'] ?? '')) === 'xmlhttprequest';
}
private function json(array $data, int $statusCode = 200): void
{
http_response_code($statusCode);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
}