106 lines
3.9 KiB
PHP
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);
|
|
}
|
|
}
|