162 lines
4.5 KiB
PHP
162 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Users;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class UserListService
|
|
{
|
|
private const SORT_FIELDS = [
|
|
'id',
|
|
'firstname',
|
|
'lastname',
|
|
'email',
|
|
'status',
|
|
'updated_at',
|
|
];
|
|
|
|
public function list(?string $sort, ?string $order): array
|
|
{
|
|
$sort = in_array($sort, self::SORT_FIELDS, true) ? $sort : 'id';
|
|
$order = strtolower((string) $order) === 'desc' ? 'desc' : 'asc';
|
|
|
|
$users = User::query()
|
|
->with('roles')
|
|
->orderBy($sort, $order)
|
|
->get();
|
|
|
|
$guardianMap = $this->guardianTypeMap();
|
|
[$secondByUserId, $secondByEmail] = $this->secondParentMaps();
|
|
|
|
$usersWithRoles = [];
|
|
|
|
foreach ($users as $user) {
|
|
$roles = $user->roles->map(fn ($role) => (string) $role->name)->values()->all();
|
|
$roleIds = $user->roles->map(fn ($role) => (int) $role->id)->values()->all();
|
|
|
|
$userId = (int) $user->id;
|
|
$parentType = $guardianMap[$userId] ?? '';
|
|
|
|
$isSecond = false;
|
|
if ($userId > 0 && !empty($secondByUserId[$userId])) {
|
|
$isSecond = true;
|
|
} else {
|
|
$email = trim(strtolower((string) $user->email));
|
|
if ($email !== '' && !empty($secondByEmail[$email])) {
|
|
$isSecond = true;
|
|
}
|
|
}
|
|
|
|
$usersWithRoles[] = [
|
|
'user' => $user->toArray(),
|
|
'roles' => $roles,
|
|
'role_ids' => $roleIds,
|
|
'parent_type' => $parentType,
|
|
'second_from_parents' => $isSecond ? 'Yes' : '',
|
|
];
|
|
}
|
|
|
|
return $usersWithRoles;
|
|
}
|
|
|
|
public function getUsersWithRoles(?string $sort = 'id', ?string $order = 'asc'): array
|
|
{
|
|
$sort = (string) ($sort ?? 'id');
|
|
$order = (string) ($order ?? 'asc');
|
|
|
|
$map = [
|
|
'id' => 'users.id',
|
|
'firstname' => 'users.firstname',
|
|
'lastname' => 'users.lastname',
|
|
'email' => 'users.email',
|
|
'role' => 'role',
|
|
];
|
|
|
|
$sortField = $map[$sort] ?? 'users.id';
|
|
|
|
return User::getUsersWithRoles($sortField, $order);
|
|
}
|
|
|
|
public function getUnverifiedUsers(): array
|
|
{
|
|
return User::getUnverifiedUsers();
|
|
}
|
|
|
|
public function getUsersByRole(string $role): array
|
|
{
|
|
return User::getUsersByRole($role);
|
|
}
|
|
|
|
private function guardianTypeMap(): array
|
|
{
|
|
if (!Schema::hasTable('family_guardians')) {
|
|
return [];
|
|
}
|
|
|
|
$rows = DB::table('family_guardians')
|
|
->selectRaw('user_id, MAX(is_primary) AS max_primary, COUNT(*) AS cnt')
|
|
->groupBy('user_id')
|
|
->get();
|
|
|
|
$map = [];
|
|
foreach ($rows as $row) {
|
|
$userId = (int) ($row->user_id ?? 0);
|
|
if ($userId <= 0) {
|
|
continue;
|
|
}
|
|
$count = (int) ($row->cnt ?? 0);
|
|
if ($count <= 0) {
|
|
continue;
|
|
}
|
|
$maxPrimary = (int) ($row->max_primary ?? 0);
|
|
$map[$userId] = $maxPrimary > 0 ? 'Primary' : 'Secondary';
|
|
}
|
|
|
|
return $map;
|
|
}
|
|
|
|
private function secondParentMaps(): array
|
|
{
|
|
if (!Schema::hasTable('parents')) {
|
|
return [[], []];
|
|
}
|
|
|
|
$byUserId = [];
|
|
$byEmail = [];
|
|
|
|
if (Schema::hasColumn('parents', 'secondparent_user_id')) {
|
|
$rows = DB::table('parents')
|
|
->selectRaw('secondparent_user_id AS uid, COUNT(*) AS cnt')
|
|
->where('secondparent_user_id', '!=', 0)
|
|
->groupBy('secondparent_user_id')
|
|
->get();
|
|
|
|
foreach ($rows as $row) {
|
|
$userId = (int) ($row->uid ?? 0);
|
|
if ($userId > 0) {
|
|
$byUserId[$userId] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Schema::hasColumn('parents', 'secondparent_email')) {
|
|
$rows = DB::table('parents')
|
|
->selectRaw('LOWER(TRIM(secondparent_email)) AS em, COUNT(*) AS cnt')
|
|
->where('secondparent_email', '!=', '')
|
|
->groupBy('secondparent_email')
|
|
->get();
|
|
|
|
foreach ($rows as $row) {
|
|
$email = trim(strtolower((string) ($row->em ?? '')));
|
|
if ($email !== '') {
|
|
$byEmail[$email] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return [$byUserId, $byEmail];
|
|
}
|
|
}
|