From 7e3653a78b0f90bd898daa15c878f2c504bcd729 Mon Sep 17 00:00:00 2001 From: tuxarmy Date: Sat, 4 Apr 2026 12:09:36 +0700 Subject: [PATCH] feat: tambah ShieldSeeder dari shield:seed, update config discovery dan DatabaseSeeder --- config/filament-shield.php | 6 +- database/seeders/DatabaseSeeder.php | 1 + database/seeders/ShieldSeeder.php | 231 ++++++++++++++++++++++++++++ 3 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 database/seeders/ShieldSeeder.php diff --git a/config/filament-shield.php b/config/filament-shield.php index eb46378..c287e7e 100644 --- a/config/filament-shield.php +++ b/config/filament-shield.php @@ -248,9 +248,9 @@ return [ */ 'discovery' => [ - 'discover_all_resources' => false, - 'discover_all_widgets' => false, - 'discover_all_pages' => false, + 'discover_all_resources' => true, + 'discover_all_widgets' => true, + 'discover_all_pages' => true, ], /* diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 65bebcc..b26a65d 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -9,6 +9,7 @@ class DatabaseSeeder extends Seeder public function run(): void { $this->call([ + ShieldSeeder::class, PermissionSeeder::class, DivisionSeeder::class, UserSeeder::class, diff --git a/database/seeders/ShieldSeeder.php b/database/seeders/ShieldSeeder.php new file mode 100644 index 0000000..c843f7b --- /dev/null +++ b/database/seeders/ShieldSeeder.php @@ -0,0 +1,231 @@ +forgetCachedPermissions(); + + $tenants = '[]'; + $users = '[]'; + $userTenantPivot = '[]'; + $rolesWithPermissions = '[{ + "name":"super_admin", + "guard_name":"web", + "permissions":[] + },{ + "name":"ketua", + "guard_name":"web", + "permissions":[] + },{ + "name":"bendahara", + "guard_name":"web", + "permissions":[] + },{ + "name":"pengurus", + "guard_name":"web", + "permissions":[] + },{ + "name":"anggota", + "guard_name":"web", + "permissions":[] + },{ + "name":"auditor", + "guard_name":"web", + "permissions":[] + }]'; + $directPermissions = '[]'; + + // 1. Seed tenants first (if present) + if (! blank($tenants) && $tenants !== '[]') { + static::seedTenants($tenants); + } + + // 2. Seed roles with permissions + static::makeRolesWithPermissions($rolesWithPermissions); + + // 3. Seed direct permissions + static::makeDirectPermissions($directPermissions); + + // 4. Seed users with their roles/permissions (if present) + if (! blank($users) && $users !== '[]') { + static::seedUsers($users); + } + + // 5. Seed user-tenant pivot (if present) + if (! blank($userTenantPivot) && $userTenantPivot !== '[]') { + static::seedUserTenantPivot($userTenantPivot); + } + + $this->command->info('Shield Seeding Completed.'); + } + + protected static function seedTenants(string $tenants): void + { + if (blank($tenantData = json_decode($tenants, true))) { + return; + } + + $tenantModel = ''; + if (blank($tenantModel)) { + return; + } + + foreach ($tenantData as $tenant) { + $tenantModel::firstOrCreate( + ['id' => $tenant['id']], + $tenant + ); + } + } + + protected static function seedUsers(string $users): void + { + if (blank($userData = json_decode($users, true))) { + return; + } + + $userModel = 'App\Models\User'; + $tenancyEnabled = false; + + foreach ($userData as $data) { + // Extract role/permission data before creating user + $roles = $data['roles'] ?? []; + $permissions = $data['permissions'] ?? []; + $tenantRoles = $data['tenant_roles'] ?? []; + $tenantPermissions = $data['tenant_permissions'] ?? []; + unset($data['roles'], $data['permissions'], $data['tenant_roles'], $data['tenant_permissions']); + + $user = $userModel::firstOrCreate( + ['email' => $data['email']], + $data + ); + + // Handle tenancy mode - sync roles/permissions per tenant + if ($tenancyEnabled && (! empty($tenantRoles) || ! empty($tenantPermissions))) { + foreach ($tenantRoles as $tenantId => $roleNames) { + $contextId = $tenantId === '_global' ? null : $tenantId; + setPermissionsTeamId($contextId); + $user->syncRoles($roleNames); + } + + foreach ($tenantPermissions as $tenantId => $permissionNames) { + $contextId = $tenantId === '_global' ? null : $tenantId; + setPermissionsTeamId($contextId); + $user->syncPermissions($permissionNames); + } + } else { + // Non-tenancy mode + if (! empty($roles)) { + $user->syncRoles($roles); + } + + if (! empty($permissions)) { + $user->syncPermissions($permissions); + } + } + } + } + + protected static function seedUserTenantPivot(string $pivot): void + { + if (blank($pivotData = json_decode($pivot, true))) { + return; + } + + $pivotTable = ''; + if (blank($pivotTable)) { + return; + } + + foreach ($pivotData as $row) { + $uniqueKeys = []; + + if (isset($row['user_id'])) { + $uniqueKeys['user_id'] = $row['user_id']; + } + + $tenantForeignKey = 'team_id'; + if (! blank($tenantForeignKey) && isset($row[$tenantForeignKey])) { + $uniqueKeys[$tenantForeignKey] = $row[$tenantForeignKey]; + } + + if (! empty($uniqueKeys)) { + DB::table($pivotTable)->updateOrInsert($uniqueKeys, $row); + } + } + } + + protected static function makeRolesWithPermissions(string $rolesWithPermissions): void + { + if (blank($rolePlusPermissions = json_decode($rolesWithPermissions, true))) { + return; + } + + /** @var \Illuminate\Database\Eloquent\Model $roleModel */ + $roleModel = Utils::getRoleModel(); + /** @var \Illuminate\Database\Eloquent\Model $permissionModel */ + $permissionModel = Utils::getPermissionModel(); + + $tenancyEnabled = false; + $teamForeignKey = 'team_id'; + + foreach ($rolePlusPermissions as $rolePlusPermission) { + $tenantId = $rolePlusPermission[$teamForeignKey] ?? null; + + // Set tenant context for role creation and permission sync + if ($tenancyEnabled) { + setPermissionsTeamId($tenantId); + } + + $roleData = [ + 'name' => $rolePlusPermission['name'], + 'guard_name' => $rolePlusPermission['guard_name'], + ]; + + // Include tenant ID in role data (can be null for global roles) + if ($tenancyEnabled && ! blank($teamForeignKey)) { + $roleData[$teamForeignKey] = $tenantId; + } + + $role = $roleModel::firstOrCreate($roleData); + + if (! blank($rolePlusPermission['permissions'])) { + $permissionModels = collect($rolePlusPermission['permissions']) + ->map(fn ($permission) => $permissionModel::firstOrCreate([ + 'name' => $permission, + 'guard_name' => $rolePlusPermission['guard_name'], + ])) + ->all(); + + $role->syncPermissions($permissionModels); + } + } + } + + public static function makeDirectPermissions(string $directPermissions): void + { + if (blank($permissions = json_decode($directPermissions, true))) { + return; + } + + /** @var \Illuminate\Database\Eloquent\Model $permissionModel */ + $permissionModel = Utils::getPermissionModel(); + + foreach ($permissions as $permission) { + if ($permissionModel::whereName($permission['name'])->doesntExist()) { + $permissionModel::create([ + 'name' => $permission['name'], + 'guard_name' => $permission['guard_name'], + ]); + } + } + } +}