1
0
Files
TaskBoard/backend/app/class/enity/class_project.php
Falknat 250eac70a7 Управление проектами
Добавил возможность удаления, создание и редактирование проектов.
2026-01-18 10:19:34 +07:00

389 lines
15 KiB
PHP
Raw 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 Project extends BaseEntity {
protected $db_name = 'project';
// Получение всех проектов
public function getAll() {
$current_user_id = RestApi::getCurrentUserId();
$projects = Database::select($this->db_name, [
'id',
'id_order',
'name',
'id_ready',
'id_admin'
], [
'ORDER' => ['id_order' => 'ASC']
]);
// Обрабатываем id_admin для каждого проекта
return array_map(function($project) use ($current_user_id) {
$admins = $project['id_admin'] ? json_decode($project['id_admin'], true) : [];
if ($current_user_id && in_array((int)$current_user_id, $admins, true)) {
$project['id_admin'] = true;
} else {
unset($project['id_admin']);
}
return $project;
}, $projects);
}
// Получение одного проекта
// $current_user_id — ID текущего пользователя для проверки админства
public static function get($id, $current_user_id = null) {
$project = Database::get('project', [
'id',
'id_order',
'name',
'id_ready',
'id_admin'
], ['id' => $id]);
if ($project) {
$admins = $project['id_admin'] ? json_decode($project['id_admin'], true) : [];
// Если передан user_id — проверяем админство
if ($current_user_id && in_array((int)$current_user_id, $admins, true)) {
$project['id_admin'] = true;
} else {
// Не админ — убираем поле
unset($project['id_admin']);
}
}
return $project;
}
// Получение id_ready (ID колонки "Готово") по ID проекта
public static function getReadyColumnId($project_id) {
$project = Database::get('project', ['id_ready'], ['id' => $project_id]);
return $project ? (int)$project['id_ready'] : null;
}
// Получение колонок проекта
public static function getColumns($project_id) {
return Database::select('columns', [
'id',
'name_columns',
'color',
'id_order'
], [
'id_project' => $project_id,
'ORDER' => ['id_order' => 'ASC']
]);
}
// Получение отделов проекта
public static function getDepartments($project_id) {
return Database::select('departments', [
'id',
'name_departments',
'color'
], [
'id_project' => $project_id
]);
}
// Получение всех данных проекта (проект + колонки + отделы + метки)
public static function getProjectData($project_id) {
// Получаем ID текущего пользователя для проверки админства
$current_user_id = RestApi::getCurrentUserId();
$project = self::get($project_id, $current_user_id);
if (!$project) {
return null;
}
// Получаем метки (глобальные)
$labels = Database::select('labels', [
'id',
'name_labels',
'icon',
'color'
]);
return [
'project' => $project,
'columns' => self::getColumns($project_id),
'departments' => self::getDepartments($project_id),
'labels' => $labels
];
}
// Проверка является ли пользователь админом проекта
public static function isAdmin($project_id, $user_id): bool {
$project = Database::get('project', ['id_admin'], ['id' => $project_id]);
if (!$project || !$project['id_admin']) {
return false;
}
$admins = json_decode($project['id_admin'], true) ?: [];
return in_array((int)$user_id, $admins, true);
}
// ==================== CRUD ПРОЕКТОВ ====================
// Создание проекта с дефолтными колонками
public static function create($name, $user_id) {
// Получаем максимальный id_order
$maxOrder = Database::max('project', 'id_order') ?? 0;
// Создаём проект
Database::insert('project', [
'name' => $name,
'id_order' => $maxOrder + 1,
'id_admin' => json_encode([(int)$user_id]),
'id_member' => json_encode([])
]);
$projectId = Database::id();
if (!$projectId) {
return ['success' => false, 'errors' => ['project' => 'Ошибка создания проекта']];
}
// Создаём дефолтные колонки
Database::insert('columns', [
'name_columns' => 'К выполнению',
'color' => '#6366f1',
'id_project' => $projectId,
'id_order' => 1
]);
$firstColumnId = Database::id();
Database::insert('columns', [
'name_columns' => 'Готово',
'color' => '#22c55e',
'id_project' => $projectId,
'id_order' => 2
]);
$readyColumnId = Database::id();
// Устанавливаем id_ready
Database::update('project', ['id_ready' => $readyColumnId], ['id' => $projectId]);
return [
'success' => true,
'id' => $projectId,
'columns' => [
['id' => $firstColumnId, 'name_columns' => 'К выполнению', 'color' => '#6366f1', 'id_order' => 1],
['id' => $readyColumnId, 'name_columns' => 'Готово', 'color' => '#22c55e', 'id_order' => 2]
],
'id_ready' => $readyColumnId
];
}
// Обновление проекта
public static function update($id, $name, $user_id) {
// Проверяем права
if (!self::isAdmin($id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
Database::update('project', ['name' => $name], ['id' => $id]);
return ['success' => true];
}
// Удаление проекта (каскадно: колонки, задачи, комментарии, файлы)
public static function delete($id, $user_id) {
// Проверяем права
if (!self::isAdmin($id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на удаление']];
}
// Получаем все задачи проекта
$tasks = Database::select('cards_task', ['id'], ['id_project' => $id]);
$taskIds = array_column($tasks, 'id');
if (!empty($taskIds)) {
// Получаем все комментарии к задачам
$comments = Database::select('comments', ['id'], ['id_task' => $taskIds]);
// Удаляем файлы комментариев с диска
foreach ($comments as $comment) {
FileUpload::deleteFolder('comment', $comment['id']);
}
// Удаляем комментарии из БД
Database::delete('comments', ['id_task' => $taskIds]);
}
// Удаляем файлы задач с диска
foreach ($tasks as $task) {
FileUpload::deleteFolder('task', $task['id']);
}
// Удаляем задачи из БД
Database::delete('cards_task', ['id_project' => $id]);
// Удаляем колонки
Database::delete('columns', ['id_project' => $id]);
// Удаляем отделы проекта
Database::delete('departments', ['id_project' => $id]);
// Удаляем проект
Database::delete('project', ['id' => $id]);
return ['success' => true];
}
// Обновление порядка проектов
public static function updateOrder($ids, $user_id) {
foreach ($ids as $order => $id) {
Database::update('project', ['id_order' => $order + 1], ['id' => $id]);
}
return ['success' => true];
}
// ==================== CRUD КОЛОНОК ====================
// Добавление колонки
public static function addColumn($project_id, $name, $color, $user_id) {
// Проверяем права
if (!self::isAdmin($project_id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
// Получаем максимальный id_order для проекта
$maxOrder = Database::max('columns', 'id_order', ['id_project' => $project_id]) ?? 0;
Database::insert('columns', [
'name_columns' => $name,
'color' => $color ?: '#6366f1',
'id_project' => $project_id,
'id_order' => $maxOrder + 1
]);
$columnId = Database::id();
return [
'success' => true,
'id' => $columnId,
'column' => [
'id' => $columnId,
'name_columns' => $name,
'color' => $color ?: '#6366f1',
'id_order' => $maxOrder + 1
]
];
}
// Обновление колонки
public static function updateColumn($id, $name, $color, $user_id) {
// Получаем колонку для проверки проекта
$column = Database::get('columns', ['id_project'], ['id' => $id]);
if (!$column) {
return ['success' => false, 'errors' => ['column' => 'Колонка не найдена']];
}
// Проверяем права
if (!self::isAdmin($column['id_project'], $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
$updateData = [];
if ($name !== null) $updateData['name_columns'] = $name;
if ($color !== null) $updateData['color'] = $color;
if (!empty($updateData)) {
Database::update('columns', $updateData, ['id' => $id]);
}
return ['success' => true];
}
// Удаление колонки (возвращает количество задач для подтверждения)
public static function getColumnTasksCount($column_id) {
return Database::count('cards_task', ['column_id' => $column_id]);
}
// Удаление колонки с задачами
public static function deleteColumn($id, $user_id) {
// Получаем колонку для проверки проекта
$column = Database::get('columns', ['id_project', 'id_order'], ['id' => $id]);
if (!$column) {
return ['success' => false, 'errors' => ['column' => 'Колонка не найдена']];
}
// Проверяем права
if (!self::isAdmin($column['id_project'], $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на удаление']];
}
// Проверяем, не является ли это последней колонкой перед "Готово"
// Минимум должно быть 3 колонки (2 обычные + готово), чтобы можно было удалить
$columnsCount = Database::count('columns', ['id_project' => $column['id_project']]);
if ($columnsCount <= 2) {
return ['success' => false, 'errors' => ['column' => 'Нельзя удалить последнюю колонку перед финальной']];
}
// Проверяем, не является ли это последней (финальной) колонкой
$lastColumn = Database::get('columns', ['id'], [
'id_project' => $column['id_project'],
'ORDER' => ['id_order' => 'DESC'],
'LIMIT' => 1
]);
if ($lastColumn && (int)$lastColumn['id'] === (int)$id) {
return ['success' => false, 'errors' => ['column' => 'Нельзя удалить финальную колонку (последнюю)']];
}
// Получаем задачи колонки
$tasks = Database::select('cards_task', ['id'], ['column_id' => $id]);
$taskIds = array_column($tasks, 'id');
// Удаляем комментарии к задачам
if (!empty($taskIds)) {
Database::delete('comments', ['id_task' => $taskIds]);
}
// Удаляем задачи
Database::delete('cards_task', ['column_id' => $id]);
// Удаляем колонку
Database::delete('columns', ['id' => $id]);
// Обновляем id_ready на новую последнюю колонку
$newLastColumn = Database::get('columns', ['id'], [
'id_project' => $column['id_project'],
'ORDER' => ['id_order' => 'DESC'],
'LIMIT' => 1
]);
if ($newLastColumn) {
Database::update('project', ['id_ready' => $newLastColumn['id']], ['id' => $column['id_project']]);
}
return ['success' => true, 'deleted_tasks' => count($taskIds)];
}
// Обновление порядка колонок
public static function updateColumnsOrder($project_id, $ids, $user_id) {
// Проверяем права
if (!self::isAdmin($project_id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
foreach ($ids as $order => $id) {
Database::update('columns', ['id_order' => $order + 1], ['id' => $id, 'id_project' => $project_id]);
}
// Автоматически устанавливаем id_ready на последнюю колонку
$lastColumnId = end($ids);
if ($lastColumnId) {
Database::update('project', ['id_ready' => $lastColumnId], ['id' => $project_id]);
}
return ['success' => true];
}
// Установка финальной колонки (id_ready) - ЗАБЛОКИРОВАНО
// Финальная колонка всегда последняя, изменение запрещено
public static function setReadyColumn($project_id, $column_id, $user_id) {
return ['success' => false, 'errors' => ['column' => 'Изменение финальной колонки запрещено. Финальная колонка всегда последняя.']];
}
}
?>