940afe9319
API CI/CD / Validate (composer + pint) (push) Successful in 2m7s
API CI/CD / Test (PHPUnit) (push) Failing after 2m23s
API CI/CD / Build frontend assets (push) Successful in 2m18s
API CI/CD / Security audit (push) Successful in 31s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
111 lines
3.1 KiB
PHP
111 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Roles;
|
|
|
|
use App\Models\Role;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class RoleCrudService
|
|
{
|
|
public function create(array $payload): Role
|
|
{
|
|
$data = $this->normalizePayload($payload);
|
|
|
|
try {
|
|
return DB::transaction(function () use ($data) {
|
|
return Role::query()->create($data);
|
|
});
|
|
} catch (\Throwable $e) {
|
|
Log::error('Role create failed: '.$e->getMessage());
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function update(Role $role, array $payload): Role
|
|
{
|
|
$data = $this->normalizePayload($payload, $role);
|
|
|
|
try {
|
|
return DB::transaction(function () use ($role, $data) {
|
|
$role->fill($data);
|
|
$role->save();
|
|
|
|
return $role;
|
|
});
|
|
} catch (\Throwable $e) {
|
|
Log::error('Role update failed: '.$e->getMessage());
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function delete(Role $role): void
|
|
{
|
|
try {
|
|
DB::transaction(function () use ($role) {
|
|
$role->delete();
|
|
});
|
|
} catch (\Throwable $e) {
|
|
Log::error('Role delete failed: '.$e->getMessage());
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function normalizePayload(array $payload, ?Role $role = null): array
|
|
{
|
|
$rawName = trim((string) ($payload['name'] ?? $role?->name ?? ''));
|
|
$rawSlug = trim((string) ($payload['slug'] ?? $role?->slug ?? ''));
|
|
$route = trim((string) ($payload['dashboard_route'] ?? $role?->dashboard_route ?? ''));
|
|
$desc = trim((string) ($payload['description'] ?? $role?->description ?? ''));
|
|
$priority = (int) ($payload['priority'] ?? $role?->priority ?? 0);
|
|
$isActive = array_key_exists('is_active', $payload)
|
|
? (! empty($payload['is_active']) ? 1 : 0)
|
|
: (int) ($role?->is_active ?? 0);
|
|
|
|
$name = strtolower($rawName);
|
|
$dashboardRoute = strtolower($route);
|
|
$description = strtolower($desc);
|
|
|
|
$slug = $rawSlug !== '' ? $rawSlug : $name;
|
|
$slug = strtolower(preg_replace('/[^a-z0-9]+/i', '_', $slug));
|
|
$slug = trim($slug, '_');
|
|
|
|
if ($slug !== ($role?->slug ?? null)) {
|
|
$slug = $this->ensureUniqueSlug($slug, $role?->id);
|
|
}
|
|
|
|
return [
|
|
'name' => $name,
|
|
'slug' => $slug,
|
|
'description' => $description,
|
|
'dashboard_route' => $dashboardRoute,
|
|
'priority' => $priority,
|
|
'is_active' => $isActive,
|
|
];
|
|
}
|
|
|
|
private function ensureUniqueSlug(string $baseSlug, ?int $ignoreId = null): string
|
|
{
|
|
$slug = $baseSlug;
|
|
$i = 2;
|
|
|
|
while (true) {
|
|
$query = Role::query()->where('slug', $slug);
|
|
if ($ignoreId !== null) {
|
|
$query->where('id', '!=', $ignoreId);
|
|
}
|
|
|
|
if (! $query->exists()) {
|
|
return $slug;
|
|
}
|
|
|
|
$slug = $baseSlug.'_'.$i;
|
|
$i++;
|
|
|
|
if ($i > 100000) {
|
|
return $slug;
|
|
}
|
|
}
|
|
}
|
|
}
|