Snapshot of main at 9f39a6e1e (2026-11-02)
This commit is contained in:
commit
6ccf1792d7
2580 files changed
+1040202
No files matched your search
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Admin;
|
||||
use App\Models\AdminRole;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Spatie\Permission\Models\Role;
|
||||
use Spatie\Permission\PermissionRegistrar;
|
||||
|
||||
/**
|
||||
* Replace the legacy scoped roles Admin\{id}\admin by a role from admin_roles.
|
||||
*
|
||||
* Admin profiles used to get the role Admin\{id}\admin, with every permission of that moment and never synced
|
||||
* (admin_roles has no "admin"). The permission checks now accept any role on the profile, so these roles are
|
||||
* no longer needed. For every such role, on any installation:
|
||||
* 1. each holder gets Admin\{id}\{default role} (admin_settings.default_admin_role, 'administrator'),
|
||||
* created and synced from its definition when missing; nobody loses access;
|
||||
* 2. then the legacy role is removed.
|
||||
* Without a definition for the default role nothing changes. Running it again changes nothing.
|
||||
* Called by `php artisan database:update`; run it with --dry-run first to see what it would do.
|
||||
*/
|
||||
class AdminRolesMigrate extends Command
|
||||
{
|
||||
protected $signature = 'admin-roles:migrate {--dry-run : Show what would change, change nothing}';
|
||||
|
||||
protected $description = 'Replace the legacy Admin\\{id}\\admin roles by the default role from admin_roles';
|
||||
|
||||
/** Matches Admin\{id}\admin */
|
||||
public const LEGACY_PATTERN = '/^Admin\\\\(\d+)\\\\admin$/';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$dryRun = (bool) $this->option('dry-run');
|
||||
$defaultName = AdminRole::defaultName();
|
||||
$definition = AdminRole::where('name', $defaultName)->first();
|
||||
|
||||
$legacyRoles = Role::where('guard_name', 'web')->get()
|
||||
->filter(fn (Role $role) => preg_match(self::LEGACY_PATTERN, $role->name));
|
||||
|
||||
if ($legacyRoles->isEmpty()) {
|
||||
$this->info('No legacy Admin\\{id}\\admin roles: nothing to do.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
if (!$definition) {
|
||||
$this->error("The default admin role '{$defaultName}' (admin_settings.default_admin_role) has no admin_roles definition: nothing changed.");
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info(($dryRun ? '[dry run] ' : '') . "Replacing {$legacyRoles->count()} legacy role(s) by '{$defaultName}':");
|
||||
|
||||
foreach ($legacyRoles as $legacy) {
|
||||
preg_match(self::LEGACY_PATTERN, $legacy->name, $m);
|
||||
$adminId = (int) $m[1];
|
||||
$exists = Admin::whereKey($adminId)->exists();
|
||||
|
||||
$holderIds = DB::table('model_has_roles')
|
||||
->where('role_id', $legacy->id)
|
||||
->where('model_type', User::class)
|
||||
->pluck('model_id');
|
||||
|
||||
$this->line(" {$legacy->name}: {$holderIds->count()} holder(s)" . ($exists ? '' : ' (admin profile no longer exists)'));
|
||||
|
||||
if ($exists) {
|
||||
foreach (User::whereKey($holderIds)->get() as $user) {
|
||||
$target = "Admin\\{$adminId}\\{$defaultName}";
|
||||
if ($user->hasRole($target)) {
|
||||
$this->line(" user #{$user->id} already has {$target}");
|
||||
continue;
|
||||
}
|
||||
$this->line(" user #{$user->id} gets {$target}");
|
||||
if (!$dryRun) {
|
||||
$definition->assignScopedTo($user, $adminId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->line(" remove {$legacy->name}");
|
||||
if (!$dryRun) {
|
||||
$legacy->delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$dryRun) {
|
||||
app(PermissionRegistrar::class)->forgetCachedPermissions();
|
||||
$this->info('Done.');
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user