108 lines
3.0 KiB
PHP
108 lines
3.0 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->id, $role->slug ?? null);
|
|
|
|
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, ?int $ignoreId = null, ?string $currentSlug = null): array
|
|
{
|
|
$rawName = trim((string) ($payload['name'] ?? ''));
|
|
$rawSlug = trim((string) ($payload['slug'] ?? ''));
|
|
$route = trim((string) ($payload['dashboard_route'] ?? ''));
|
|
$desc = trim((string) ($payload['description'] ?? ''));
|
|
$priority = (int) ($payload['priority'] ?? 0);
|
|
$isActive = !empty($payload['is_active']) ? 1 : 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 !== $currentSlug) {
|
|
$slug = $this->ensureUniqueSlug($slug, $ignoreId);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|