Files
sam-api/app/Observers/MenuObserver.php

107 lines
2.8 KiB
PHP
Raw Normal View History

<?php
namespace App\Observers;
use App\Models\Commons\Menu; // ← 실제 경로 확인
use Spatie\Permission\Models\Permission;
use Spatie\Permission\PermissionRegistrar;
class MenuObserver
{
protected function actions(): array
{
// config/authz.php 에서 오버라이드 가능 (없으면 기본값)
return config('authz.menu_actions', ['view', 'create', 'update', 'delete', 'approve']);
}
protected string $guard = 'api';
public function created(Menu $menu): void
{
if (! $this->shouldHandle($menu)) {
return;
}
$this->setTeam((int) $menu->tenant_id);
$this->ensurePermissions($menu);
$this->forgetCache();
}
public function updated(Menu $menu): void
{
// 메뉴 ID 기반: 권한 이름 변경 불필요
// 필요 시, 기본 롤 자동 부여/회수 같은 정책을 이곳에…
}
public function deleted(Menu $menu): void
{
if (! $this->shouldHandle($menu)) {
return;
}
$this->setTeam((int) $menu->tenant_id);
$this->removePermissions($menu);
$this->forgetCache();
}
public function restored(Menu $menu): void
{
if (! $this->shouldHandle($menu)) {
return;
}
$this->setTeam((int) $menu->tenant_id);
$this->ensurePermissions($menu);
$this->forgetCache();
}
public function forceDeleted(Menu $menu): void
{
if (! $this->shouldHandle($menu)) {
return;
}
$this->setTeam((int) $menu->tenant_id);
$this->removePermissions($menu);
$this->forgetCache();
}
/** teams 사용 시 tenant_id 없는 공용 메뉴는 스킵하는 게 안전 */
protected function shouldHandle(Menu $menu): bool
{
return ! is_null($menu->tenant_id);
}
protected function setTeam(int $tenantId): void
{
app(PermissionRegistrar::class)->setPermissionsTeamId($tenantId);
}
protected function ensurePermissions(Menu $menu): void
{
foreach ($this->actions() as $act) {
Permission::firstOrCreate([
'tenant_id' => (int) $menu->tenant_id,
'guard_name' => $this->guard,
'name' => "menu:{$menu->id}.{$act}",
]);
}
}
protected function removePermissions(Menu $menu): void
{
Permission::where('tenant_id', (int) $menu->tenant_id)
->where('guard_name', $this->guard)
->where(function ($q) use ($menu) {
foreach ($this->actions() as $act) {
$q->orWhere('name', "menu:{$menu->id}.{$act}");
}
})->delete();
}
protected function forgetCache(): void
{
app(PermissionRegistrar::class)->forgetCachedPermissions();
}
}