dashboard for org
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Models\OrganizationUserModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\OrganizationModel;
|
||||
use App\Services\InvitationService;
|
||||
use App\Services\AccessService;
|
||||
|
||||
class InvitationController extends BaseController
|
||||
{
|
||||
protected InvitationService $invitationService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->invitationService = new InvitationService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Страница принятия/отклонения приглашения
|
||||
*/
|
||||
public function accept(string $token)
|
||||
{
|
||||
$invitation = $this->invitationService->orgUserModel->findByInviteToken($token);
|
||||
|
||||
if (!$invitation) {
|
||||
return $this->renderTwig('organizations/invitation_expired', [
|
||||
'title' => 'Приглашение недействительно',
|
||||
]);
|
||||
}
|
||||
|
||||
// Получаем данные организации
|
||||
$orgModel = new OrganizationModel();
|
||||
$organization = $orgModel->find($invitation['organization_id']);
|
||||
|
||||
// Получаем данные приглашающего
|
||||
$invitedByUser = null;
|
||||
if ($invitation['invited_by']) {
|
||||
$userModel = new UserModel();
|
||||
$invitedByUser = $userModel->find($invitation['invited_by']);
|
||||
}
|
||||
|
||||
// Определяем, авторизован ли пользователь
|
||||
$currentUserId = session()->get('user_id');
|
||||
$isLoggedIn = !empty($currentUserId);
|
||||
|
||||
// Если пользователь авторизован - проверяем, тот ли это email
|
||||
$emailMatches = true;
|
||||
if ($isLoggedIn && $invitation['user_id']) {
|
||||
$currentUser = (new UserModel())->find($currentUserId);
|
||||
// Проверяем, тот ли пользователь (по ID или email)
|
||||
$emailMatches = ($currentUserId == $invitation['user_id']);
|
||||
}
|
||||
|
||||
// Метка роли
|
||||
$roleLabels = [
|
||||
'owner' => 'Владелец',
|
||||
'admin' => 'Администратор',
|
||||
'manager' => 'Менеджер',
|
||||
'guest' => 'Гость',
|
||||
];
|
||||
|
||||
return $this->renderTwig('organizations/invitation_accept', [
|
||||
'title' => 'Приглашение в ' . ($organization['name'] ?? 'организацию'),
|
||||
'token' => $token,
|
||||
'organization' => $organization,
|
||||
'role' => $invitation['role'],
|
||||
'role_label' => $roleLabels[$invitation['role']] ?? $invitation['role'],
|
||||
'invited_by' => $invitedByUser,
|
||||
'invited_at' => $invitation['invited_at'],
|
||||
'is_logged_in' => $isLoggedIn,
|
||||
'email_matches' => $emailMatches,
|
||||
'current_user_id'=> $currentUserId,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработка принятия приглашения
|
||||
*/
|
||||
public function processAccept()
|
||||
{
|
||||
$token = $this->request->getPost('token');
|
||||
$action = $this->request->getPost('action');
|
||||
|
||||
if ($action === 'decline') {
|
||||
return $this->decline($token);
|
||||
}
|
||||
|
||||
$userId = session()->get('user_id');
|
||||
|
||||
// Если пользователь не авторизован - редирект на страницу создания пароля
|
||||
if (!$userId) {
|
||||
return redirect()->to('/invitation/complete/' . $token);
|
||||
}
|
||||
|
||||
// Принимаем приглашение
|
||||
$result = $this->invitationService->acceptInvitation($token, $userId);
|
||||
|
||||
if (!$result['success']) {
|
||||
session()->setFlashdata('error', $result['message']);
|
||||
return redirect()->to('/invitation/accept/' . $token);
|
||||
}
|
||||
|
||||
session()->setFlashdata('success', 'Вы приняли приглашение в организацию "' . $result['organization_name'] . '"');
|
||||
|
||||
// Переключаем организацию и редиректим на главную
|
||||
session()->set('active_org_id', $result['organization_id']);
|
||||
(new AccessService())->resetCache();
|
||||
|
||||
return redirect()->to('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Отклонение приглашения
|
||||
*/
|
||||
public function decline(string $token)
|
||||
{
|
||||
$result = $this->invitationService->declineInvitation($token);
|
||||
|
||||
if (!$result['success']) {
|
||||
session()->setFlashdata('error', $result['message']);
|
||||
} else {
|
||||
session()->setFlashdata('info', 'Приглашение отклонено');
|
||||
}
|
||||
|
||||
return redirect()->to('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Страница завершения регистрации (для новых пользователей)
|
||||
*/
|
||||
public function complete(string $token)
|
||||
{
|
||||
$invitation = $this->invitationService->orgUserModel->findByInviteToken($token);
|
||||
|
||||
if (!$invitation) {
|
||||
return $this->renderTwig('organizations/invitation_expired', [
|
||||
'title' => 'Приглашение недействительно',
|
||||
]);
|
||||
}
|
||||
|
||||
// Если пользователь уже авторизован и это его приглашение
|
||||
$userId = session()->get('user_id');
|
||||
if ($userId && $invitation['user_id'] == $userId) {
|
||||
return redirect()->to('/invitation/accept/' . $token);
|
||||
}
|
||||
|
||||
// Получаем данные организации
|
||||
$orgModel = new OrganizationModel();
|
||||
$organization = $orgModel->find($invitation['organization_id']);
|
||||
|
||||
// Метка роли
|
||||
$roleLabels = [
|
||||
'owner' => 'Владелец',
|
||||
'admin' => 'Администратор',
|
||||
'manager' => 'Менеджер',
|
||||
'guest' => 'Гость',
|
||||
];
|
||||
|
||||
return $this->renderTwig('organizations/invitation_complete', [
|
||||
'title' => 'Завершение регистрации',
|
||||
'token' => $token,
|
||||
'email' => $invitation['user_id'] ? '' : '', // Email возьмем из теневой записи
|
||||
'organization' => $organization,
|
||||
'role' => $invitation['role'],
|
||||
'role_label' => $roleLabels[$invitation['role']] ?? $invitation['role'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработка завершения регистрации
|
||||
*/
|
||||
public function processComplete()
|
||||
{
|
||||
$token = $this->request->getPost('token');
|
||||
$name = $this->request->getPost('name');
|
||||
$password = $this->request->getPost('password');
|
||||
$passwordConfirm = $this->request->getPost('password_confirm');
|
||||
|
||||
// Валидация
|
||||
$errors = [];
|
||||
|
||||
if (empty($name) || strlen($name) < 2) {
|
||||
$errors[] = 'Имя должно содержать минимум 2 символа';
|
||||
}
|
||||
|
||||
if (empty($password) || strlen($password) < 8) {
|
||||
$errors[] = 'Пароль должен содержать минимум 8 символов';
|
||||
}
|
||||
|
||||
if ($password !== $passwordConfirm) {
|
||||
$errors[] = 'Пароли не совпадают';
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
return redirect()->back()->withInput()->with('errors', $errors);
|
||||
}
|
||||
|
||||
$invitation = $this->invitationService->orgUserModel->findByInviteToken($token);
|
||||
|
||||
if (!$invitation) {
|
||||
return redirect()->to('/');
|
||||
}
|
||||
|
||||
// Находим теневую запись пользователя
|
||||
$userModel = new UserModel();
|
||||
|
||||
// Если user_id указан - обновляем существующего пользователя
|
||||
if ($invitation['user_id']) {
|
||||
$user = $userModel->find($invitation['user_id']);
|
||||
if (!$user) {
|
||||
session()->setFlashdata('error', 'Пользователь не найден');
|
||||
return redirect()->to('/invitation/complete/' . $token);
|
||||
}
|
||||
|
||||
// Обновляем профиль
|
||||
$userModel->update($user['id'], [
|
||||
'name' => $name,
|
||||
'password' => $password,
|
||||
]);
|
||||
|
||||
$userId = $user['id'];
|
||||
} else {
|
||||
// Создаем нового пользователя (теневой + реальный)
|
||||
// На самом деле у нас уже есть запись в users - нужно её "активировать"
|
||||
$shadowUsers = $userModel->where('email', $userModel->getFindByEmail($invitation['organization_id']))->findAll();
|
||||
// Логика для теневых пользователей требует доработки
|
||||
|
||||
session()->setFlashdata('error', 'Ошибка регистрации');
|
||||
return redirect()->to('/invitation/complete/' . $token);
|
||||
}
|
||||
|
||||
// Авторизуем пользователя
|
||||
$user = $userModel->find($userId);
|
||||
$this->loginUser($user);
|
||||
|
||||
// Принимаем приглашение
|
||||
$result = $this->invitationService->acceptInvitation($token, $userId);
|
||||
|
||||
if (!$result['success']) {
|
||||
session()->setFlashdata('error', $result['message']);
|
||||
return redirect()->to('/');
|
||||
}
|
||||
|
||||
session()->setFlashdata('success', 'Добро пожаловать! Вы успешно зарегистрировались и приняли приглашение.');
|
||||
|
||||
// Переключаем организацию
|
||||
session()->set('active_org_id', $result['organization_id']);
|
||||
(new AccessService())->resetCache();
|
||||
|
||||
return redirect()->to('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Авторизация пользователя после регистрации
|
||||
*/
|
||||
protected function loginUser(array $user): void
|
||||
{
|
||||
session()->set([
|
||||
'user_id' => $user['id'],
|
||||
'email' => $user['email'],
|
||||
'name' => $user['name'],
|
||||
'logged_in' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user