Большое обновление
1. Создание личных проектов 2. Управление командой 3. Приглашение участников 4. Уведомления и многое другое...
This commit is contained in:
@@ -104,7 +104,7 @@ class Comment extends BaseEntity {
|
||||
|
||||
// Проверяем права: автор комментария ИЛИ админ проекта
|
||||
$isAuthor = (int)$comment['id_accounts'] === (int)$id_accounts;
|
||||
$isProjectAdmin = $task && Project::isAdmin($task['id_project'], $id_accounts);
|
||||
$isProjectAdmin = $task && ProjectAccess::isAdmin($task['id_project'], $id_accounts);
|
||||
|
||||
if (!$isAuthor && !$isProjectAdmin) {
|
||||
RestApi::response([
|
||||
@@ -138,9 +138,26 @@ class Comment extends BaseEntity {
|
||||
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);
|
||||
@@ -156,7 +173,7 @@ class Comment extends BaseEntity {
|
||||
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);
|
||||
@@ -166,7 +183,7 @@ class Comment extends BaseEntity {
|
||||
|
||||
// Проверка прав: автор комментария ИЛИ админ проекта
|
||||
$isAuthor = (int)$comment['id_accounts'] === (int)$user_id;
|
||||
$isProjectAdmin = $task && Project::isAdmin($task['id_project'], $user_id);
|
||||
$isProjectAdmin = $task && ProjectAccess::isAdmin($task['id_project'], $user_id);
|
||||
|
||||
if (!$isAuthor && !$isProjectAdmin) {
|
||||
RestApi::response([
|
||||
|
||||
@@ -4,55 +4,49 @@ 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_admin'
|
||||
'id_ready'
|
||||
], [
|
||||
'id' => $projectIds,
|
||||
'ORDER' => ['id_order' => 'ASC']
|
||||
]);
|
||||
|
||||
// Обрабатываем id_admin для каждого проекта
|
||||
// Добавляем флаг is_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']);
|
||||
}
|
||||
|
||||
$project['is_admin'] = ProjectAccess::isAdmin($project['id'], $current_user_id);
|
||||
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_ready'
|
||||
], ['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']);
|
||||
}
|
||||
if ($project && $current_user_id) {
|
||||
$project['is_admin'] = ProjectAccess::isAdmin($id, $current_user_id);
|
||||
}
|
||||
|
||||
return $project;
|
||||
@@ -114,17 +108,6 @@ class Project extends BaseEntity {
|
||||
];
|
||||
}
|
||||
|
||||
// Проверка является ли пользователь админом проекта
|
||||
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 ПРОЕКТОВ ====================
|
||||
|
||||
// Создание проекта с дефолтными колонками
|
||||
@@ -132,12 +115,11 @@ class Project extends BaseEntity {
|
||||
// Получаем максимальный id_order
|
||||
$maxOrder = Database::max('project', 'id_order') ?? 0;
|
||||
|
||||
// Создаём проект
|
||||
// Создаём проект с создателем как владельцем (id_admin)
|
||||
Database::insert('project', [
|
||||
'name' => $name,
|
||||
'id_order' => $maxOrder + 1,
|
||||
'id_admin' => json_encode([(int)$user_id]),
|
||||
'id_member' => json_encode([])
|
||||
'id_admin' => json_encode([$user_id])
|
||||
]);
|
||||
|
||||
$projectId = Database::id();
|
||||
@@ -172,14 +154,14 @@ class Project extends BaseEntity {
|
||||
['id' => $firstColumnId, 'name_columns' => 'К выполнению', 'color' => '#6366f1', 'id_order' => 1],
|
||||
['id' => $readyColumnId, 'name_columns' => 'Готово', 'color' => '#22c55e', 'id_order' => 2]
|
||||
],
|
||||
'id_ready' => $readyColumnId
|
||||
'id_ready' => $readyColumnId,
|
||||
'is_admin' => true
|
||||
];
|
||||
}
|
||||
|
||||
// Обновление проекта
|
||||
public static function update($id, $name, $user_id) {
|
||||
// Проверяем права
|
||||
if (!self::isAdmin($id, $user_id)) {
|
||||
if (!ProjectAccess::isAdmin($id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
|
||||
}
|
||||
|
||||
@@ -189,8 +171,7 @@ class Project extends BaseEntity {
|
||||
|
||||
// Удаление проекта (каскадно: колонки, задачи, комментарии, файлы)
|
||||
public static function delete($id, $user_id) {
|
||||
// Проверяем права
|
||||
if (!self::isAdmin($id, $user_id)) {
|
||||
if (!ProjectAccess::isAdmin($id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на удаление']];
|
||||
}
|
||||
|
||||
@@ -225,6 +206,12 @@ class Project extends BaseEntity {
|
||||
// Удаляем отделы проекта
|
||||
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]);
|
||||
|
||||
@@ -243,9 +230,8 @@ class Project extends BaseEntity {
|
||||
|
||||
// Добавление колонки
|
||||
public static function addColumn($project_id, $name, $color, $user_id) {
|
||||
// Проверяем права
|
||||
if (!self::isAdmin($project_id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
|
||||
if (!ProjectAccess::can($project_id, $user_id, 'create_column')) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на создание колонок']];
|
||||
}
|
||||
|
||||
// Получаем максимальный id_order для проекта
|
||||
@@ -279,9 +265,8 @@ class Project extends BaseEntity {
|
||||
return ['success' => false, 'errors' => ['column' => 'Колонка не найдена']];
|
||||
}
|
||||
|
||||
// Проверяем права
|
||||
if (!self::isAdmin($column['id_project'], $user_id)) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
|
||||
if (!ProjectAccess::can($column['id_project'], $user_id, 'edit_column')) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование колонок']];
|
||||
}
|
||||
|
||||
$updateData = [];
|
||||
@@ -308,9 +293,8 @@ class Project extends BaseEntity {
|
||||
return ['success' => false, 'errors' => ['column' => 'Колонка не найдена']];
|
||||
}
|
||||
|
||||
// Проверяем права
|
||||
if (!self::isAdmin($column['id_project'], $user_id)) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на удаление']];
|
||||
if (!ProjectAccess::can($column['id_project'], $user_id, 'delete_column')) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на удаление колонок']];
|
||||
}
|
||||
|
||||
// Проверяем, не является ли это последней колонкой перед "Готово"
|
||||
@@ -360,9 +344,8 @@ class Project extends BaseEntity {
|
||||
|
||||
// Обновление порядка колонок
|
||||
public static function updateColumnsOrder($project_id, $ids, $user_id) {
|
||||
// Проверяем права
|
||||
if (!self::isAdmin($project_id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
|
||||
if (!ProjectAccess::can($project_id, $user_id, 'edit_column')) {
|
||||
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование колонок']];
|
||||
}
|
||||
|
||||
foreach ($ids as $order => $id) {
|
||||
|
||||
540
backend/app/class/enity/class_projectAccess.php
Normal file
540
backend/app/class/enity/class_projectAccess.php
Normal file
@@ -0,0 +1,540 @@
|
||||
<?php
|
||||
|
||||
class ProjectAccess {
|
||||
|
||||
// Список всех доступных прав
|
||||
const PERMISSIONS = [
|
||||
'create_task', // создание задач
|
||||
'edit_task', // редактирование любых задач
|
||||
'edit_own_task_only', // редактирование только назначенных на себя
|
||||
'delete_task', // удаление задач
|
||||
'move_task', // перемещение любых задач между колонками
|
||||
'move_own_task_only', // перемещение только назначенных на себя
|
||||
'archive_task', // архивирование задач
|
||||
'create_column', // создание колонок
|
||||
'edit_column', // редактирование колонок
|
||||
'delete_column', // удаление колонок
|
||||
'manage_departments', // управление отделами
|
||||
'remove_members', // удаление участников (приглашать/редактировать могут только админы)
|
||||
'create_comment', // создание комментариев в любых задачах
|
||||
'create_comment_own_task_only', // создание комментариев только в назначенных на себя
|
||||
'delete_own_comments', // удаление своих комментариев
|
||||
'delete_all_comments', // удаление любых комментариев в проекте
|
||||
'upload_files', // загрузка файлов
|
||||
'upload_images' // загрузка картинок
|
||||
];
|
||||
|
||||
// Права по умолчанию для нового участника
|
||||
const DEFAULT_PERMISSIONS = [
|
||||
'create_task' => true, // создание задач
|
||||
'edit_task' => false, // редактирование любых задач
|
||||
'edit_own_task_only' => true, // редактирование только назначенных на себя
|
||||
'delete_task' => false, // удаление задач
|
||||
'move_task' => false, // перемещение любых задач между колонками
|
||||
'move_own_task_only' => true, // перемещение только назначенных на себя
|
||||
'archive_task' => true, // архивирование задач
|
||||
'create_column' => false, // создание колонок
|
||||
'edit_column' => false, // редактирование колонок
|
||||
'delete_column' => false, // удаление колонок
|
||||
'manage_departments' => false, // управление отделами
|
||||
'remove_members' => false, // удаление участников
|
||||
'create_comment' => false, // создание комментариев в любых задачах
|
||||
'create_comment_own_task_only' => true, // создание комментариев только в назначенных на себя
|
||||
'delete_own_comments' => true, // удаление своих комментариев
|
||||
'delete_all_comments' => false, // удаление любых комментариев
|
||||
'upload_files' => true, // загрузка файлов
|
||||
'upload_images' => true // загрузка картинок
|
||||
];
|
||||
|
||||
// ==================== ПРОВЕРКИ ДОСТУПА ====================
|
||||
|
||||
// Проверить, является ли пользователь владельцем проекта (в id_admin таблицы projects)
|
||||
public static function isOwner(int $project_id, int $user_id): bool {
|
||||
$project = Database::get('project', ['id_admin'], ['id' => $project_id]);
|
||||
if (!$project || !$project['id_admin']) {
|
||||
return false;
|
||||
}
|
||||
$owners = json_decode($project['id_admin'], true);
|
||||
return is_array($owners) && in_array($user_id, $owners);
|
||||
}
|
||||
|
||||
// Проверить, является ли пользователь участником проекта
|
||||
public static function isMember(int $project_id, int $user_id): bool {
|
||||
// Владелец всегда имеет доступ
|
||||
if (self::isOwner($project_id, $user_id)) {
|
||||
return true;
|
||||
}
|
||||
return Database::has('project_members', [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
}
|
||||
|
||||
// Проверить, является ли пользователь админом проекта
|
||||
public static function isAdmin(int $project_id, int $user_id): bool {
|
||||
// Владелец = безоговорочный админ
|
||||
if (self::isOwner($project_id, $user_id)) {
|
||||
return true;
|
||||
}
|
||||
return Database::has('project_members', [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id,
|
||||
'is_admin' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
// Проверить конкретное право (владелец/админ имеет все права)
|
||||
public static function can(int $project_id, int $user_id, string $permission): bool {
|
||||
// Владелец может всё
|
||||
if (self::isOwner($project_id, $user_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$member = Database::get('project_members', ['is_admin', 'permissions'], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
if (!$member) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Админ может всё
|
||||
if ((int)$member['is_admin'] === 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$permissions = $member['permissions'] ? json_decode($member['permissions'], true) : [];
|
||||
return isset($permissions[$permission]) && $permissions[$permission] === true;
|
||||
}
|
||||
|
||||
// Проверить право на редактирование задачи (с учётом edit_own_task_only)
|
||||
// "Своя задача" = назначен на пользователя ИЛИ создана пользователем
|
||||
public static function canEditTask(int $project_id, int $user_id, ?int $task_assignee_id, ?int $task_creator_id = null): bool {
|
||||
if (self::isAdmin($project_id, $user_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self::can($project_id, $user_id, 'edit_task')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Создатель + право создания → может редактировать свои созданные
|
||||
if ($task_creator_id === $user_id && self::can($project_id, $user_id, 'create_task')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Назначена на себя + право edit_own_task_only
|
||||
if ($task_assignee_id === $user_id && self::can($project_id, $user_id, 'edit_own_task_only')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверить право на перемещение задачи (с учётом move_own_task_only)
|
||||
// "Своя задача" = назначен на пользователя ИЛИ создана пользователем
|
||||
public static function canMoveTask(int $project_id, int $user_id, ?int $task_assignee_id, ?int $task_creator_id = null): bool {
|
||||
if (self::isAdmin($project_id, $user_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self::can($project_id, $user_id, 'move_task')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Создатель + право создания → может перемещать свои созданные
|
||||
if ($task_creator_id === $user_id && self::can($project_id, $user_id, 'create_task')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Назначена на себя + право move_own_task_only
|
||||
if ($task_assignee_id === $user_id && self::can($project_id, $user_id, 'move_own_task_only')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверить право на создание комментария в задаче
|
||||
public static function canCreateComment(int $project_id, int $user_id, ?int $task_assignee_id, ?int $task_creator_id = null): bool {
|
||||
if (self::isAdmin($project_id, $user_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Полное право — комментировать любые задачи
|
||||
if (self::can($project_id, $user_id, 'create_comment')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Создатель + право создания → может комментировать свои созданные
|
||||
if ($task_creator_id === $user_id && self::can($project_id, $user_id, 'create_task')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Назначена на себя + право create_comment_own_task_only
|
||||
if ($task_assignee_id === $user_id && self::can($project_id, $user_id, 'create_comment_own_task_only')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ==================== ПРОВЕРКИ С EXIT ====================
|
||||
|
||||
// Требовать доступ к проекту (при отказе — 403 и exit)
|
||||
public static function requireAccess(int $project_id, ?int $user_id): void {
|
||||
if (!$user_id) {
|
||||
RestApi::response(['success' => false, 'errors' => ['auth' => 'Требуется авторизация']], 401);
|
||||
}
|
||||
|
||||
if (!self::isMember($project_id, $user_id)) {
|
||||
RestApi::response(['success' => false, 'errors' => ['access' => 'Нет доступа к проекту']], 403);
|
||||
}
|
||||
}
|
||||
|
||||
// Требовать права админа
|
||||
public static function requireAdmin(int $project_id, ?int $user_id): void {
|
||||
if (!$user_id) {
|
||||
RestApi::response(['success' => false, 'errors' => ['auth' => 'Требуется авторизация']], 401);
|
||||
}
|
||||
|
||||
if (!self::isAdmin($project_id, $user_id)) {
|
||||
RestApi::response(['success' => false, 'errors' => ['access' => 'Требуются права администратора']], 403);
|
||||
}
|
||||
}
|
||||
|
||||
// Требовать конкретное право
|
||||
public static function requirePermission(int $project_id, ?int $user_id, string $permission): void {
|
||||
if (!$user_id) {
|
||||
RestApi::response(['success' => false, 'errors' => ['auth' => 'Требуется авторизация']], 401);
|
||||
}
|
||||
|
||||
if (!self::can($project_id, $user_id, $permission)) {
|
||||
RestApi::response(['success' => false, 'errors' => ['access' => 'Недостаточно прав']], 403);
|
||||
}
|
||||
}
|
||||
|
||||
// Требовать право на редактирование задачи
|
||||
public static function requireEditTask(int $project_id, ?int $user_id, ?int $task_assignee_id, ?int $task_creator_id = null): void {
|
||||
if (!$user_id) {
|
||||
RestApi::response(['success' => false, 'errors' => ['auth' => 'Требуется авторизация']], 401);
|
||||
}
|
||||
|
||||
if (!self::canEditTask($project_id, $user_id, $task_assignee_id, $task_creator_id)) {
|
||||
RestApi::response(['success' => false, 'errors' => ['access' => 'Нет прав на редактирование задачи']], 403);
|
||||
}
|
||||
}
|
||||
|
||||
// Требовать право на перемещение задачи
|
||||
public static function requireMoveTask(int $project_id, ?int $user_id, ?int $task_assignee_id, ?int $task_creator_id = null): void {
|
||||
if (!$user_id) {
|
||||
RestApi::response(['success' => false, 'errors' => ['auth' => 'Требуется авторизация']], 401);
|
||||
}
|
||||
|
||||
if (!self::canMoveTask($project_id, $user_id, $task_assignee_id, $task_creator_id)) {
|
||||
RestApi::response(['success' => false, 'errors' => ['access' => 'Нет прав на перемещение задачи']], 403);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== УПРАВЛЕНИЕ УЧАСТНИКАМИ ====================
|
||||
|
||||
// Добавить участника в проект
|
||||
public static function addMember(int $project_id, int $user_id, int $current_user_id, bool $is_admin = false, ?array $permissions = null): array {
|
||||
// Нельзя пригласить себя
|
||||
if ($user_id === $current_user_id) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Нельзя пригласить себя в проект']];
|
||||
}
|
||||
|
||||
if (self::isMember($project_id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Пользователь уже участник проекта']];
|
||||
}
|
||||
|
||||
$perms = $permissions ?? self::DEFAULT_PERMISSIONS;
|
||||
|
||||
Database::insert('project_members', [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id,
|
||||
'is_admin' => $is_admin ? 1 : 0,
|
||||
'permissions' => json_encode($perms),
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return ['success' => true, 'id' => Database::id()];
|
||||
}
|
||||
|
||||
// Удалить участника из проекта (владельца удалить нельзя, админ не может удалить себя)
|
||||
public static function removeMember(int $project_id, int $user_id, int $current_user_id): array {
|
||||
// Владельца удалить нельзя
|
||||
if (self::isOwner($project_id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Нельзя удалить владельца проекта']];
|
||||
}
|
||||
|
||||
$member = Database::get('project_members', ['is_admin'], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
if (!$member) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Участник не найден']];
|
||||
}
|
||||
|
||||
// Админ может выйти сам, если есть другие админы или владелец
|
||||
// (владелец всегда есть в id_admin проекта, так что это безопасно)
|
||||
|
||||
Database::delete('project_members', [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
// Получить всех участников проекта (включая владельцев из id_admin)
|
||||
public static function getMembers(int $project_id): array {
|
||||
$result = [];
|
||||
$addedUserIds = [];
|
||||
|
||||
// Получаем владельцев из id_admin проекта
|
||||
$project = Database::get('project', ['id_admin'], ['id' => $project_id]);
|
||||
if ($project && $project['id_admin']) {
|
||||
$ownerIds = json_decode($project['id_admin'], true);
|
||||
if (is_array($ownerIds) && count($ownerIds) > 0) {
|
||||
$owners = Database::select('accounts', ['id', 'name', 'username', 'avatar_url', 'telegram'], ['id' => $ownerIds]);
|
||||
foreach ($owners as $owner) {
|
||||
$result[] = [
|
||||
'id' => null,
|
||||
'id_user' => (int)$owner['id'],
|
||||
'is_admin' => true,
|
||||
'is_owner' => true,
|
||||
'permissions' => [],
|
||||
'created_at' => null,
|
||||
'name' => $owner['name'],
|
||||
'username' => $owner['username'],
|
||||
'avatar_url' => $owner['avatar_url'],
|
||||
'telegram' => $owner['telegram']
|
||||
];
|
||||
$addedUserIds[] = (int)$owner['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Получаем участников из project_members
|
||||
$members = Database::select('project_members', [
|
||||
'[>]accounts' => ['id_user' => 'id']
|
||||
], [
|
||||
'project_members.id',
|
||||
'project_members.id_user',
|
||||
'project_members.is_admin',
|
||||
'project_members.permissions',
|
||||
'project_members.created_at',
|
||||
'accounts.name',
|
||||
'accounts.username',
|
||||
'accounts.avatar_url',
|
||||
'accounts.telegram'
|
||||
], [
|
||||
'project_members.id_project' => $project_id
|
||||
]);
|
||||
|
||||
foreach ($members as $member) {
|
||||
$userId = (int)$member['id_user'];
|
||||
// Пропускаем если уже добавлен как владелец
|
||||
if (in_array($userId, $addedUserIds)) {
|
||||
continue;
|
||||
}
|
||||
$result[] = [
|
||||
'id' => $member['id'],
|
||||
'id_user' => $userId,
|
||||
'is_admin' => (int)$member['is_admin'] === 1,
|
||||
'is_owner' => false,
|
||||
'permissions' => $member['permissions'] ? json_decode($member['permissions'], true) : [],
|
||||
'created_at' => $member['created_at'],
|
||||
'name' => $member['name'],
|
||||
'username' => $member['username'],
|
||||
'avatar_url' => $member['avatar_url'],
|
||||
'telegram' => $member['telegram']
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Получить ID всех проектов пользователя (включая где он владелец)
|
||||
public static function getUserProjectIds(int $user_id): array {
|
||||
$projectIds = [];
|
||||
|
||||
// Проекты из project_members
|
||||
$rows = Database::select('project_members', ['id_project'], [
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
foreach ($rows as $row) {
|
||||
$projectIds[] = (int)$row['id_project'];
|
||||
}
|
||||
|
||||
// Проекты где пользователь в id_admin
|
||||
$allProjects = Database::select('project', ['id', 'id_admin']);
|
||||
foreach ($allProjects as $project) {
|
||||
if ($project['id_admin']) {
|
||||
$owners = json_decode($project['id_admin'], true);
|
||||
if (is_array($owners) && in_array($user_id, $owners)) {
|
||||
$pid = (int)$project['id'];
|
||||
if (!in_array($pid, $projectIds)) {
|
||||
$projectIds[] = $pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $projectIds;
|
||||
}
|
||||
|
||||
// ==================== УПРАВЛЕНИЕ ПРАВАМИ ====================
|
||||
|
||||
// Установить конкретное право
|
||||
public static function setPermission(int $project_id, int $user_id, string $permission, bool $value, int $current_user_id): array {
|
||||
// Нельзя редактировать свои права
|
||||
if ($user_id === $current_user_id) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Нельзя изменять свои права']];
|
||||
}
|
||||
|
||||
if (!in_array($permission, self::PERMISSIONS)) {
|
||||
return ['success' => false, 'errors' => ['permission' => 'Неизвестное право: ' . $permission]];
|
||||
}
|
||||
|
||||
$member = Database::get('project_members', ['permissions'], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
if (!$member) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Участник не найден']];
|
||||
}
|
||||
|
||||
$permissions = $member['permissions'] ? json_decode($member['permissions'], true) : [];
|
||||
$permissions[$permission] = $value;
|
||||
|
||||
Database::update('project_members', [
|
||||
'permissions' => json_encode($permissions)
|
||||
], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
return ['success' => true, 'permissions' => $permissions];
|
||||
}
|
||||
|
||||
// Установить несколько прав сразу
|
||||
public static function setPermissions(int $project_id, int $user_id, array $permissions, int $current_user_id): array {
|
||||
// Нельзя редактировать свои права
|
||||
if ($user_id === $current_user_id) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Нельзя изменять свои права']];
|
||||
}
|
||||
|
||||
// Нельзя редактировать права владельца
|
||||
if (self::isOwner($project_id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Нельзя изменять права владельца проекта']];
|
||||
}
|
||||
|
||||
foreach (array_keys($permissions) as $perm) {
|
||||
if (!in_array($perm, self::PERMISSIONS)) {
|
||||
return ['success' => false, 'errors' => ['permission' => 'Неизвестное право: ' . $perm]];
|
||||
}
|
||||
}
|
||||
|
||||
$member = Database::get('project_members', ['permissions'], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
if (!$member) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Участник не найден']];
|
||||
}
|
||||
|
||||
$currentPerms = $member['permissions'] ? json_decode($member['permissions'], true) : [];
|
||||
$mergedPerms = array_merge($currentPerms, $permissions);
|
||||
|
||||
Database::update('project_members', [
|
||||
'permissions' => json_encode($mergedPerms)
|
||||
], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
return ['success' => true, 'permissions' => $mergedPerms];
|
||||
}
|
||||
|
||||
// Получить права участника
|
||||
public static function getPermissions(int $project_id, int $user_id): ?array {
|
||||
// Владелец имеет все права
|
||||
if (self::isOwner($project_id, $user_id)) {
|
||||
$allPerms = [];
|
||||
foreach (self::PERMISSIONS as $perm) {
|
||||
$allPerms[$perm] = true;
|
||||
}
|
||||
return $allPerms;
|
||||
}
|
||||
|
||||
$member = Database::get('project_members', ['is_admin', 'permissions'], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
if (!$member) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Админ имеет все права
|
||||
if ((int)$member['is_admin'] === 1) {
|
||||
$allPerms = [];
|
||||
foreach (self::PERMISSIONS as $perm) {
|
||||
$allPerms[$perm] = true;
|
||||
}
|
||||
return $allPerms;
|
||||
}
|
||||
|
||||
return $member['permissions'] ? json_decode($member['permissions'], true) : [];
|
||||
}
|
||||
|
||||
// Назначить/снять админа
|
||||
public static function setAdmin(int $project_id, int $user_id, bool $is_admin, int $current_user_id): array {
|
||||
// Нельзя редактировать свои права
|
||||
if ($user_id === $current_user_id) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Нельзя изменять свои права']];
|
||||
}
|
||||
|
||||
// Нельзя изменять статус владельца
|
||||
if (self::isOwner($project_id, $user_id)) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Нельзя изменять статус владельца проекта']];
|
||||
}
|
||||
|
||||
$member = Database::get('project_members', ['id'], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
if (!$member) {
|
||||
return ['success' => false, 'errors' => ['member' => 'Участник не найден']];
|
||||
}
|
||||
|
||||
Database::update('project_members', [
|
||||
'is_admin' => $is_admin ? 1 : 0
|
||||
], [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id
|
||||
]);
|
||||
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
// Получить список всех доступных прав (для UI)
|
||||
public static function getAvailablePermissions(): array {
|
||||
return self::PERMISSIONS;
|
||||
}
|
||||
|
||||
// Получить дефолтные права (для UI)
|
||||
public static function getDefaultPermissions(): array {
|
||||
return self::DEFAULT_PERMISSIONS;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
237
backend/app/class/enity/class_projectInvite.php
Normal file
237
backend/app/class/enity/class_projectInvite.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
class ProjectInvite {
|
||||
|
||||
const STATUS_PENDING = 'pending';
|
||||
const STATUS_ACCEPTED = 'accepted';
|
||||
const STATUS_DECLINED = 'declined';
|
||||
|
||||
// ==================== СОЗДАНИЕ ПРИГЛАШЕНИЯ ====================
|
||||
|
||||
/**
|
||||
* Создать приглашение в проект
|
||||
*/
|
||||
public static function create(int $project_id, int $to_user_id, int $from_user_id, bool $is_admin = false, ?array $permissions = null): array {
|
||||
// Нельзя пригласить себя
|
||||
if ($to_user_id === $from_user_id) {
|
||||
return ['success' => false, 'errors' => ['invite' => 'Нельзя пригласить себя в проект']];
|
||||
}
|
||||
|
||||
// Проверяем, что пользователь существует
|
||||
$user = Database::get('accounts', ['id'], ['id' => $to_user_id]);
|
||||
if (!$user) {
|
||||
return ['success' => false, 'errors' => ['invite' => 'Пользователь не найден']];
|
||||
}
|
||||
|
||||
// Проверяем, что пользователь ещё не участник проекта
|
||||
if (ProjectAccess::isMember($project_id, $to_user_id)) {
|
||||
return ['success' => false, 'errors' => ['invite' => 'Пользователь уже участник проекта']];
|
||||
}
|
||||
|
||||
// Проверяем, нет ли уже pending-приглашения
|
||||
if (self::hasPending($project_id, $to_user_id)) {
|
||||
return ['success' => false, 'errors' => ['invite' => 'Пользователь уже приглашён, ожидается ответ']];
|
||||
}
|
||||
|
||||
// Права по умолчанию
|
||||
$perms = $permissions ?? ProjectAccess::DEFAULT_PERMISSIONS;
|
||||
|
||||
// Сохраняем is_admin в permissions для передачи при accept
|
||||
$inviteData = [
|
||||
'is_admin' => $is_admin,
|
||||
'permissions' => $perms
|
||||
];
|
||||
|
||||
Database::insert('project_invites', [
|
||||
'id_project' => $project_id,
|
||||
'id_from_user' => $from_user_id,
|
||||
'id_to_user' => $to_user_id,
|
||||
'status' => self::STATUS_PENDING,
|
||||
'permissions' => json_encode($inviteData),
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return ['success' => true, 'id' => Database::id()];
|
||||
}
|
||||
|
||||
// ==================== ПРОВЕРКИ ====================
|
||||
|
||||
/**
|
||||
* Есть ли pending-приглашение для пользователя в проект
|
||||
*/
|
||||
public static function hasPending(int $project_id, int $to_user_id): bool {
|
||||
return Database::has('project_invites', [
|
||||
'id_project' => $project_id,
|
||||
'id_to_user' => $to_user_id,
|
||||
'status' => self::STATUS_PENDING
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить количество pending-приглашений для пользователя
|
||||
*/
|
||||
public static function getPendingCount(int $user_id): int {
|
||||
return Database::count('project_invites', [
|
||||
'id_to_user' => $user_id,
|
||||
'status' => self::STATUS_PENDING
|
||||
]);
|
||||
}
|
||||
|
||||
// ==================== ПОЛУЧЕНИЕ ПРИГЛАШЕНИЙ ====================
|
||||
|
||||
/**
|
||||
* Получить все pending-приглашения для пользователя (входящие)
|
||||
*/
|
||||
public static function getMyPending(int $user_id): array {
|
||||
$invites = Database::select('project_invites', [
|
||||
'[>]project' => ['id_project' => 'id'],
|
||||
'[>]accounts' => ['id_from_user' => 'id']
|
||||
], [
|
||||
'project_invites.id',
|
||||
'project_invites.id_project',
|
||||
'project_invites.created_at',
|
||||
'project_invites.permissions',
|
||||
'project.name(project_name)',
|
||||
'accounts.name(from_user_name)',
|
||||
'accounts.username(from_user_username)',
|
||||
'accounts.avatar_url(from_user_avatar)'
|
||||
], [
|
||||
'project_invites.id_to_user' => $user_id,
|
||||
'project_invites.status' => self::STATUS_PENDING,
|
||||
'ORDER' => ['project_invites.created_at' => 'DESC']
|
||||
]);
|
||||
|
||||
return array_map(function($invite) {
|
||||
$permData = $invite['permissions'] ? json_decode($invite['permissions'], true) : [];
|
||||
return [
|
||||
'id' => (int)$invite['id'],
|
||||
'project_id' => (int)$invite['id_project'],
|
||||
'project_name' => $invite['project_name'],
|
||||
'from_user' => [
|
||||
'name' => $invite['from_user_name'],
|
||||
'username' => $invite['from_user_username'],
|
||||
'avatar_url' => $invite['from_user_avatar']
|
||||
],
|
||||
'is_admin' => $permData['is_admin'] ?? false,
|
||||
'created_at' => $invite['created_at']
|
||||
];
|
||||
}, $invites);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить pending-приглашения для проекта (для админа)
|
||||
*/
|
||||
public static function getProjectPending(int $project_id): array {
|
||||
$invites = Database::select('project_invites', [
|
||||
'[>]accounts' => ['id_to_user' => 'id']
|
||||
], [
|
||||
'project_invites.id',
|
||||
'project_invites.id_to_user',
|
||||
'project_invites.created_at',
|
||||
'project_invites.permissions',
|
||||
'accounts.name',
|
||||
'accounts.username',
|
||||
'accounts.avatar_url'
|
||||
], [
|
||||
'project_invites.id_project' => $project_id,
|
||||
'project_invites.status' => self::STATUS_PENDING,
|
||||
'ORDER' => ['project_invites.created_at' => 'DESC']
|
||||
]);
|
||||
|
||||
return array_map(function($invite) {
|
||||
$permData = $invite['permissions'] ? json_decode($invite['permissions'], true) : [];
|
||||
return [
|
||||
'id' => (int)$invite['id'],
|
||||
'id_user' => (int)$invite['id_to_user'],
|
||||
'name' => $invite['name'],
|
||||
'username' => $invite['username'],
|
||||
'avatar_url' => $invite['avatar_url'],
|
||||
'is_admin' => $permData['is_admin'] ?? false,
|
||||
'created_at' => $invite['created_at'],
|
||||
'status' => 'pending'
|
||||
];
|
||||
}, $invites);
|
||||
}
|
||||
|
||||
// ==================== ОТВЕТ НА ПРИГЛАШЕНИЕ ====================
|
||||
|
||||
/**
|
||||
* Принять приглашение
|
||||
*/
|
||||
public static function accept(int $invite_id, int $user_id): array {
|
||||
$invite = Database::get('project_invites', '*', [
|
||||
'id' => $invite_id,
|
||||
'id_to_user' => $user_id,
|
||||
'status' => self::STATUS_PENDING
|
||||
]);
|
||||
|
||||
if (!$invite) {
|
||||
return ['success' => false, 'errors' => ['invite' => 'Приглашение не найдено или уже обработано']];
|
||||
}
|
||||
|
||||
$project_id = (int)$invite['id_project'];
|
||||
$permData = $invite['permissions'] ? json_decode($invite['permissions'], true) : [];
|
||||
$is_admin = $permData['is_admin'] ?? false;
|
||||
$permissions = $permData['permissions'] ?? ProjectAccess::DEFAULT_PERMISSIONS;
|
||||
|
||||
// Добавляем в project_members
|
||||
Database::insert('project_members', [
|
||||
'id_project' => $project_id,
|
||||
'id_user' => $user_id,
|
||||
'is_admin' => $is_admin ? 1 : 0,
|
||||
'permissions' => json_encode($permissions),
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
// Обновляем статус приглашения
|
||||
Database::update('project_invites', [
|
||||
'status' => self::STATUS_ACCEPTED,
|
||||
'responded_at' => date('Y-m-d H:i:s')
|
||||
], ['id' => $invite_id]);
|
||||
|
||||
return ['success' => true, 'project_id' => $project_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Отклонить приглашение
|
||||
*/
|
||||
public static function decline(int $invite_id, int $user_id): array {
|
||||
$invite = Database::get('project_invites', ['id'], [
|
||||
'id' => $invite_id,
|
||||
'id_to_user' => $user_id,
|
||||
'status' => self::STATUS_PENDING
|
||||
]);
|
||||
|
||||
if (!$invite) {
|
||||
return ['success' => false, 'errors' => ['invite' => 'Приглашение не найдено или уже обработано']];
|
||||
}
|
||||
|
||||
Database::update('project_invites', [
|
||||
'status' => self::STATUS_DECLINED,
|
||||
'responded_at' => date('Y-m-d H:i:s')
|
||||
], ['id' => $invite_id]);
|
||||
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* Отменить приглашение (для админа)
|
||||
*/
|
||||
public static function cancel(int $invite_id, int $project_id): array {
|
||||
$invite = Database::get('project_invites', ['id'], [
|
||||
'id' => $invite_id,
|
||||
'id_project' => $project_id,
|
||||
'status' => self::STATUS_PENDING
|
||||
]);
|
||||
|
||||
if (!$invite) {
|
||||
return ['success' => false, 'errors' => ['invite' => 'Приглашение не найдено']];
|
||||
}
|
||||
|
||||
Database::delete('project_invites', ['id' => $invite_id]);
|
||||
|
||||
return ['success' => true];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -14,6 +14,7 @@ class Task extends BaseEntity {
|
||||
public $date;
|
||||
public $date_closed;
|
||||
public $id_account;
|
||||
public $create_id_account; // ID создателя задачи
|
||||
public $title;
|
||||
public $descript;
|
||||
public $descript_full;
|
||||
@@ -69,6 +70,7 @@ class Task extends BaseEntity {
|
||||
'column_id' => $this->column_id,
|
||||
'date' => $this->date ?: null,
|
||||
'id_account' => $this->id_account,
|
||||
'create_id_account' => $this->create_id_account,
|
||||
'title' => $this->title,
|
||||
'descript' => $this->descript ?: null,
|
||||
'descript_full' => $this->descript_full ?: null,
|
||||
@@ -255,6 +257,7 @@ class Task extends BaseEntity {
|
||||
'id_department',
|
||||
'id_label',
|
||||
'id_account',
|
||||
'create_id_account',
|
||||
'order',
|
||||
'column_id',
|
||||
'date',
|
||||
|
||||
@@ -16,27 +16,69 @@ class Account extends BaseEntity {
|
||||
|
||||
// Валидация данных при создании аккаунта
|
||||
protected function validate() {
|
||||
$this->error_message = [];
|
||||
static::$error_message = [];
|
||||
|
||||
// === ИМЯ ===
|
||||
if (!$this->name) {
|
||||
$this->addError('name', 'Имя не может быть пустым');
|
||||
} elseif (mb_strlen($this->name) < 2) {
|
||||
$this->addError('name', 'Имя слишком короткое');
|
||||
} elseif (mb_strlen($this->name) > 50) {
|
||||
$this->addError('name', 'Имя слишком длинное');
|
||||
} elseif (!preg_match('/^[\p{L}\s\-]+$/u', $this->name)) {
|
||||
// Только буквы (любого языка), пробелы и дефис
|
||||
$this->addError('name', 'Имя может содержать только буквы');
|
||||
}
|
||||
|
||||
// === ЛОГИН ===
|
||||
if (!$this->username) {
|
||||
$this->addError('username', 'Логин не может быть пустым');
|
||||
} elseif (strlen($this->username) < 3) {
|
||||
$this->addError('username', 'Логин минимум 3 символа');
|
||||
} elseif (strlen($this->username) > 32) {
|
||||
$this->addError('username', 'Логин максимум 32 символа');
|
||||
} elseif (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $this->username)) {
|
||||
// Начинается с буквы, далее a-z, 0-9, _
|
||||
$this->addError('username', 'Логин: латиница, цифры и _ (начинается с буквы)');
|
||||
} elseif (Database::get($this->db_name, ['id'], ['username' => $this->username])) {
|
||||
$this->addError('username', 'Этот логин уже занят');
|
||||
}
|
||||
if ($this->username && Database::get($this->db_name, ['id'], ['username' => $this->username])) {
|
||||
$this->addError('username', 'Пользователь с таким логином уже существует');
|
||||
}
|
||||
|
||||
// === ПАРОЛЬ ===
|
||||
if (!$this->password) {
|
||||
$this->addError('password', 'Пароль не может быть пустым');
|
||||
} elseif (strlen($this->password) < 6) {
|
||||
$this->addError('password', 'Пароль минимум 6 символов');
|
||||
} elseif (strlen($this->password) > 100) {
|
||||
$this->addError('password', 'Пароль слишком длинный');
|
||||
}
|
||||
|
||||
return $this->getErrors();
|
||||
}
|
||||
|
||||
// Очистка данных перед сохранением
|
||||
protected function sanitize() {
|
||||
// Имя: убираем лишние пробелы
|
||||
$this->name = trim(preg_replace('/\s+/', ' ', $this->name));
|
||||
|
||||
// Логин: только допустимые символы (регистр сохраняется)
|
||||
$this->username = preg_replace('/[^a-zA-Z0-9_]/', '', $this->username);
|
||||
|
||||
// Telegram: убираем @, только допустимые символы
|
||||
if ($this->telegram) {
|
||||
$this->telegram = str_replace('@', '', $this->telegram);
|
||||
$this->telegram = preg_replace('/[^a-zA-Z0-9_]/', '', $this->telegram);
|
||||
$this->telegram = strtolower($this->telegram);
|
||||
$this->telegram = $this->telegram ?: null;
|
||||
}
|
||||
}
|
||||
|
||||
// Создание нового аккаунта
|
||||
public function create() {
|
||||
|
||||
// Очищаем данные
|
||||
$this->sanitize();
|
||||
|
||||
// Валидация данных
|
||||
if ($errors = $this->validate()) {
|
||||
return $errors;
|
||||
@@ -133,6 +175,7 @@ class Account extends BaseEntity {
|
||||
|
||||
// Получаем данные пользователя
|
||||
$user = Database::get($this->db_name, [
|
||||
'id',
|
||||
'id_department',
|
||||
'name',
|
||||
'username',
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
require_once __DIR__ . '/class/enity/class_base.php';
|
||||
require_once __DIR__ . '/class/enity/class_fileUpload.php';
|
||||
require_once __DIR__ . '/class/enity/class_user.php';
|
||||
require_once __DIR__ . '/class/enity/class_projectAccess.php';
|
||||
require_once __DIR__ . '/class/enity/class_projectInvite.php';
|
||||
require_once __DIR__ . '/class/enity/class_project.php';
|
||||
require_once __DIR__ . '/class/enity/class_task.php';
|
||||
require_once __DIR__ . '/class/enity/class_comment.php';
|
||||
@@ -35,10 +37,12 @@
|
||||
'/api/user' => __DIR__ . '/../api/user.php',
|
||||
'/api/task' => __DIR__ . '/../api/task.php',
|
||||
'/api/project' => __DIR__ . '/../api/project.php',
|
||||
'/api/projectAccess' => __DIR__ . '/../api/projectAccess.php',
|
||||
'/api/projectInvite' => __DIR__ . '/../api/projectInvite.php',
|
||||
'/api/comment' => __DIR__ . '/../api/comment.php',
|
||||
'/api/server' => __DIR__ . '/../api/server.php',
|
||||
];
|
||||
|
||||
$publicActions = ['auth_login', 'check_session', 'get_settings'];
|
||||
$publicActions = ['auth_login', 'check_session', 'create_user', 'get_settings'];
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user