Your IP : 216.73.216.79


Current Path : /var/www/html/reddsis/app/Http/Controllers/Backend/
Upload File :
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;
    }
}