Skip to content

Commit

Permalink
Added -H|--hard option for permissions:sync and better abort handling (
Browse files Browse the repository at this point in the history
…#212)

* Added option for hard reset and better handling of aborting

* Permission console messages

---------

Co-authored-by: Simon <[email protected]>
  • Loading branch information
mps-pso and sjking85 authored Oct 27, 2024
1 parent 160442f commit 826ca74
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 29 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ This will not delete any existing permissions. However, if you want to delete al
php artisan permissions:sync -C|--clean
```

There may be an occassion where you wish to hard reset and truncate your existing permissions. To delete all permissions and reset the primary key, run

```bash
php artisan permissions:sync -H|--hard
```

#### Example:
If you have a **Post** model, it will generate the following permissions
```
Expand Down
90 changes: 61 additions & 29 deletions src/Commands/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

namespace Althinect\FilamentSpatieRolesPermissions\Commands;

use ReflectionClass;
use ReflectionException;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use ReflectionClass;
use ReflectionException;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Schema;
use Illuminate\Contracts\Filesystem\FileNotFoundException;

class Permission extends Command
{
Expand All @@ -23,15 +24,15 @@ class Permission extends Command
{--C|clean}
{--P|policies}
{--O|oep}
{--Y|yes-to-all}';
{--Y|yes-to-all}
{--H|hard}';

protected $description = 'Generates permissions through Models or Filament Resources and custom permissions';

public function __construct()
{
parent::__construct();
$this->config = config('filament-spatie-roles-permissions.generator');

}

/**
Expand All @@ -44,33 +45,65 @@ public function handle(): void

$classes = array_diff($classes, $this->getExcludedModels());

$this->deleteExistingPermissions();
// Only attempt to delete existing permissions if a deletion option is passed
if ($this->option('hard') || $this->option('clean')) {
$deletionResult = $this->deleteExistingPermissions();
if (!$deletionResult) {
$this->line('<bg=yellow;options=bold;>*** OPERATION ABORTED ***</>');
$this->warn('No changes were made.');
$this->info('Consider running <bg=blue>php artisan permissions:sync</> if you just wish to sync without deleting.');
return;
}
}

$this->prepareClassPermissionsAndPolicies($classes);

$this->prepareCustomPermissions();

$permissionModel = config('permission.models.permission');

$count = 0;

foreach ($this->permissions as $permission) {
$this->comment('Syncing Permission for: '.$permission['name']);
$this->comment('Syncing Permission for: ' . $permission['name']);
$permissionModel::firstOrCreate($permission);
$count++;
}

$this->info('<bg=green;options=bold;>DONE</>');
$this->info($count . ' permissions synced successfully.');
}

public function deleteExistingPermissions(): void
public function deleteExistingPermissions(): bool
{
if ($this->option('clean')) {
if ($this->option('yes-to-all') || $this->confirm('This will delete existing permissions. Do you want to continue?', false)) {
$permissionsTable = config('permission.table_names.permissions');

if ($this->option('hard')) {
if ($this->option('yes-to-all') || $this->confirm("This will delete all existing permissions AND truncate your {$permissionsTable} database. Do you want to continue?", false)) {
$this->comment('Deleting Permissions And Truncating');
try {
Schema::disableForeignKeyConstraints();
DB::table($permissionsTable)->truncate();
Schema::enableForeignKeyConstraints();
return true;
} catch (\Exception $exception) {
$this->error($exception->getMessage());
return false;
}
}
} elseif ($this->option('clean')) {
if ($this->option('yes-to-all') || $this->confirm('This will delete all existing permissions. Do you want to continue?', false)) {
$this->comment('Deleting Permissions');
try {
DB::table(config('permission.table_names.permissions'))->delete();
$this->comment('Deleted Permissions');
DB::table($permissionsTable)->delete();
return true;
} catch (\Exception $exception) {
$this->warn($exception->getMessage());
$this->error($exception->getMessage());
return false;
}
}
}
return false;
}

/**
Expand Down Expand Up @@ -99,15 +132,15 @@ public function prepareClassPermissionsAndPolicies($classes): void
];

if ($this->option('policies')) {
$contents = Str::replace('{{ '.$key.' }}', $permission, $contents);
$contents = Str::replace('{{ ' . $key . ' }}', $permission, $contents);
}
}
}

if ($this->option('policies') || $this->option('yes-to-all')) {

$policyVariables = [
'class' => $modelName.'Policy',
'class' => $modelName . 'Policy',
'namespacedModel' => $model->getName(),
'namespacedUserModel' => (new ReflectionClass($this->config['user_model']))->getName(),
'namespace' => $this->config['policies_namespace'],
Expand All @@ -120,20 +153,20 @@ public function prepareClassPermissionsAndPolicies($classes): void
if ($modelName == 'User' && $search == 'namespacedModel') {
$contents = Str::replace('use {{ namespacedModel }};', '', $contents);
} else {
$contents = Str::replace('{{ '.$search.' }}', $replace, $contents);
$contents = Str::replace('{{ ' . $search . ' }}', $replace, $contents);
}
}

if ($filesystem->exists(app_path('Policies/'.$modelName.'Policy.php'))) {
if ($filesystem->exists(app_path('Policies/' . $modelName . 'Policy.php'))) {
if ($this->option('oep')) {
$filesystem->put(app_path('Policies/'.$modelName.'Policy.php'), $contents);
$this->comment('Overriding Existing Policy: '.$modelName);
$filesystem->put(app_path('Policies/' . $modelName . 'Policy.php'), $contents);
$this->comment('Overriding Existing Policy: ' . $modelName);
} else {
$this->warn('Policy already exists for: '.$modelName);
$this->warn('Policy already exists for: ' . $modelName);
}
} else {
$filesystem->put(app_path('Policies/'.$modelName.'Policy.php'), $contents);
$this->comment('Creating Policy: '.$modelName);
$filesystem->put(app_path('Policies/' . $modelName . 'Policy.php'), $contents);
$this->comment('Creating Policy: ' . $modelName);
}
}
}
Expand Down Expand Up @@ -163,12 +196,12 @@ public function getModels(): array

foreach ($resources as $resource) {
$resourceNameSpace = $this->extractNamespace($resource);
$reflection = new ReflectionClass($resourceNameSpace.'\\'.$resource->getFilenameWithoutExtension());
$reflection = new ReflectionClass($resourceNameSpace . '\\' . $resource->getFilenameWithoutExtension());
if (
! $reflection->isAbstract() && $reflection->getParentClass() &&
$reflection->getParentClass()->getName() == 'Filament\Resources\Resource'
) {
$models[] = new ReflectionClass(app($resourceNameSpace.'\\'.$resource->getFilenameWithoutExtension())->getModel());
$models[] = new ReflectionClass(app($resourceNameSpace . '\\' . $resource->getFilenameWithoutExtension())->getModel());
}
}
}
Expand All @@ -190,12 +223,11 @@ private function getClassesInDirectory($path): array

foreach ($files as $file) {
$namespace = $this->extractNamespace($file);
$class = $namespace.'\\'.$file->getFilenameWithoutExtension();
$class = $namespace . '\\' . $file->getFilenameWithoutExtension();
$model = new ReflectionClass($class);
if (! $model->isAbstract()) {
$models[] = $model;
}

}

return $models;
Expand Down Expand Up @@ -268,6 +300,6 @@ protected function resolveStubPath($stub)
{
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
? $customPath
: __DIR__.$stub;
: __DIR__ . $stub;
}
}

0 comments on commit 826ca74

Please sign in to comment.