1
0
Files
TaskBoard/backend/app/class/enity/class_comment.php
2026-01-19 15:10:37 +07:00

283 lines
11 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
class Comment extends BaseEntity {
protected $db_name = 'comments';
// Свойства комментария
public $id;
public $id_task;
public $id_accounts;
public $id_answer; // ID родительского комментария (ответ на)
public $text;
public $date_create;
// Создание комментария
public function create() {
static::$error_message = [];
// Валидация
if (!$this->id_task) {
$this->addError('id_task', 'Задача не указана');
}
if (!$this->id_accounts) {
$this->addError('id_accounts', 'Пользователь не указан');
}
if (!$this->text || trim($this->text) === '') {
$this->addError('text', 'Текст комментария не может быть пустым');
}
if ($errors = $this->getErrors()) {
return $errors;
}
// Проверяем что задача существует и не архивная
$task = Task::check_task($this->id_task);
if ((int)$task['archive'] === 1) {
$this->addError('task', 'Нельзя комментировать архивные задачи');
return $this->getErrors();
}
// Если это ответ — проверяем что родительский комментарий существует
if ($this->id_answer) {
self::checkComment($this->id_answer);
}
// Вставляем в базу
Database::insert($this->db_name, [
'id_task' => $this->id_task,
'id_accounts' => $this->id_accounts,
'id_answer' => $this->id_answer ?: null,
'text' => $this->text,
'date_create' => date('Y-m-d H:i:s'),
'file_img' => '[]'
]);
$this->id = Database::id();
// Возвращаем созданный комментарий с данными пользователя
return [
'success' => true,
'comment' => $this->getById($this->id)
];
}
// Обновление комментария
public function update() {
static::$error_message = [];
// Валидация
if (!$this->id) {
$this->addError('id', 'ID комментария не указан');
}
if (!$this->text || trim($this->text) === '') {
$this->addError('text', 'Текст комментария не может быть пустым');
}
if ($errors = $this->getErrors()) {
return $errors;
}
// Проверяем что комментарий существует
$comment = self::checkComment($this->id);
// Проверяем что задача не архивная
$task = Database::get('cards_task', ['archive'], ['id' => $comment['id_task']]);
if ($task && (int)$task['archive'] === 1) {
$this->addError('task', 'Нельзя редактировать комментарии архивных задач');
return $this->getErrors();
}
// Проверяем что пользователь — автор комментария
if ((int)$comment['id_accounts'] !== (int)$this->id_accounts) {
$this->addError('access', 'Вы можете редактировать только свои комментарии');
return $this->getErrors();
}
// Обновляем в БД
Database::update($this->db_name, [
'text' => $this->text
], [
'id' => $this->id
]);
return [
'success' => true,
'comment' => $this->getById($this->id)
];
}
// Удаление комментария (с дочерними)
public static function delete($id, $id_accounts) {
// Проверяем что комментарий существует
$comment = self::checkComment($id);
// Получаем задачу для проверки админа проекта и архивации
$task = Database::get('cards_task', ['id_project', 'archive'], ['id' => $comment['id_task']]);
// Нельзя удалять комментарии архивных задач
if ($task && (int)$task['archive'] === 1) {
RestApi::response([
'success' => false,
'errors' => ['task' => 'Нельзя удалять комментарии архивных задач']
], 400);
}
// Проверяем права: автор комментария ИЛИ админ проекта
$isAuthor = (int)$comment['id_accounts'] === (int)$id_accounts;
$isProjectAdmin = $task && ProjectAccess::isAdmin($task['id_project'], $id_accounts);
if (!$isAuthor && !$isProjectAdmin) {
RestApi::response([
'success' => false,
'errors' => ['access' => 'Нет прав на удаление комментария']
], 403);
}
// Рекурсивно удаляем все дочерние комментарии
self::deleteWithChildren($id);
return ['success' => true];
}
// Рекурсивное удаление комментария и всех его дочерних
private static function deleteWithChildren($id) {
// Находим все дочерние комментарии
$children = Database::select('comments', ['id'], ['id_answer' => $id]);
// Рекурсивно удаляем дочерние
if ($children) {
foreach ($children as $child) {
self::deleteWithChildren($child['id']);
}
}
// Удаляем папку с файлами комментария
FileUpload::deleteFolder('comment', $id);
// Удаляем сам комментарий
Database::delete('comments', ['id' => $id]);
}
// Удаление комментария (проверка прав уже выполнена на уровне API)
public static function deleteWithAccess($id) {
// Рекурсивно удаляем все дочерние комментарии
self::deleteWithChildren($id);
return ['success' => true];
}
// === МЕТОДЫ ДЛЯ РАБОТЫ С ФАЙЛАМИ ===
// Загрузка файла к комментарию (проверка прав уже выполнена на уровне API)
public static function uploadFileSimple($comment_id, $file_base64, $file_name) {
return FileUpload::upload('comment', $comment_id, $file_base64, $file_name);
}
// Удаление файлов комментария (проверка прав уже выполнена на уровне API)
public static function deleteFileSimple($comment_id, $file_names) {
return FileUpload::delete('comment', $comment_id, $file_names);
}
// Загрузка файла к комментарию (только автор может загружать) - DEPRECATED
public static function uploadFile($comment_id, $file_base64, $file_name, $user_id) {
// Проверка что комментарий существует
$comment = self::checkComment($comment_id);
// Проверка что пользователь — автор комментария
if ((int)$comment['id_accounts'] !== (int)$user_id) {
RestApi::response([
'success' => false,
'errors' => ['access' => 'Вы можете загружать файлы только к своим комментариям']
], 403);
}
return FileUpload::upload('comment', $comment_id, $file_base64, $file_name);
}
// Удаление файлов комментария (автор или админ проекта) - DEPRECATED
public static function deleteFile($comment_id, $file_names, $user_id) {
// Проверка что комментарий существует
$comment = self::checkComment($comment_id);
// Получаем задачу для проверки админа проекта
$task = Database::get('cards_task', ['id_project'], ['id' => $comment['id_task']]);
// Проверка прав: автор комментария ИЛИ админ проекта
$isAuthor = (int)$comment['id_accounts'] === (int)$user_id;
$isProjectAdmin = $task && ProjectAccess::isAdmin($task['id_project'], $user_id);
if (!$isAuthor && !$isProjectAdmin) {
RestApi::response([
'success' => false,
'errors' => ['access' => 'Нет прав на удаление файлов']
], 403);
}
return FileUpload::delete('comment', $comment_id, $file_names);
}
// Получение комментария по ID (с данными пользователя)
public function getById($id) {
$comment = Database::get($this->db_name, [
'[>]accounts' => ['id_accounts' => 'id']
], [
'comments.id',
'comments.id_task',
'comments.id_accounts',
'comments.id_answer',
'comments.text',
'comments.date_create',
'comments.file_img',
'accounts.name(author_name)',
'accounts.avatar_url(author_avatar)'
], [
'comments.id' => $id
]);
// Декодируем JSON файлов
if ($comment) {
$comment['file_img'] = $comment['file_img'] ? json_decode($comment['file_img'], true) : [];
}
return $comment;
}
// Получение всех комментариев задачи
public function getByTask($id_task) {
// Проверяем что задача существует
Task::check_task($id_task);
$comments = Database::select($this->db_name, [
'[>]accounts' => ['id_accounts' => 'id']
], [
'comments.id',
'comments.id_task',
'comments.id_accounts',
'comments.id_answer',
'comments.text',
'comments.date_create',
'comments.file_img',
'accounts.name(author_name)',
'accounts.avatar_url(author_avatar)'
], [
'comments.id_task' => $id_task,
'ORDER' => ['comments.date_create' => 'ASC']
]);
// Декодируем JSON файлов для каждого комментария
return array_map(function($comment) {
$comment['file_img'] = $comment['file_img'] ? json_decode($comment['file_img'], true) : [];
return $comment;
}, $comments ?: []);
}
// Проверка и получение комментария (при ошибке — сразу ответ и exit)
public static function checkComment($id) {
$comment = Database::get('comments', '*', ['id' => $id]);
if (!$id || !$comment) {
RestApi::response(['success' => false, 'errors' => ['comment' => 'Комментарий не найден']], 404);
}
return $comment;
}
}
?>