| Current Path : /var/www/html/reddsis/app/Http/Controllers/Backend/ |
| Current File : /var/www/html/reddsis/app/Http/Controllers/Backend/AutoPermissionController.php |
<?php
namespace App\Http\Controllers\Backend;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Illuminate\Pagination\LengthAwarePaginator;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
class AutoPermissionController extends Controller
{
protected array $excluded = [
'ContentSliderTranslation',
'ContentArticleTranslation',
'ContentApplicationTranslation',
'ContentDownloadTranslation',
'ContentVideoTranslation',
'ContentPhotoGalleryTranslation',
'ContentCalendarTranslation',
'VisitorSetting',
];
public function index(Request $request)
{
$search = $request->get('search');
$models = $this->getModels();
$roles = Role::where('guard_name', 'admin')->orderBy('name')->get();
$existingPermissions = Permission::where('guard_name', 'admin')
->pluck('name')
->toArray();
$routePermissions = $this->extractRoutePermissions();
$allExpected = [];
foreach ($routePermissions as $prefix => $actions) {
$moduleName = $this->getModuleNameFromPrefix($prefix);
foreach ($actions as $action) {
$permissionName = "{$prefix}.{$action}";
$allExpected[] = [
'permission' => $permissionName,
'module' => $moduleName,
'prefix' => $prefix,
'action' => $action,
'generated' => in_array($permissionName, $existingPermissions),
];
}
}
if ($search) {
$allExpected = array_filter($allExpected, function ($perm) use ($search) {
return stripos($perm['permission'], $search) !== false
|| stripos($perm['module'], $search) !== false;
});
}
usort($allExpected, fn($a, $b) => strcmp($a['module'], $b['module']));
$totalPermissions = count($allExpected);
$generatedCount = count(array_filter($allExpected, fn($p) => $p['generated']));
$missingCount = $totalPermissions - $generatedCount;
$currentPage = max(1, (int) $request->get('page', 1));
$perPage = 15;
$paginated = new LengthAwarePaginator(
array_slice($allExpected, ($currentPage - 1) * $perPage, $perPage),
$totalPermissions,
$perPage,
$currentPage,
['path' => route('auto-permissions.index', [], false)]
);
$paginated->appends($request->except('page'));
return view('backend.module.auto-permission.index', [
'models' => $models,
'roles' => $roles,
'actions' => ['view', 'create', 'update', 'delete'],
'permissions' => $paginated->items(),
'paginator' => $paginated,
'search' => $search,
'stats' => [
'total' => $totalPermissions,
'generated' => $generatedCount,
'missing' => $missingCount,
],
]);
}
protected function extractRoutePermissions(): array
{
$permissions = [];
$routeCollection = \Illuminate\Support\Facades\Route::getRoutes();
foreach ($routeCollection as $route) {
$middlewares = $route->middleware();
foreach ($middlewares as $middleware) {
if (!is_string($middleware)) {
continue;
}
if (!str_contains($middleware, 'permission:')) {
continue;
}
$permissionPart = $middleware;
if (preg_match('/permission:([^,]+)/', $permissionPart, $matches)) {
$permString = $matches[1];
$permParts = explode(',', $permString);
foreach ($permParts as $perm) {
$perm = trim($perm);
if (empty($perm)) {
continue;
}
$dotCount = substr_count($perm, '.');
if ($dotCount === 1) {
$parts = explode('.', $perm);
$prefix = $parts[0];
$action = $parts[1] ?? 'view';
} elseif ($dotCount >= 2) {
$lastDot = strrpos($perm, '.');
$prefix = substr($perm, 0, $lastDot);
$action = substr($perm, $lastDot + 1);
} else {
continue;
}
$action = $this->normalizeAction($action);
if (!isset($permissions[$prefix])) {
$permissions[$prefix] = [];
}
if (!in_array($action, $permissions[$prefix], true)) {
$permissions[$prefix][] = $action;
}
}
}
}
}
return $permissions;
}
protected function normalizeAction(string $action): string
{
$mapping = [
'view' => 'view',
'index' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
'delete' => 'delete',
];
return $mapping[$action] ?? 'view';
}
protected function getModuleNameFromPrefix(string $prefix): string
{
$mapping = [
'activity-log' => 'ActivityLog',
'auto-permission' => 'AutoPermission',
'backend-menu' => 'BackendMenu',
'backend-user' => 'BackendUser',
'content-application' => 'ContentApplication',
'content-article' => 'ContentArticle',
'content-download' => 'ContentDownload',
'content-image' => 'ContentImage',
'content-photo-gallery' => 'ContentPhotoGallery',
'content-photo-list' => 'ContentPhotoList',
'content-public-holiday' => 'ContentPublicHoliday',
'content-calendar' => 'ContentCalendar',
'content-slider' => 'ContentSlider',
'content-video' => 'ContentVideo',
'file' => 'FileManager',
'frontend-menu' => 'FrontendMenu',
'frontend-user' => 'FrontendUser',
'menu-category' => 'MenuCategory',
'permission' => 'Permission',
'ref' => 'Ref',
'role' => 'Role',
'route' => 'Route',
'visitor' => 'Visitor',
];
return $mapping[$prefix] ?? $prefix;
}
public function generate(Request $request)
{
$request->validate([
'model' => 'required|string',
'actions' => 'required|array|min:1',
'actions.*' => 'string|in:view,create,update,delete',
'roles' => 'nullable|array',
'roles.*' => 'integer|exists:roles,id',
]);
$modelClass = $request->input('model');
$actions = $request->input('actions', []);
$roleIds = $request->input('roles', []);
$prefix = $this->getPermissionPrefix($modelClass);
$guard = 'admin';
$created = [];
foreach ($actions as $action) {
$permissionName = "{$prefix}.{$action}";
$perm = Permission::firstOrCreate([
'name' => $permissionName,
'guard_name' => $guard,
]);
$created[] = $permissionName;
}
if (!empty($roleIds)) {
$permissions = Permission::where('guard_name', $guard)
->whereIn('name', $created)
->get();
foreach ($roleIds as $roleId) {
$role = Role::find($roleId);
if ($role) {
$role->givePermissionTo($permissions);
}
}
}
app(PermissionRegistrar::class)->forgetCachedPermissions();
flash()->success('Permissions created and assigned successfully: ' . implode(', ', $created));
return redirect()->route('auto-permissions.index');
}
protected function getModels(): array
{
$path = app_path('Models/Backend');
$files = File::files($path);
$models = [];
foreach ($files as $file) {
$className = pathinfo($file->getFilename(), PATHINFO_FILENAME);
if (in_array($className, $this->excluded, true)) {
continue;
}
$fullClass = "App\\Models\\Backend\\{$className}";
$prefix = $this->getPermissionPrefix($fullClass);
$models[] = [
'class' => $fullClass,
'name' => $className,
'prefix' => $prefix,
];
}
usort($models, fn($a, $b) => strcmp($a['name'], $b['name']));
return $models;
}
protected function getPermissionPrefix(string $modelClass): string
{
$basename = class_basename($modelClass);
$kebab = Str::kebab($basename);
$replacements = [
'backend-user' => 'backend-user',
'frontend-user' => 'frontend-user',
'content-slider' => 'content-slider',
'content-article' => 'content-article',
'content-application' => 'content-application',
'content-download' => 'content-download',
'content-image' => 'content-image',
'content-video' => 'content-video',
'content-photo-gallery' => 'content-photo-gallery',
'content-photo-list' => 'content-photo-list',
'content-public-holiday' => 'content-public-holiday',
'content-calendar' => 'content-calendar',
'activity-log' => 'activity-log',
'auto-permission' => 'auto-permission',
'backend-menu' => 'backend-menu',
'frontend-menu' => 'frontend-menu',
'menu-category' => 'menu-category',
'permission' => 'permission',
'ref' => 'ref',
'role' => 'role',
'route' => 'route',
'visit' => 'visitor',
];
return $replacements[$kebab] ?? $kebab;
}
}