singleloginsystem/app/Services/RoleService.php
= cd29191c7b Feat: add role priority management
- Added `priority` column to `roles` table with migration and model updates.
- Introduced priority management methods in `RoleService` and validation logic for updates.
- Enhanced access-manager UI to display and edit role priorities via a modal.
- Updated related data classes and views to support and handle the new priority field.
2026-05-25 06:35:21 +00:00

126 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services;
use App\Data\Role\{CreateRoleData, RoleData, UpdateRolePriorityData};
use App\Models\Role;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;
use NoDiscard;
use Spatie\LaravelData\{DataCollection, PaginatedDataCollection};
use Throwable;
final class RoleService
{
/**
* Create a new role.
* Returns the created role DTO
*
* @throws Throwable when an error occurs during the creation.
*/
public function create(CreateRoleData $data): RoleData
{
$role = DB::transaction(fn () => Role::query()->create([
'name' => $data->name,
'priority' => $data->priority,
'guard_name' => 'web',
]));
return RoleData::from($role);
}
/**
* @throws InvalidArgumentException when id is invalid.
* @throws Throwable when an error occurs during the deletion.
*/
public function delete(int $id): void
{
if ($id <= 0) {
throw new InvalidArgumentException('Invalid id');
}
DB::transaction(function () use ($id): void {
Role::query()->findOrFail($id)->delete();
});
}
/**
* Returns a Paginated Collection of roles with their connected apps DTO
*
* @return PaginatedDataCollection<int, RoleData>
*/
#[NoDiscard]
public function getAll(): PaginatedDataCollection
{
$roles = Role::query()
->with(['apps:id,name', 'users:id,name'])
->orderBy('id')
->paginate();
return RoleData::collect($roles, PaginatedDataCollection::class);
}
public function searchRolesForSelect(string $search = ''): Collection
{
return Role::query()
->when('' !== $search, fn ($query) => $query->where('name', 'like', "%{$search}%"))
->select('id', 'name')
->get();
}
public function getAllRoleIds(): array
{
return Role::query()->pluck('id')->toArray();
}
/**
* Return all permissions for the given roles, grouped by role name.
* Each permission is a plain array so Livewire can serialise the property cleanly.
*
* @param array<int, int> $roleIds
*
* @return DataCollection<int, RoleData>|null
*/
#[NoDiscard]
public function getPermissionsGroupedByRole(array $roleIds): ?DataCollection
{
if (empty($roleIds)) {
return null;
}
$roles = Role::query()
->with('permissions:id,name')
->whereIn('id', $roleIds)
->get(['id', 'name', 'priority']);
return RoleData::collect($roles, DataCollection::class);
}
/**
* Update the priority of a role.
*
* @throws InvalidArgumentException when roleId is invalid.
* @throws Throwable when an error occurs during the update.
*/
public function updatePriority(UpdateRolePriorityData $data): RoleData
{
if ($data->roleId <= 0) {
throw new InvalidArgumentException('Invalid role id');
}
$role = DB::transaction(function () use ($data) {
$role = Role::query()->findOrFail($data->roleId);
$role->update([
'priority' => $data->priority,
]);
return $role;
});
return RoleData::from($role);
}
}