Files
alrahma_sunday_school_api/app/Services/Roles/RoleQueryService.php
T
2026-06-09 01:03:53 -04:00

106 lines
3.9 KiB
PHP

<?php
namespace App\Services\Roles;
use App\Models\Role;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
class RoleQueryService
{
public function listRoles(array $filters): LengthAwarePaginator
{
$query = Role::query()
->select([
'roles.id',
'roles.name',
'roles.slug',
'roles.description',
'roles.dashboard_route',
'roles.priority',
'roles.is_active',
'roles.created_at',
'roles.updated_at',
])
->leftJoin('user_roles', function ($join) {
$join->on('user_roles.role_id', '=', 'roles.id')
->whereNull('user_roles.deleted_at');
})
->selectRaw('COUNT(DISTINCT user_roles.user_id) AS user_count')
->groupBy([
'roles.id',
'roles.name',
'roles.slug',
'roles.description',
'roles.dashboard_route',
'roles.priority',
'roles.is_active',
'roles.created_at',
'roles.updated_at',
]);
if (!empty($filters['search'])) {
$search = trim((string) $filters['search']);
$query->where(function (Builder $q) use ($search) {
$q->where('roles.name', 'like', '%' . $search . '%')
->orWhere('roles.slug', 'like', '%' . $search . '%')
->orWhere('roles.description', 'like', '%' . $search . '%');
});
}
$sortBy = (string) ($filters['sort_by'] ?? 'name');
$sortDir = strtolower((string) ($filters['sort_dir'] ?? 'asc')) === 'desc' ? 'desc' : 'asc';
$allowed = ['name', 'slug', 'priority', 'is_active', 'created_at'];
if (!in_array($sortBy, $allowed, true)) {
$sortBy = 'name';
}
$perPage = (int) ($filters['per_page'] ?? 20);
$perPage = $perPage > 0 ? $perPage : 20;
return $query->orderBy($sortBy, $sortDir)->paginate($perPage);
}
public function listUsersWithRoles(array $filters): LengthAwarePaginator
{
$query = DB::table('users')
->leftJoin('user_roles', function ($join) {
$join->on('user_roles.user_id', '=', 'users.id')
->whereNull('user_roles.deleted_at');
})
->leftJoin('roles', 'roles.id', '=', 'user_roles.role_id')
->select(
'users.id',
'users.firstname',
'users.lastname',
'users.email',
'users.account_id',
DB::raw('GROUP_CONCAT(DISTINCT roles.name) as roles')
)
->groupBy('users.id', 'users.firstname', 'users.lastname', 'users.email', 'users.account_id');
if (!empty($filters['search'])) {
$search = trim((string) $filters['search']);
$query->where(function ($q) use ($search) {
$q->where('users.firstname', 'like', '%' . $search . '%')
->orWhere('users.lastname', 'like', '%' . $search . '%')
->orWhere('users.email', 'like', '%' . $search . '%')
->orWhere('users.account_id', 'like', '%' . $search . '%');
});
}
$sortBy = (string) ($filters['sort_by'] ?? 'lastname');
$sortDir = strtolower((string) ($filters['sort_dir'] ?? 'asc')) === 'desc' ? 'desc' : 'asc';
$allowed = ['firstname', 'lastname', 'email', 'account_id'];
if (!in_array($sortBy, $allowed, true)) {
$sortBy = 'lastname';
}
$perPage = (int) ($filters['per_page'] ?? 20);
$perPage = $perPage > 0 ? $perPage : 20;
return $query->orderBy('users.' . $sortBy, $sortDir)->paginate($perPage);
}
}