Files
bp/app/Models/OrganizationUserModel.php
2026-01-15 07:09:36 +03:00

153 lines
4.3 KiB
PHP

<?php
namespace App\Models;
use CodeIgniter\Model;
use App\Models\Traits\TenantScopedModel;
class OrganizationUserModel extends Model
{
use TenantScopedModel;
protected $table = 'organization_users';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = 'array';
protected $allowedFields = [
'organization_id',
'user_id',
'role',
'status',
'invite_token',
'invited_by',
'invited_at',
'invite_expires_at',
'joined_at',
];
protected $useTimestamps = false;
// Константы статусов
public const STATUS_ACTIVE = 'active';
public const STATUS_PENDING = 'pending';
public const STATUS_BLOCKED = 'blocked';
// Роли
public const ROLE_OWNER = 'owner';
public const ROLE_ADMIN = 'admin';
public const ROLE_MANAGER = 'manager';
public const ROLE_GUEST = 'guest';
/**
* Поиск приглашения по токену
*/
public function findByInviteToken(string $token): ?array
{
return $this->where('invite_token', $token)
->where('status', self::STATUS_PENDING)
->where('invite_expires_at >', date('Y-m-d H:i:s'))
->first();
}
/**
* Получение списка пользователей организации с данными из users
*/
public function getOrganizationUsers(int $organizationId): array
{
// Создаём новый чистый запрос с нуля
$db = $this->db();
$builder = $db->newQuery();
return $builder->select('ou.*, u.name as user_name, u.email as user_email, u.avatar as user_avatar')
->from('organization_users ou')
->join('users u', 'u.id = ou.user_id', 'left')
->where('ou.organization_id', $organizationId)
->orderBy('ou.joined_at', 'DESC')
->get()
->getResultArray();
}
/**
* Проверка, существует ли активное приглашение для пользователя
*/
public function hasPendingInvite(int $organizationId, int $userId): bool
{
return $this->where('organization_id', $organizationId)
->where('user_id', $userId)
->where('status', self::STATUS_PENDING)
->countAllResults() > 0;
}
/**
* Получение всех приглашений организации
*/
public function getPendingInvites(int $organizationId): array
{
return $this->where('organization_id', $organizationId)
->where('status', self::STATUS_PENDING)
->orderBy('invited_at', 'DESC')
->findAll();
}
/**
* Создание приглашения
*/
public function createInvitation(array $data): int
{
$data['invited_at'] = date('Y-m-d H:i:s');
return $this->insert($data);
}
/**
* Принятие приглашения
*/
public function acceptInvitation(int $id, int $userId): bool
{
return $this->update($id, [
'status' => self::STATUS_ACTIVE,
'invite_token' => null,
'joined_at' => date('Y-m-d H:i:s'),
]);
}
/**
* Отклонение приглашения
*/
public function declineInvitation(int $id): bool
{
return $this->delete($id);
}
/**
* Отзыв приглашения
*/
public function cancelInvitation(int $id): bool
{
return $this->delete($id);
}
/**
* Изменение роли пользователя
*/
public function updateRole(int $id, string $role): bool
{
return $this->update($id, ['role' => $role]);
}
/**
* Блокировка пользователя
*/
public function blockUser(int $id): bool
{
return $this->update($id, ['status' => self::STATUS_BLOCKED]);
}
/**
* Разблокировка пользователя
*/
public function unblockUser(int $id): bool
{
return $this->update($id, ['status' => self::STATUS_ACTIVE]);
}
}