/
Francuz
/
DailyPort
Обзор
Документация
Войти
/
Francuz
/
DailyPort
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/Task.php
197 строк
9 KB
Francuz
docs: подробные комментарии ко всем PHP-файлам проекта
15 июн 2026, 08:08
15 июн 2026, 08:08
594585d
Код
Авторство
О чём код?
<?php /** * Класс Task — модель задачи таск-менеджера. * * Задачи поддерживают древовидную структуру через поле parent_id: * - корневые задачи (parent_id = NULL) * - подзадачи (parent_id = ID родительской задачи) * * Каждая задача привязана к: * - странице (page_id) * - статусу (status_id) — определяет столбец на доске * * Дополнительные поля: * - title, description — название и описание * - deadline — срок выполнения * - created_by — кто создал * - assigned_to — ответственный * - sort_order — порядок в столбце */ class Task { private Database $db; public function __construct(Database $db) { $this->db = $db; } /** * Получить корневые задачи страницы (без подзадач). * * @param int $pageId ID страницы * @return array Корневые задачи, отсортированные по sort_order */ public function getByPage(int $pageId): array { $pageId = $this->db->escape((string)$pageId); $result = $this->db->query("SELECT * FROM tasks WHERE page_id = $pageId AND parent_id IS NULL ORDER BY sort_order ASC, id ASC"); return $result->fetch_all(MYSQLI_ASSOC); } /** * Получить подзадачи указанной задачи. * * @param int $parentId ID родительской задачи * @return array Подзадачи */ public function getChildren(int $parentId): array { $parentId = $this->db->escape((string)$parentId); $result = $this->db->query("SELECT * FROM tasks WHERE parent_id = $parentId ORDER BY sort_order ASC, id ASC"); return $result->fetch_all(MYSQLI_ASSOC); } /** * Получить ВСЕ задачи страницы (включая подзадачи). * * @param int $pageId ID страницы * @return array Все задачи */ public function getAllByPage(int $pageId): array { $pageId = $this->db->escape((string)$pageId); $result = $this->db->query("SELECT * FROM tasks WHERE page_id = $pageId ORDER BY sort_order ASC, id ASC"); return $result->fetch_all(MYSQLI_ASSOC); } /** Найти задачу по ID */ public function find(int $id): ?array { $id = $this->db->escape((string)$id); $result = $this->db->query("SELECT * FROM tasks WHERE id = $id"); return $result->fetch_assoc() ?: null; } /** * Создать новую задачу. * * @param int $pageId ID страницы * @param string $title Название задачи * @param int|null $parentId ID родительской задачи (null = корневая) * @param int|null $statusId ID статуса (null = первый доступный) * @param string|null $description Описание * @param string|null $deadline Дедлайн (формат: YYYY-MM-DD HH:MM:SS) * @param string|null $createdBy Кто создал * @param string|null $assignedTo Ответственный * @return int ID созданной задачи */ public function create(int $pageId, string $title, ?int $parentId = null, ?int $statusId = null, ?string $description = null, ?string $deadline = null, ?string $createdBy = null, ?string $assignedTo = null): int { $pageId = $this->db->escape((string)$pageId); $title = "'" . $this->db->escape($title) . "'"; $parentId = $parentId !== null ? $this->db->escape((string)$parentId) : 'NULL'; $description = $description !== null ? "'" . $this->db->escape($description) . "'" : 'NULL'; $deadline = $deadline !== null ? "'" . $this->db->escape($deadline) . "'" : 'NULL'; $createdBy = $createdBy !== null ? "'" . $this->db->escape($createdBy) . "'" : 'NULL'; $assignedTo = $assignedTo !== null ? "'" . $this->db->escape($assignedTo) . "'" : 'NULL'; // Если статус не указан, берём первый доступный для страницы if ($statusId === null) { $statusResult = $this->db->query("SELECT id FROM task_statuses WHERE page_id = $pageId ORDER BY sort_order ASC LIMIT 1"); $statusRow = $statusResult->fetch_assoc(); $statusId = $statusRow ? $this->db->escape((string)$statusRow['id']) : '1'; } else { $statusId = $this->db->escape((string)$statusId); } // Вычисляем порядок сортировки внутри родителя/страницы $maxOrder = $this->db->query("SELECT COALESCE(MAX(sort_order), 0) + 1 AS next_order FROM tasks WHERE page_id = $pageId AND parent_id " . ($parentId === 'NULL' ? 'IS NULL' : "= $parentId"))->fetch_assoc(); $order = $maxOrder['next_order']; $this->db->query("INSERT INTO tasks (page_id, parent_id, status_id, title, description, deadline, created_by, assigned_to, sort_order) VALUES ($pageId, $parentId, $statusId, $title, $description, $deadline, $createdBy, $assignedTo, $order)"); return (int)$this->db->query("SELECT LAST_INSERT_ID() AS id")->fetch_assoc()['id']; } /** * Обновить задачу (частичное обновление — только переданные поля). * * Поддерживаемые поля: title, description, status_id, deadline, assigned_to, parent_id * * @param int $id ID задачи * @param array $data Ассоциативный массив полей для обновления */ public function update(int $id, array $data): bool { $id = $this->db->escape((string)$id); $sets = []; if (array_key_exists('title', $data)) { $sets[] = "title = '" . $this->db->escape($data['title']) . "'"; } if (array_key_exists('description', $data)) { $val = $data['description']; $sets[] = $val === null ? "description = NULL" : "description = '" . $this->db->escape($val) . "'"; } if (array_key_exists('status_id', $data)) { $sets[] = "status_id = " . $this->db->escape((string)$data['status_id']); } if (array_key_exists('deadline', $data)) { $val = $data['deadline']; $sets[] = $val === null ? "deadline = NULL" : "deadline = '" . $this->db->escape($val) . "'"; } if (array_key_exists('assigned_to', $data)) { $val = $data['assigned_to']; $sets[] = $val === null ? "assigned_to = NULL" : "assigned_to = '" . $this->db->escape($val) . "'"; } if (array_key_exists('parent_id', $data)) { $val = $data['parent_id']; $sets[] = $val === null ? "parent_id = NULL" : "parent_id = " . $this->db->escape((string)$val); } if (empty($sets)) return false; $this->db->query("UPDATE tasks SET " . implode(', ', $sets) . " WHERE id = $id"); return true; } /** * Удалить задачу (подзадачи удаляются каскадно через FOREIGN KEY ON DELETE CASCADE). */ public function delete(int $id): bool { $id = $this->db->escape((string)$id); $this->db->query("DELETE FROM tasks WHERE id = $id"); return true; } /** * Обновить порядок сортировки задач в столбце. * * @param int $pageId ID страницы * @param array $orderedIds ID задач в новом порядке * @param int|null $parentId ID родителя (для подзадач) */ public function updateSortOrder(int $pageId, array $orderedIds, ?int $parentId = null): bool { $pageId = $this->db->escape((string)$pageId); foreach ($orderedIds as $position => $id) { $id = $this->db->escape((string)$id); $this->db->query("UPDATE tasks SET sort_order = $position WHERE id = $id AND page_id = $pageId"); } return true; } /** * Подсчитать количество подзадач. * * @param int $parentId ID родительской задачи * @return int Количество подзадач */ public function countChildren(int $parentId): int { $parentId = $this->db->escape((string)$parentId); $result = $this->db->query("SELECT COUNT(*) AS cnt FROM tasks WHERE parent_id = $parentId"); return (int)$result->fetch_assoc()['cnt']; } }