Files
2026-06-11 11:46:12 -04:00

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];
}
}