1
0
Files
TaskBoard/backend/app/class/enity/class_project.php
Falknat 190b4d0a5e Большое обновление
1. Создание личных проектов
2. Управление командой
3. Приглашение участников
4. Уведомления

и многое другое...
2026-01-18 20:17:02 +07:00

372 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();
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'
], [
'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
];
}
// ==================== 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' => 'Изменение финальной колонки запрещено. Финальная колонка всегда последняя.']];
}
}
?>