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

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

238 lines
8.9 KiB
PHP
Raw Permalink 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 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];
}
}
?>