283 lines
11 KiB
PHP
283 lines
11 KiB
PHP
<?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;
|
||
}
|
||
}
|
||
|
||
?>
|