135 lines
4.9 KiB
PHP
135 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Filesystem\Filesystem;
|
|
use Illuminate\Support\Str;
|
|
use Spatie\Permission\Models\Permission;
|
|
use Spatie\Permission\Models\Role;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\Hash;
|
|
|
|
class ScanResourcesPermissions extends Command
|
|
{
|
|
protected $signature = 'permissions:scan
|
|
{--create-user= : Email del usuario a crear}
|
|
{--password= : Contraseña para el usuario (si se usa --create-user)}
|
|
{--role=Administrador : Nombre del rol a crear}';
|
|
|
|
protected $description = 'Escanea app/Filament/Resources para generar permisos CRUD, crear rol y asignar permisos. Opcionalmente crea un usuario y le asigna el rol.';
|
|
|
|
public function handle()
|
|
{
|
|
$this->info('Escaneando recursos Filament...');
|
|
|
|
$fs = new Filesystem();
|
|
$resourcesPath = app_path('Filament/Resources');
|
|
|
|
if (! $fs->isDirectory($resourcesPath)) {
|
|
$this->error("No se encontró la carpeta {$resourcesPath}. Ningún permiso fue creado.");
|
|
return 1;
|
|
}
|
|
|
|
$files = $fs->allFiles($resourcesPath);
|
|
|
|
$created = [];
|
|
|
|
foreach ($files as $file) {
|
|
if (! Str::endsWith($file->getFilename(), 'Resource.php')) {
|
|
continue;
|
|
}
|
|
|
|
$filename = pathinfo($file->getFilename(), PATHINFO_FILENAME);
|
|
$className = 'App\\Filament\\Resources\\' . $filename;
|
|
|
|
// Intentar obtener un label legible: preferimos el método getPluralModelLabel(), luego getNavigationLabel(), luego la propiedad estática
|
|
$label = null;
|
|
$pluralLabel = null;
|
|
|
|
if (class_exists($className)) {
|
|
if (method_exists($className, 'getPluralModelLabel')) {
|
|
$pluralLabel = $className::getPluralModelLabel();
|
|
}
|
|
|
|
if (! $pluralLabel && method_exists($className, 'getNavigationLabel')) {
|
|
$pluralLabel = $className::getNavigationLabel();
|
|
}
|
|
|
|
if (! $pluralLabel && isset($className::$navigationLabel)) {
|
|
$pluralLabel = $className::$navigationLabel;
|
|
}
|
|
}
|
|
|
|
// Si no hay label plural, usar el nombre del archivo sin sufijo Resource
|
|
if ($pluralLabel) {
|
|
$base = Str::lower($pluralLabel);
|
|
} else {
|
|
$base = Str::lower(Str::replaceLast('Resource', '', $filename));
|
|
}
|
|
|
|
// Normalizar: eliminar espacios extra y restos de extensión
|
|
$base = trim((string) Str::of($base)->lower());
|
|
$base = preg_replace('/\.php$/', '', $base);
|
|
|
|
// Generar formas singular y plural
|
|
$plural = Str::lower(Str::plural($base));
|
|
$singular = Str::lower(Str::singular($base));
|
|
|
|
// Generar permisos comunes
|
|
$perms = [
|
|
"ver {$plural}",
|
|
"crear {$singular}",
|
|
"editar {$singular}",
|
|
"eliminar {$singular}",
|
|
];
|
|
|
|
foreach ($perms as $permName) {
|
|
$permission = Permission::firstOrCreate(['name' => $permName]);
|
|
$created[] = $permission->name;
|
|
}
|
|
}
|
|
|
|
// Asegurar permisos para roles y permisos (usados en Resource::canViewAny en algunos casos)
|
|
Permission::firstOrCreate(['name' => 'ver roles']);
|
|
Permission::firstOrCreate(['name' => 'ver permisos']);
|
|
|
|
$this->info('Permisos generados/asegurados: ' . count($created));
|
|
$this->line(implode("\n", array_slice($created, 0, 200)));
|
|
|
|
// Eliminar permisos mal formados (ej. que contienen '.php') generados por escaneos previos
|
|
Permission::where('name', 'like', '%.php%')->orWhere('name', 'like', '%.phps%')->delete();
|
|
|
|
// Crear rol y asignar todos los permisos
|
|
$roleName = $this->option('role') ?? 'Administrador';
|
|
$role = Role::firstOrCreate(['name' => $roleName]);
|
|
$all = Permission::all();
|
|
$role->syncPermissions($all);
|
|
|
|
$this->info("Rol '{$roleName}' creado/actualizado y se le asignaron " . $all->count() . " permisos.");
|
|
|
|
// Si se solicita, crear usuario y asignar rol
|
|
$createUserEmail = $this->option('create-user');
|
|
$password = $this->option('password');
|
|
|
|
if ($createUserEmail) {
|
|
if (! $password) {
|
|
$this->error('Si usas --create-user debes pasar también --password.');
|
|
return 1;
|
|
}
|
|
|
|
$user = User::updateOrCreate(
|
|
['email' => $createUserEmail],
|
|
['name' => $roleName, 'password' => Hash::make($password)]
|
|
);
|
|
|
|
$user->assignRole($role);
|
|
$this->info("Usuario '{$createUserEmail}' creado/actualizado y se le asignó el rol '{$roleName}'.");
|
|
}
|
|
|
|
$this->info('Finalizado.');
|
|
|
|
return 0;
|
|
}
|
|
}
|