1
0
Files
TaskBoard/backend/app/class/enity/class_project.php
Falknat 6928687982 Фиксы
Доп правки
2026-01-18 21:02:23 +07:00

478 lines
19 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();
if (!$current_user_id) {
return [];
}
// Получаем ID проектов где пользователь участник
$projectIds = ProjectAccess::getUserProjectIds($current_user_id);
if (empty($projectIds)) {
return [];
}
$projects = Database::select($this->db_name, [
'id',
'id_order',
'name',
'id_ready'
], [
'id' => $projectIds,
'ORDER' => ['id_order' => 'ASC']
]);
// Добавляем флаг is_admin для каждого проекта
return array_map(function($project) use ($current_user_id) {
$project['is_admin'] = ProjectAccess::isAdmin($project['id'], $current_user_id);
return $project;
}, $projects);
}
// Получение одного проекта
public static function get($id, $current_user_id = null) {
$project = Database::get('project', [
'id',
'id_order',
'name',
'id_ready'
], ['id' => $id]);
if ($project && $current_user_id) {
$project['is_admin'] = ProjectAccess::isAdmin($id, $current_user_id);
}
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',
'order_id'
], [
'id_project' => $project_id,
'ORDER' => ['order_id' => 'ASC']
]);
}
// Получение всех данных проекта (проект + колонки + отделы + метки)
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
];
}
// ==================== CRUD ПРОЕКТОВ ====================
// Создание проекта с дефолтными колонками
public static function create($name, $user_id) {
// Получаем максимальный id_order
$maxOrder = Database::max('project', 'id_order') ?? 0;
// Создаём проект с создателем как владельцем (id_admin)
Database::insert('project', [
'name' => $name,
'id_order' => $maxOrder + 1,
'id_admin' => json_encode([$user_id])
]);
$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,
'is_admin' => true
];
}
// Обновление проекта
public static function update($id, $name, $user_id) {
if (!ProjectAccess::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 (!ProjectAccess::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_members', ['id_project' => $id]);
// Удаляем приглашения в проект
Database::delete('project_invites', ['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 (!ProjectAccess::can($project_id, $user_id, 'create_column')) {
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 (!ProjectAccess::can($column['id_project'], $user_id, 'edit_column')) {
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 (!ProjectAccess::can($column['id_project'], $user_id, 'delete_column')) {
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 (!ProjectAccess::can($project_id, $user_id, 'edit_column')) {
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' => 'Изменение финальной колонки запрещено. Финальная колонка всегда последняя.']];
}
// ==================== CRUD ОТДЕЛОВ ====================
// Добавление отдела
public static function addDepartment($project_id, $name, $color, $user_id) {
if (!ProjectAccess::can($project_id, $user_id, 'manage_departments')) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на управление отделами']];
}
// Валидация имени
if (!$name || trim($name) === '') {
return ['success' => false, 'errors' => ['name' => 'Укажите название отдела']];
}
// Получаем максимальный order_id для проекта
$maxOrder = (int)(Database::max('departments', 'order_id', ['id_project' => $project_id]) ?? 0);
$newOrderId = $maxOrder + 1;
Database::insert('departments', [
'name_departments' => $name,
'color' => $color ?: '#6366f1',
'id_project' => $project_id,
'order_id' => $newOrderId
]);
$departmentId = Database::id();
return [
'success' => true,
'id' => $departmentId,
'department' => [
'id' => $departmentId,
'name_departments' => $name,
'color' => $color ?: '#6366f1',
'order_id' => $newOrderId
]
];
}
// Обновление отдела
public static function updateDepartment($id, $name, $color, $user_id) {
// Получаем отдел для проверки проекта
$department = Database::get('departments', ['id_project'], ['id' => $id]);
if (!$department) {
return ['success' => false, 'errors' => ['department' => 'Отдел не найден']];
}
if (!ProjectAccess::can($department['id_project'], $user_id, 'manage_departments')) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на управление отделами']];
}
// Валидация имени (если передано)
if ($name !== null && trim($name) === '') {
return ['success' => false, 'errors' => ['name' => 'Укажите название отдела']];
}
$updateData = [];
if ($name !== null) $updateData['name_departments'] = $name;
if ($color !== null) $updateData['color'] = $color;
if (!empty($updateData)) {
Database::update('departments', $updateData, ['id' => $id]);
}
return ['success' => true];
}
// Получение количества задач в отделе
public static function getDepartmentTasksCount($department_id) {
return Database::count('cards_task', ['id_department' => $department_id]);
}
// Удаление отдела (обнуляет id_department у задач)
public static function deleteDepartment($id, $user_id) {
// Получаем отдел для проверки проекта
$department = Database::get('departments', ['id_project'], ['id' => $id]);
if (!$department) {
return ['success' => false, 'errors' => ['department' => 'Отдел не найден']];
}
if (!ProjectAccess::can($department['id_project'], $user_id, 'manage_departments')) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на управление отделами']];
}
// Обнуляем id_department у задач (не удаляем сами задачи)
Database::update('cards_task', ['id_department' => null], ['id_department' => $id]);
// Удаляем отдел
Database::delete('departments', ['id' => $id]);
return ['success' => true];
}
// Обновление порядка отделов
public static function updateDepartmentsOrder($project_id, $ids, $user_id) {
if (!ProjectAccess::can($project_id, $user_id, 'manage_departments')) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на управление отделами']];
}
foreach ($ids as $order => $id) {
Database::update('departments', ['order_id' => $order + 1], ['id' => $id, 'id_project' => $project_id]);
}
return ['success' => true];
}
}
?>