From d00a4569854edd854f83ea987614bf16e89179aa Mon Sep 17 00:00:00 2001 From: Kilian Trunk Date: Wed, 29 Oct 2025 12:00:12 +0100 Subject: [PATCH 1/3] feat(worbench-setup): make plugin development self-contained --- .lando.dist.yml | 26 +- README.md | 21 +- composer.json | 5 +- env/php-8.3/.lando.dist.yml | 5 +- env/php-8.3/composer.json | 2 +- testbench.yaml | 22 +- workbench/.env.example | 16 +- workbench/.gitignore | 23 +- .../Http/Middleware/WorkbenchBootstrap.php | 180 +++++++++ workbench/app/Models/User.php | 34 +- workbench/app/Policies/CategoryPolicy.php | 75 ++++ workbench/app/Policies/GroupPolicy.php | 75 ++++ workbench/app/Policies/MeasureUnitPolicy.php | 75 ++++ workbench/app/Policies/PriceListPolicy.php | 75 ++++ workbench/app/Policies/ProductPolicy.php | 75 ++++ .../app/Policies/ProductStatusPolicy.php | 75 ++++ workbench/app/Policies/ProductTypePolicy.php | 75 ++++ workbench/app/Policies/PropertyPolicy.php | 75 ++++ .../app/Policies/PropertyValuePolicy.php | 75 ++++ workbench/app/Policies/RolePolicy.php | 75 ++++ workbench/app/Policies/TaxClassPolicy.php | 75 ++++ .../app/Providers/AdminPanelProvider.php | 9 +- .../app/Providers/AuthServiceProvider.php | 25 ++ .../Providers/WorkbenchServiceProvider.php | 17 +- workbench/bootstrap/app.php | 10 +- workbench/bootstrap/cache/packages.php | 270 +++++++++++++ workbench/bootstrap/cache/services.php | 354 ++++++++++++++++++ workbench/bootstrap/cache/testbench.yaml | 36 ++ .../bootstrap/cache/testbench.yaml.backup | 36 ++ workbench/composer.json | 9 + workbench/config/app.php | 126 +++++++ workbench/config/auth.php | 117 ++++++ workbench/config/blade-heroicons.php | 57 +++ workbench/config/blade-icons.php | 183 +++++++++ workbench/config/cache.php | 108 ++++++ workbench/config/concurrency.php | 20 + workbench/config/cors.php | 34 ++ workbench/config/database.php | 173 +++++++++ workbench/config/eclipse-catalogue.php | 5 + workbench/config/filament-shield.php | 97 +++++ workbench/config/filament.php | 101 +++++ workbench/config/filesystems.php | 80 ++++ workbench/config/hashing.php | 67 ++++ workbench/config/livewire.php | 160 ++++++++ workbench/config/logging.php | 132 +++++++ workbench/config/permission.php | 206 ++++++++++ workbench/config/queue.php | 112 ++++++ workbench/config/session.php | 217 +++++++++++ workbench/config/tinker.php | 50 +++ workbench/config/view.php | 36 ++ workbench/database/database.sqlite | Bin 0 -> 458752 bytes workbench/database/factories/UserFactory.php | 15 +- ...01_000000_testbench_create_users_table.php | 49 +++ ...01_000001_testbench_create_cache_table.php | 35 ++ ..._01_000002_testbench_create_jobs_table.php | 57 +++ ...025_08_10_104332_create_sessions_table.php | 33 ++ ...8_28_113759_create_notifications_table.php | 31 ++ ..._08_28_142604_create_permission_tables.php | 136 +++++++ workbench/public/index.php | 55 +++ workbench/public/robots.txt | 2 + .../resources/views/errors/401.blade.php | 5 + .../resources/views/errors/402.blade.php | 5 + .../resources/views/errors/403.blade.php | 5 + .../resources/views/errors/404.blade.php | 5 + .../resources/views/errors/419.blade.php | 5 + .../resources/views/errors/429.blade.php | 5 + .../resources/views/errors/500.blade.php | 5 + .../resources/views/errors/503.blade.php | 5 + .../resources/views/errors/layout.blade.php | 53 +++ .../resources/views/errors/minimal.blade.php | 34 ++ workbench/resources/views/welcome.blade.php | 66 ++++ workbench/routes/console.php | 2 +- workbench/routes/web.php | 2 +- workbench/storage/.gitkeep | 0 workbench/storage/framework/.gitkeep | 0 workbench/storage/framework/cache/.gitkeep | 0 workbench/storage/framework/data/.gitkeep | 0 workbench/storage/framework/sessions/.gitkeep | 0 workbench/storage/framework/testing/.gitkeep | 0 workbench/storage/framework/views/.gitkeep | 0 workbench/storage/logs/.gitkeep | 0 81 files changed, 4535 insertions(+), 81 deletions(-) create mode 100644 workbench/app/Http/Middleware/WorkbenchBootstrap.php create mode 100644 workbench/app/Policies/CategoryPolicy.php create mode 100644 workbench/app/Policies/GroupPolicy.php create mode 100644 workbench/app/Policies/MeasureUnitPolicy.php create mode 100644 workbench/app/Policies/PriceListPolicy.php create mode 100644 workbench/app/Policies/ProductPolicy.php create mode 100644 workbench/app/Policies/ProductStatusPolicy.php create mode 100644 workbench/app/Policies/ProductTypePolicy.php create mode 100644 workbench/app/Policies/PropertyPolicy.php create mode 100644 workbench/app/Policies/PropertyValuePolicy.php create mode 100644 workbench/app/Policies/RolePolicy.php create mode 100644 workbench/app/Policies/TaxClassPolicy.php create mode 100644 workbench/app/Providers/AuthServiceProvider.php create mode 100755 workbench/bootstrap/cache/packages.php create mode 100755 workbench/bootstrap/cache/services.php create mode 100644 workbench/bootstrap/cache/testbench.yaml create mode 100644 workbench/bootstrap/cache/testbench.yaml.backup create mode 100644 workbench/composer.json create mode 100644 workbench/config/app.php create mode 100644 workbench/config/auth.php create mode 100644 workbench/config/blade-heroicons.php create mode 100644 workbench/config/blade-icons.php create mode 100644 workbench/config/cache.php create mode 100644 workbench/config/concurrency.php create mode 100644 workbench/config/cors.php create mode 100644 workbench/config/database.php create mode 100644 workbench/config/eclipse-catalogue.php create mode 100644 workbench/config/filament-shield.php create mode 100644 workbench/config/filament.php create mode 100644 workbench/config/filesystems.php create mode 100644 workbench/config/hashing.php create mode 100644 workbench/config/livewire.php create mode 100644 workbench/config/logging.php create mode 100644 workbench/config/permission.php create mode 100644 workbench/config/queue.php create mode 100644 workbench/config/session.php create mode 100644 workbench/config/tinker.php create mode 100644 workbench/config/view.php create mode 100644 workbench/database/database.sqlite create mode 100644 workbench/database/migrations/0001_01_01_000000_testbench_create_users_table.php create mode 100644 workbench/database/migrations/0001_01_01_000001_testbench_create_cache_table.php create mode 100644 workbench/database/migrations/0001_01_01_000002_testbench_create_jobs_table.php create mode 100644 workbench/database/migrations/2025_08_10_104332_create_sessions_table.php create mode 100644 workbench/database/migrations/2025_08_28_113759_create_notifications_table.php create mode 100644 workbench/database/migrations/2025_08_28_142604_create_permission_tables.php create mode 100644 workbench/public/index.php create mode 100644 workbench/public/robots.txt create mode 100644 workbench/resources/views/errors/401.blade.php create mode 100644 workbench/resources/views/errors/402.blade.php create mode 100644 workbench/resources/views/errors/403.blade.php create mode 100644 workbench/resources/views/errors/404.blade.php create mode 100644 workbench/resources/views/errors/419.blade.php create mode 100644 workbench/resources/views/errors/429.blade.php create mode 100644 workbench/resources/views/errors/500.blade.php create mode 100644 workbench/resources/views/errors/503.blade.php create mode 100644 workbench/resources/views/errors/layout.blade.php create mode 100644 workbench/resources/views/errors/minimal.blade.php create mode 100644 workbench/resources/views/welcome.blade.php create mode 100644 workbench/storage/.gitkeep create mode 100644 workbench/storage/framework/.gitkeep create mode 100644 workbench/storage/framework/cache/.gitkeep create mode 100644 workbench/storage/framework/data/.gitkeep create mode 100644 workbench/storage/framework/sessions/.gitkeep create mode 100644 workbench/storage/framework/testing/.gitkeep create mode 100644 workbench/storage/framework/views/.gitkeep create mode 100644 workbench/storage/logs/.gitkeep diff --git a/.lando.dist.yml b/.lando.dist.yml index 72cefe1..b12668f 100644 --- a/.lando.dist.yml +++ b/.lando.dist.yml @@ -1,12 +1,30 @@ #file: noinspection ComposeUnknownKeys,YAMLSchemaValidation -name: eclipse-catalogue +name: eclipse-catalogue-plugin +recipe: laravel +config: + webroot: workbench/public + php: '8.3' + via: nginx + database: mariadb:10.11 services: appserver: type: php:custom xdebug: "debug,develop,coverage" - via: cli + environment: + TZ: "Europe/Ljubljana" + APP_BASE_PATH: "/app/workbench" + TESTBENCH_WORKING_PATH: "/app" overrides: - image: slimdeluxe/php:8.2-v1.3 + image: slimdeluxe/php:8.3-v1.3 + platform: linux/amd64 + run: + - composer install --no-interaction --prefer-dist + - composer run setup --no-interaction + - composer run build --no-interaction + appserver_nginx: + scanner: + path: /admin/login + retry: 5 tooling: php: service: appserver @@ -23,4 +41,4 @@ tooling: testbench: service: appserver description: Run testbench CLI - cmd: "vendor/bin/testbench" + cmd: "vendor/bin/testbench" \ No newline at end of file diff --git a/README.md b/README.md index 2f293a7..63c1577 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,26 @@ Should you want to contribute, please see the development guidelines in the [Dat ```` 4. You can now develop and run tests. Happy coding 😉 -💡 To manually test the plugin in the browser, see our [recommendation](https://github.com/DataLinx/eclipsephp-core/blob/main/docs/Documentation.md#-plugin-development), which is also [how Filament suggests package development](https://filamentphp.com/docs/3.x/support/contributing#developing-with-a-local-copy-of-filament). +#### Workbench + Lando (browser testing) + +This package ships with a minimal Testbench Workbench so you can run the Filament UI without a separate app: + +1. Clone the repository +2. Start the container + ```shell + lando start + ``` + +3. Open the admin panel at `https://eclipse-catalogue-plugin.lndo.site/admin` + +**No login required** - you'll be automatically signed in as a test user with full permissions. + +Notes: +- The container serves `workbench/public` as the webroot. +- Use `lando test` for `package:test` and `lando testbench` for other Testbench commands. +- No Telescope, websockets or health checks are enabled to keep the setup minimal. + +💡 To manually test the plugin in the browser, see our [recommendation](https://github.com/DataLinx/eclipsephp-core/blob/main/docs/Documentation.md#-plugin-development), which is also [how Filament suggests package development](https://filamentphp.com/docs/3.x/support/contributing#developing-with-a-local-copy-of-filament). However, the plugin should be universal and not dependent on our app setup or core package. ### Changelog diff --git a/composer.json b/composer.json index 7a69dfd..5cf1253 100644 --- a/composer.json +++ b/composer.json @@ -83,10 +83,11 @@ "@php vendor/bin/testbench serve --ansi" ], "setup": [ + "@php -r \"if (!file_exists('workbench/.env')) { copy('workbench/.env.example', 'workbench/.env'); echo '.env file created from .env.example\\n'; }\"", + "@php vendor/bin/testbench key:generate --ansi", "npm install", - "@php vendor/bin/testbench vendor:publish --provider='Spatie\\Permission\\PermissionServiceProvider'", "@php vendor/bin/testbench vendor:publish --tag='filament-shield-config'", - "@php vendor/bin/testbench vendor:publish --provider='Laravel\\Scout\\ScoutServiceProvider'", + "@php vendor/bin/testbench filament:assets", "@php vendor/bin/testbench package:sync-skeleton" ] }, diff --git a/env/php-8.3/.lando.dist.yml b/env/php-8.3/.lando.dist.yml index b9ec10c..1aff75e 100644 --- a/env/php-8.3/.lando.dist.yml +++ b/env/php-8.3/.lando.dist.yml @@ -1,5 +1,4 @@ -#file: noinspection ComposeUnknownKeys -name: eclipsephp-catalogue-plugin-8.3 +name: eclipse-catalogue-8.3 services: appserver: type: php:custom @@ -28,4 +27,4 @@ tooling: testbench: service: appserver description: Run testbench CLI - cmd: "vendor/bin/testbench" + cmd: "vendor/bin/testbench" \ No newline at end of file diff --git a/env/php-8.3/composer.json b/env/php-8.3/composer.json index 830cc51..baef055 100644 --- a/env/php-8.3/composer.json +++ b/env/php-8.3/composer.json @@ -38,4 +38,4 @@ "Workbench\\Database\\Seeders\\": "workbench/database/seeders/" } } -} +} \ No newline at end of file diff --git a/testbench.yaml b/testbench.yaml index 64a584a..e037997 100644 --- a/testbench.yaml +++ b/testbench.yaml @@ -1,13 +1,21 @@ laravel: '@testbench' +env: + - DB_CONNECTION=sqlite + - DB_DATABASE=/app/workbench/database/database.sqlite + - APP_KEY=base64:ZQvPGC7uVADkjOgtGIIuCI8u3/Pzu+VaRObIbHsgjCc= + - APP_ENV=local + - APP_DEBUG=true + - SESSION_DRIVER=database + - CACHE_STORE=database + - QUEUE_CONNECTION=sync + providers: - Workbench\App\Providers\WorkbenchServiceProvider migrations: - workbench/database/migrations - -seeders: - - Workbench\Database\Seeders\DatabaseSeeder + - database/migrations workbench: start: '/' @@ -16,7 +24,7 @@ workbench: discovers: web: true api: false - commands: false + commands: true components: false views: false build: @@ -25,8 +33,4 @@ workbench: - db-wipe - migrate-fresh assets: - - laravel-assets - sync: - - from: storage - to: workbench/storage - reverse: true + - laravel-assets \ No newline at end of file diff --git a/workbench/.env.example b/workbench/.env.example index e5488ab..f8a0d08 100644 --- a/workbench/.env.example +++ b/workbench/.env.example @@ -1,8 +1,8 @@ APP_NAME=Laravel APP_ENV=local -APP_KEY=AckfSECXIvnK5r28GVIWUAxmbBSjTsmF +APP_KEY= APP_DEBUG=true -APP_URL=http://localhost +APP_URL=https://eclipse-catalogue-plugin.lndo.site APP_LOCALE=en APP_FALLBACK_LOCALE=en @@ -21,23 +21,25 @@ LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=sqlite +DB_DATABASE=/app/workbench/database/database.sqlite # DB_HOST=127.0.0.1 # DB_PORT=3306 -# DB_DATABASE=laravel # DB_USERNAME=root # DB_PASSWORD= -SESSION_DRIVER=cookie +SESSION_DRIVER=database SESSION_LIFETIME=120 SESSION_ENCRYPT=false SESSION_PATH=/ -SESSION_DOMAIN=null +SESSION_SECURE_COOKIE=false +SESSION_HTTP_ONLY=true +SESSION_SAME_SITE=lax BROADCAST_CONNECTION=log FILESYSTEM_DISK=local -QUEUE_CONNECTION=database +QUEUE_CONNECTION=sync -CACHE_STORE=database +CACHE_STORE=array # CACHE_PREFIX= MEMCACHED_HOST=127.0.0.1 diff --git a/workbench/.gitignore b/workbench/.gitignore index 3badc3a..3a085d8 100644 --- a/workbench/.gitignore +++ b/workbench/.gitignore @@ -1,3 +1,24 @@ .env .env.dusk -storage +storage/app/* +!storage/app/.gitkeep +!storage/app/public/ +storage/app/public/* +!storage/app/public/.gitkeep +storage/framework/sessions/* +!storage/framework/sessions/.gitkeep +storage/framework/testing/* +!storage/framework/testing/.gitkeep +storage/framework/views/* +!storage/framework/views/.gitkeep +storage/logs/* +!storage/logs/.gitkeep +stubs/ +resources/views/vendor/ +lang/ +vendor +public/build +public/hot +/public/css +/public/js +/public/fonts diff --git a/workbench/app/Http/Middleware/WorkbenchBootstrap.php b/workbench/app/Http/Middleware/WorkbenchBootstrap.php new file mode 100644 index 0000000..ac6fadb --- /dev/null +++ b/workbench/app/Http/Middleware/WorkbenchBootstrap.php @@ -0,0 +1,180 @@ +check()) { + $user = User::query()->first(); + + if (! $user) { + try { + $user = User::query()->firstOrCreate( + ['email' => 'test@example.com'], + [ + 'name' => 'Admin User', + 'password' => Hash::make('password'), + 'email_verified_at' => now(), + ], + ); + } catch (Throwable $e) { + Log::error('[Workbench] User creation failed', ['message' => $e->getMessage()]); + // In case of a race/unique constraint, fetch the existing one + $user = User::query()->where('email', 'test@example.com')->first(); + } + } + + if ($user) { + $this->bootstrapPermissionsAndAssign($user); + Auth::guard('web')->login($user); + $request->session()->regenerate(); + + if ($request->is('admin/login')) { + return redirect()->to('/admin'); + } + } + } + + return $next($request); + } + + private function bootstrapPermissionsAndAssign(User $user): void + { + // Use cache to prevent running this multiple times + $cacheKey = 'workbench:permissions:bootstrapped'; + + if (Cache::has($cacheKey)) { + // Just ensure user has roles if already bootstrapped + $this->ensureUserHasRoles($user); + + return; + } + + try { + // Use lock to prevent concurrent execution + Cache::lock('workbench:bootstrap-permissions', 30)->block(10, function () use ($user, $cacheKey) { + // Double-check inside the lock + if (Cache::has($cacheKey)) { + return; + } + + // Normalize guards first + DB::table('permissions')->whereNull('guard_name')->orWhere('guard_name', '')->update(['guard_name' => 'web']); + DB::table('roles')->whereNull('guard_name')->orWhere('guard_name', '')->update(['guard_name' => 'web']); + + // Generate Filament Shield permissions if none exist yet + if (Permission::query()->count() === 0) { + Artisan::call('shield:generate', [ + '--all' => true, + '--panel' => 'admin', + ]); + } + + // Reset caches/registrar to ensure guards are picked up + Artisan::call('permission:cache-reset'); + app(PermissionRegistrar::class)->forgetCachedPermissions(); + + // Ensure roles with correct guard + $this->ensureRolesHaveCorrectGuard(); + + // Create roles + $superAdmin = Role::firstOrCreate(['name' => 'super_admin', 'guard_name' => 'web']); + $panelUser = Role::firstOrCreate(['name' => 'panel_user', 'guard_name' => 'web']); + + // Only assign permissions if the role doesn't already have them + $this->assignPermissionsToRole($superAdmin); + + // Assign roles to user + $this->ensureUserHasRoles($user); + + // Mark as bootstrapped (cache for 1 hour) + Cache::put($cacheKey, true, 3600); + }); + } catch (Throwable $e) { + Log::error('[Workbench] Bootstrap permissions failed', ['message' => $e->getMessage()]); + } + } + + private function ensureRolesHaveCorrectGuard(): void + { + $existingSuper = Role::where('name', 'super_admin')->first(); + if ($existingSuper && $existingSuper->guard_name !== 'web') { + $existingSuper->guard_name = 'web'; + $existingSuper->save(); + } + + $existingPanel = Role::where('name', 'panel_user')->first(); + if ($existingPanel && $existingPanel->guard_name !== 'web') { + $existingPanel->guard_name = 'web'; + $existingPanel->save(); + } + } + + private function assignPermissionsToRole(Role $role): void + { + // Check if role already has permissions to avoid duplicate inserts + if ($role->permissions()->count() > 0) { + return; + } + + $permissions = Permission::query()->where('guard_name', 'web')->get(); + if ($permissions->isNotEmpty()) { + // Use DB transaction to ensure atomicity + DB::transaction(function () use ($role, $permissions) { + // Clear existing permissions first to avoid duplicates + $role->permissions()->detach(); + + // Batch insert to avoid individual constraint violations + $pivotData = $permissions->map(function ($permission) use ($role) { + return [ + 'role_id' => $role->id, + 'permission_id' => $permission->id, + ]; + })->toArray(); + + // Use insert ignore equivalent for SQLite + foreach ($pivotData as $data) { + DB::table('role_has_permissions') + ->insertOrIgnore($data); + } + }); + } + } + + private function ensureUserHasRoles(User $user): void + { + $superAdmin = Role::where('name', 'super_admin')->where('guard_name', 'web')->first(); + $panelUser = Role::where('name', 'panel_user')->where('guard_name', 'web')->first(); + + $rolesToAssign = collect([$superAdmin, $panelUser]) + ->filter() + ->pluck('name') + ->toArray(); + + if (! empty($rolesToAssign)) { + // Only sync if user doesn't already have these roles + $existingRoles = $user->roles()->pluck('name')->toArray(); + $missingRoles = array_diff($rolesToAssign, $existingRoles); + + if (! empty($missingRoles)) { + $user->assignRole($missingRoles); + } + } + } +} diff --git a/workbench/app/Models/User.php b/workbench/app/Models/User.php index 6827662..a660743 100644 --- a/workbench/app/Models/User.php +++ b/workbench/app/Models/User.php @@ -2,16 +2,12 @@ namespace Workbench\App\Models; -use Filament\Models\Contracts\FilamentUser; -use Filament\Panel; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Spatie\Permission\Traits\HasRoles; -use Workbench\Database\Factories\UserFactory; -class User extends Authenticatable implements FilamentUser +class User extends Authenticatable { use HasFactory, HasRoles, Notifiable; @@ -37,27 +33,15 @@ class User extends Authenticatable implements FilamentUser ]; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'email_verified_at' => 'datetime', - 'password' => 'hashed', - ]; - - protected static function newFactory(): UserFactory - { - return UserFactory::new(); - } - - public function canAccessPanel(Panel $panel): bool - { - return true; - } - - public function sites(): BelongsToMany + protected function casts(): array { - return $this->belongsToMany(Site::class, 'site_has_user'); + return [ + 'email_verified_at' => 'datetime', + 'password' => 'hashed', + ]; } -} +} \ No newline at end of file diff --git a/workbench/app/Policies/CategoryPolicy.php b/workbench/app/Policies/CategoryPolicy.php new file mode 100644 index 0000000..0429eff --- /dev/null +++ b/workbench/app/Policies/CategoryPolicy.php @@ -0,0 +1,75 @@ +can('view_any_category'); + } + + public function view(AuthUser $authUser, Category $category): bool + { + return $authUser->can('view_category'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_category'); + } + + public function update(AuthUser $authUser, Category $category): bool + { + return $authUser->can('update_category'); + } + + public function restore(AuthUser $authUser, Category $category): bool + { + return $authUser->can('restore_category'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_category'); + } + + public function replicate(AuthUser $authUser, Category $category): bool + { + return $authUser->can('replicate_category'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_category'); + } + + public function delete(AuthUser $authUser, Category $category): bool + { + return $authUser->can('delete_category'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_category'); + } + + public function forceDelete(AuthUser $authUser, Category $category): bool + { + return $authUser->can('force_delete_category'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_category'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/GroupPolicy.php b/workbench/app/Policies/GroupPolicy.php new file mode 100644 index 0000000..ccb4d2a --- /dev/null +++ b/workbench/app/Policies/GroupPolicy.php @@ -0,0 +1,75 @@ +can('view_any_group'); + } + + public function view(AuthUser $authUser, Group $group): bool + { + return $authUser->can('view_group'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_group'); + } + + public function update(AuthUser $authUser, Group $group): bool + { + return $authUser->can('update_group'); + } + + public function restore(AuthUser $authUser, Group $group): bool + { + return $authUser->can('restore_group'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_group'); + } + + public function replicate(AuthUser $authUser, Group $group): bool + { + return $authUser->can('replicate_group'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_group'); + } + + public function delete(AuthUser $authUser, Group $group): bool + { + return $authUser->can('delete_group'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_group'); + } + + public function forceDelete(AuthUser $authUser, Group $group): bool + { + return $authUser->can('force_delete_group'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_group'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/MeasureUnitPolicy.php b/workbench/app/Policies/MeasureUnitPolicy.php new file mode 100644 index 0000000..cfeb64f --- /dev/null +++ b/workbench/app/Policies/MeasureUnitPolicy.php @@ -0,0 +1,75 @@ +can('view_any_measure_unit'); + } + + public function view(AuthUser $authUser, MeasureUnit $measureUnit): bool + { + return $authUser->can('view_measure_unit'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_measure_unit'); + } + + public function update(AuthUser $authUser, MeasureUnit $measureUnit): bool + { + return $authUser->can('update_measure_unit'); + } + + public function restore(AuthUser $authUser, MeasureUnit $measureUnit): bool + { + return $authUser->can('restore_measure_unit'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_measure_unit'); + } + + public function replicate(AuthUser $authUser, MeasureUnit $measureUnit): bool + { + return $authUser->can('replicate_measure_unit'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_measure_unit'); + } + + public function delete(AuthUser $authUser, MeasureUnit $measureUnit): bool + { + return $authUser->can('delete_measure_unit'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_measure_unit'); + } + + public function forceDelete(AuthUser $authUser, MeasureUnit $measureUnit): bool + { + return $authUser->can('force_delete_measure_unit'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_measure_unit'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/PriceListPolicy.php b/workbench/app/Policies/PriceListPolicy.php new file mode 100644 index 0000000..ecb0ee6 --- /dev/null +++ b/workbench/app/Policies/PriceListPolicy.php @@ -0,0 +1,75 @@ +can('view_any_price_list'); + } + + public function view(AuthUser $authUser, PriceList $priceList): bool + { + return $authUser->can('view_price_list'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_price_list'); + } + + public function update(AuthUser $authUser, PriceList $priceList): bool + { + return $authUser->can('update_price_list'); + } + + public function restore(AuthUser $authUser, PriceList $priceList): bool + { + return $authUser->can('restore_price_list'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_price_list'); + } + + public function replicate(AuthUser $authUser, PriceList $priceList): bool + { + return $authUser->can('replicate_price_list'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_price_list'); + } + + public function delete(AuthUser $authUser, PriceList $priceList): bool + { + return $authUser->can('delete_price_list'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_price_list'); + } + + public function forceDelete(AuthUser $authUser, PriceList $priceList): bool + { + return $authUser->can('force_delete_price_list'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_price_list'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/ProductPolicy.php b/workbench/app/Policies/ProductPolicy.php new file mode 100644 index 0000000..52cc309 --- /dev/null +++ b/workbench/app/Policies/ProductPolicy.php @@ -0,0 +1,75 @@ +can('view_any_product'); + } + + public function view(AuthUser $authUser, Product $product): bool + { + return $authUser->can('view_product'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_product'); + } + + public function update(AuthUser $authUser, Product $product): bool + { + return $authUser->can('update_product'); + } + + public function restore(AuthUser $authUser, Product $product): bool + { + return $authUser->can('restore_product'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_product'); + } + + public function replicate(AuthUser $authUser, Product $product): bool + { + return $authUser->can('replicate_product'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_product'); + } + + public function delete(AuthUser $authUser, Product $product): bool + { + return $authUser->can('delete_product'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_product'); + } + + public function forceDelete(AuthUser $authUser, Product $product): bool + { + return $authUser->can('force_delete_product'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_product'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/ProductStatusPolicy.php b/workbench/app/Policies/ProductStatusPolicy.php new file mode 100644 index 0000000..e0b0e2d --- /dev/null +++ b/workbench/app/Policies/ProductStatusPolicy.php @@ -0,0 +1,75 @@ +can('view_any_product_status'); + } + + public function view(AuthUser $authUser, ProductStatus $productStatus): bool + { + return $authUser->can('view_product_status'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_product_status'); + } + + public function update(AuthUser $authUser, ProductStatus $productStatus): bool + { + return $authUser->can('update_product_status'); + } + + public function restore(AuthUser $authUser, ProductStatus $productStatus): bool + { + return $authUser->can('restore_product_status'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_product_status'); + } + + public function replicate(AuthUser $authUser, ProductStatus $productStatus): bool + { + return $authUser->can('replicate_product_status'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_product_status'); + } + + public function delete(AuthUser $authUser, ProductStatus $productStatus): bool + { + return $authUser->can('delete_product_status'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_product_status'); + } + + public function forceDelete(AuthUser $authUser, ProductStatus $productStatus): bool + { + return $authUser->can('force_delete_product_status'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_product_status'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/ProductTypePolicy.php b/workbench/app/Policies/ProductTypePolicy.php new file mode 100644 index 0000000..cd70a3a --- /dev/null +++ b/workbench/app/Policies/ProductTypePolicy.php @@ -0,0 +1,75 @@ +can('view_any_product_type'); + } + + public function view(AuthUser $authUser, ProductType $productType): bool + { + return $authUser->can('view_product_type'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_product_type'); + } + + public function update(AuthUser $authUser, ProductType $productType): bool + { + return $authUser->can('update_product_type'); + } + + public function restore(AuthUser $authUser, ProductType $productType): bool + { + return $authUser->can('restore_product_type'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_product_type'); + } + + public function replicate(AuthUser $authUser, ProductType $productType): bool + { + return $authUser->can('replicate_product_type'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_product_type'); + } + + public function delete(AuthUser $authUser, ProductType $productType): bool + { + return $authUser->can('delete_product_type'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_product_type'); + } + + public function forceDelete(AuthUser $authUser, ProductType $productType): bool + { + return $authUser->can('force_delete_product_type'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_product_type'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/PropertyPolicy.php b/workbench/app/Policies/PropertyPolicy.php new file mode 100644 index 0000000..56499fe --- /dev/null +++ b/workbench/app/Policies/PropertyPolicy.php @@ -0,0 +1,75 @@ +can('view_any_property'); + } + + public function view(AuthUser $authUser, Property $property): bool + { + return $authUser->can('view_property'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_property'); + } + + public function update(AuthUser $authUser, Property $property): bool + { + return $authUser->can('update_property'); + } + + public function restore(AuthUser $authUser, Property $property): bool + { + return $authUser->can('restore_property'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_property'); + } + + public function replicate(AuthUser $authUser, Property $property): bool + { + return $authUser->can('replicate_property'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_property'); + } + + public function delete(AuthUser $authUser, Property $property): bool + { + return $authUser->can('delete_property'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_property'); + } + + public function forceDelete(AuthUser $authUser, Property $property): bool + { + return $authUser->can('force_delete_property'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_property'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/PropertyValuePolicy.php b/workbench/app/Policies/PropertyValuePolicy.php new file mode 100644 index 0000000..429c974 --- /dev/null +++ b/workbench/app/Policies/PropertyValuePolicy.php @@ -0,0 +1,75 @@ +can('view_any_property_value'); + } + + public function view(AuthUser $authUser, PropertyValue $propertyValue): bool + { + return $authUser->can('view_property_value'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_property_value'); + } + + public function update(AuthUser $authUser, PropertyValue $propertyValue): bool + { + return $authUser->can('update_property_value'); + } + + public function restore(AuthUser $authUser, PropertyValue $propertyValue): bool + { + return $authUser->can('restore_property_value'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_property_value'); + } + + public function replicate(AuthUser $authUser, PropertyValue $propertyValue): bool + { + return $authUser->can('replicate_property_value'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_property_value'); + } + + public function delete(AuthUser $authUser, PropertyValue $propertyValue): bool + { + return $authUser->can('delete_property_value'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_property_value'); + } + + public function forceDelete(AuthUser $authUser, PropertyValue $propertyValue): bool + { + return $authUser->can('force_delete_property_value'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_property_value'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/RolePolicy.php b/workbench/app/Policies/RolePolicy.php new file mode 100644 index 0000000..151a1c3 --- /dev/null +++ b/workbench/app/Policies/RolePolicy.php @@ -0,0 +1,75 @@ +can('view_any_role'); + } + + public function view(AuthUser $authUser, Role $role): bool + { + return $authUser->can('view_role'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_role'); + } + + public function update(AuthUser $authUser, Role $role): bool + { + return $authUser->can('update_role'); + } + + public function restore(AuthUser $authUser, Role $role): bool + { + return $authUser->can('restore_role'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_role'); + } + + public function replicate(AuthUser $authUser, Role $role): bool + { + return $authUser->can('replicate_role'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_role'); + } + + public function delete(AuthUser $authUser, Role $role): bool + { + return $authUser->can('delete_role'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_role'); + } + + public function forceDelete(AuthUser $authUser, Role $role): bool + { + return $authUser->can('force_delete_role'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_role'); + } + +} \ No newline at end of file diff --git a/workbench/app/Policies/TaxClassPolicy.php b/workbench/app/Policies/TaxClassPolicy.php new file mode 100644 index 0000000..6ccd740 --- /dev/null +++ b/workbench/app/Policies/TaxClassPolicy.php @@ -0,0 +1,75 @@ +can('view_any_tax_class'); + } + + public function view(AuthUser $authUser, TaxClass $taxClass): bool + { + return $authUser->can('view_tax_class'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('create_tax_class'); + } + + public function update(AuthUser $authUser, TaxClass $taxClass): bool + { + return $authUser->can('update_tax_class'); + } + + public function restore(AuthUser $authUser, TaxClass $taxClass): bool + { + return $authUser->can('restore_tax_class'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('restore_any_tax_class'); + } + + public function replicate(AuthUser $authUser, TaxClass $taxClass): bool + { + return $authUser->can('replicate_tax_class'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('reorder_tax_class'); + } + + public function delete(AuthUser $authUser, TaxClass $taxClass): bool + { + return $authUser->can('delete_tax_class'); + } + + public function deleteAny(AuthUser $authUser): bool + { + return $authUser->can('delete_any_tax_class'); + } + + public function forceDelete(AuthUser $authUser, TaxClass $taxClass): bool + { + return $authUser->can('force_delete_tax_class'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('force_delete_any_tax_class'); + } + +} \ No newline at end of file diff --git a/workbench/app/Providers/AdminPanelProvider.php b/workbench/app/Providers/AdminPanelProvider.php index 3a65f0d..16b0f3d 100644 --- a/workbench/app/Providers/AdminPanelProvider.php +++ b/workbench/app/Providers/AdminPanelProvider.php @@ -10,16 +10,15 @@ use Filament\Pages\Dashboard; use Filament\Panel; use Filament\PanelProvider; -use Filament\Support\Facades\FilamentView; use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; use Illuminate\Cookie\Middleware\EncryptCookies; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken; use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Session\Middleware\AuthenticateSession; use Illuminate\Session\Middleware\StartSession; -use Illuminate\Support\Facades\Blade; use Illuminate\View\Middleware\ShareErrorsFromSession; use LaraZeus\SpatieTranslatable\SpatieTranslatablePlugin; +use Workbench\App\Http\Middleware\WorkbenchBootstrap; class AdminPanelProvider extends PanelProvider { @@ -40,6 +39,7 @@ public function panel(Panel $panel): Panel SubstituteBindings::class, DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, + WorkbenchBootstrap::class, ]) ->authMiddleware([ Authenticate::class, @@ -50,6 +50,7 @@ public function panel(Panel $panel): Panel SpatieTranslatablePlugin::make() ->defaultLocales(['en']), ]) + ->viteTheme(false) ->pages([ Dashboard::class, ]); @@ -58,7 +59,5 @@ public function panel(Panel $panel): Panel public function register(): void { parent::register(); - - FilamentView::registerRenderHook('panels::body.end', fn (): string => Blade::render("@vite('resources/js/app.js')")); } -} +} \ No newline at end of file diff --git a/workbench/app/Providers/AuthServiceProvider.php b/workbench/app/Providers/AuthServiceProvider.php new file mode 100644 index 0000000..e047e85 --- /dev/null +++ b/workbench/app/Providers/AuthServiceProvider.php @@ -0,0 +1,25 @@ + + */ + protected $policies = [ + // + ]; + + /** + * Register any authentication / authorization services. + */ + public function boot(): void + { + // + } +} diff --git a/workbench/app/Providers/WorkbenchServiceProvider.php b/workbench/app/Providers/WorkbenchServiceProvider.php index 1f5c51e..4a70d57 100644 --- a/workbench/app/Providers/WorkbenchServiceProvider.php +++ b/workbench/app/Providers/WorkbenchServiceProvider.php @@ -2,8 +2,11 @@ namespace Workbench\App\Providers; +use BezhanSalleh\FilamentShield\FilamentShieldServiceProvider; +use Filament\FilamentServiceProvider; use Illuminate\Support\ServiceProvider; -use Workbench\App\Models\Site; +use Livewire\LivewireServiceProvider; +use Spatie\Permission\PermissionServiceProvider; class WorkbenchServiceProvider extends ServiceProvider { @@ -12,7 +15,12 @@ class WorkbenchServiceProvider extends ServiceProvider */ public function register(): void { + $this->app->register(PermissionServiceProvider::class); + $this->app->register(FilamentShieldServiceProvider::class); + $this->app->register(LivewireServiceProvider::class); + $this->app->register(FilamentServiceProvider::class); $this->app->register(AdminPanelProvider::class); + $this->app->register(AuthServiceProvider::class); } /** @@ -20,9 +28,6 @@ public function register(): void */ public function boot(): void { - config([ - 'eclipse-catalogue.tenancy.model' => Site::class, - 'eclipse-catalogue.tenancy.foreign_key' => 'site_id', - ]); + // } -} +} \ No newline at end of file diff --git a/workbench/bootstrap/app.php b/workbench/bootstrap/app.php index 6ead72a..01af2b1 100644 --- a/workbench/bootstrap/app.php +++ b/workbench/bootstrap/app.php @@ -3,10 +3,12 @@ use Illuminate\Foundation\Application; use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Middleware; +use Workbench\App\Providers\WorkbenchServiceProvider; -use function Orchestra\Testbench\default_skeleton_path; - -return Application::configure(basePath: $APP_BASE_PATH ?? default_skeleton_path()) +return Application::configure(basePath: $APP_BASE_PATH ?? dirname(__DIR__)) + ->withProviders([ + WorkbenchServiceProvider::class, + ]) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', @@ -16,4 +18,4 @@ }) ->withExceptions(function (Exceptions $exceptions) { // - })->create(); + })->create(); \ No newline at end of file diff --git a/workbench/bootstrap/cache/packages.php b/workbench/bootstrap/cache/packages.php new file mode 100755 index 0000000..077780c --- /dev/null +++ b/workbench/bootstrap/cache/packages.php @@ -0,0 +1,270 @@ + + array ( + 'aliases' => + array ( + 'EloquentSerialize' => 'AnourValar\\EloquentSerialize\\Facades\\EloquentSerializeFacade', + ), + ), + 'bezhansalleh/filament-plugin-essentials' => + array ( + 'providers' => + array ( + 0 => 'BezhanSalleh\\PluginEssentials\\PluginEssentialsServiceProvider', + ), + ), + 'bezhansalleh/filament-shield' => + array ( + 'aliases' => + array ( + 'FilamentShield' => 'BezhanSalleh\\FilamentShield\\Facades\\FilamentShield', + ), + 'providers' => + array ( + 0 => 'BezhanSalleh\\FilamentShield\\FilamentShieldServiceProvider', + ), + ), + 'blade-ui-kit/blade-heroicons' => + array ( + 'providers' => + array ( + 0 => 'BladeUI\\Heroicons\\BladeHeroiconsServiceProvider', + ), + ), + 'blade-ui-kit/blade-icons' => + array ( + 'providers' => + array ( + 0 => 'BladeUI\\Icons\\BladeIconsServiceProvider', + ), + ), + 'eclipsephp/common' => + array ( + 'providers' => + array ( + 0 => 'Eclipse\\Common\\CommonServiceProvider', + ), + ), + 'eclipsephp/world-plugin' => + array ( + 'providers' => + array ( + 0 => 'Eclipse\\World\\EclipseWorldServiceProvider', + ), + ), + 'filament/actions' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Actions\\ActionsServiceProvider', + ), + ), + 'filament/filament' => + array ( + 'providers' => + array ( + 0 => 'Filament\\FilamentServiceProvider', + ), + ), + 'filament/forms' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Forms\\FormsServiceProvider', + ), + ), + 'filament/infolists' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Infolists\\InfolistsServiceProvider', + ), + ), + 'filament/notifications' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Notifications\\NotificationsServiceProvider', + ), + ), + 'filament/schemas' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Schemas\\SchemasServiceProvider', + ), + ), + 'filament/spatie-laravel-settings-plugin' => + array ( + 'providers' => + array ( + 0 => 'Filament\\SpatieLaravelSettingsPluginServiceProvider', + ), + ), + 'filament/support' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Support\\SupportServiceProvider', + ), + ), + 'filament/tables' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Tables\\TablesServiceProvider', + ), + ), + 'filament/widgets' => + array ( + 'providers' => + array ( + 0 => 'Filament\\Widgets\\WidgetsServiceProvider', + ), + ), + 'kirschbaum-development/eloquent-power-joins' => + array ( + 'providers' => + array ( + 0 => 'Kirschbaum\\PowerJoins\\PowerJoinsServiceProvider', + ), + ), + 'lara-zeus/spatie-translatable' => + array ( + 'providers' => + array ( + 0 => 'LaraZeus\\SpatieTranslatable\\SpatieTranslatableServiceProvider', + ), + ), + 'laravel/pail' => + array ( + 'providers' => + array ( + 0 => 'Laravel\\Pail\\PailServiceProvider', + ), + ), + 'laravel/scout' => + array ( + 'providers' => + array ( + 0 => 'Laravel\\Scout\\ScoutServiceProvider', + ), + ), + 'laravel/tinker' => + array ( + 'providers' => + array ( + 0 => 'Laravel\\Tinker\\TinkerServiceProvider', + ), + ), + 'livewire/livewire' => + array ( + 'aliases' => + array ( + 'Livewire' => 'Livewire\\Livewire', + ), + 'providers' => + array ( + 0 => 'Livewire\\LivewireServiceProvider', + ), + ), + 'nben/filament-record-nav' => + array ( + 'aliases' => + array ( + 'FilamentRecordNav' => 'Nben\\FilamentRecordNav\\Facades\\FilamentRecordNav', + ), + 'providers' => + array ( + 0 => 'Nben\\FilamentRecordNav\\FilamentRecordNavServiceProvider', + ), + ), + 'nesbot/carbon' => + array ( + 'providers' => + array ( + 0 => 'Carbon\\Laravel\\ServiceProvider', + ), + ), + 'nunomaduro/collision' => + array ( + 'providers' => + array ( + 0 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', + ), + ), + 'nunomaduro/termwind' => + array ( + 'providers' => + array ( + 0 => 'Termwind\\Laravel\\TermwindServiceProvider', + ), + ), + 'orchestra/canvas' => + array ( + 'providers' => + array ( + 0 => 'Orchestra\\Canvas\\LaravelServiceProvider', + ), + ), + 'orchestra/canvas-core' => + array ( + 'providers' => + array ( + 0 => 'Orchestra\\Canvas\\Core\\LaravelServiceProvider', + ), + ), + 'ryangjchandler/blade-capture-directive' => + array ( + 'aliases' => + array ( + 'BladeCaptureDirective' => 'RyanChandler\\BladeCaptureDirective\\Facades\\BladeCaptureDirective', + ), + 'providers' => + array ( + 0 => 'RyanChandler\\BladeCaptureDirective\\BladeCaptureDirectiveServiceProvider', + ), + ), + 'solution-forest/filament-tree' => + array ( + 'providers' => + array ( + 0 => 'SolutionForest\\FilamentTree\\FilamentTreeServiceProvider', + ), + ), + 'spatie/laravel-medialibrary' => + array ( + 'providers' => + array ( + 0 => 'Spatie\\MediaLibrary\\MediaLibraryServiceProvider', + ), + ), + 'spatie/laravel-permission' => + array ( + 'providers' => + array ( + 0 => 'Spatie\\Permission\\PermissionServiceProvider', + ), + ), + 'spatie/laravel-settings' => + array ( + 'providers' => + array ( + 0 => 'Spatie\\LaravelSettings\\LaravelSettingsServiceProvider', + ), + ), + 'spatie/laravel-translatable' => + array ( + 'providers' => + array ( + 0 => 'Spatie\\Translatable\\TranslatableServiceProvider', + ), + ), + 'eclipsephp/catalogue-plugin' => + array ( + 'providers' => + array ( + 0 => 'Eclipse\\Catalogue\\CatalogueServiceProvider', + ), + ), +); \ No newline at end of file diff --git a/workbench/bootstrap/cache/services.php b/workbench/bootstrap/cache/services.php new file mode 100755 index 0000000..1634662 --- /dev/null +++ b/workbench/bootstrap/cache/services.php @@ -0,0 +1,354 @@ + + array ( + 0 => 'Illuminate\\Auth\\AuthServiceProvider', + 1 => 'Illuminate\\Broadcasting\\BroadcastServiceProvider', + 2 => 'Illuminate\\Bus\\BusServiceProvider', + 3 => 'Illuminate\\Cache\\CacheServiceProvider', + 4 => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 5 => 'Illuminate\\Concurrency\\ConcurrencyServiceProvider', + 6 => 'Illuminate\\Cookie\\CookieServiceProvider', + 7 => 'Illuminate\\Database\\DatabaseServiceProvider', + 8 => 'Illuminate\\Encryption\\EncryptionServiceProvider', + 9 => 'Illuminate\\Filesystem\\FilesystemServiceProvider', + 10 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider', + 11 => 'Illuminate\\Hashing\\HashServiceProvider', + 12 => 'Illuminate\\Mail\\MailServiceProvider', + 13 => 'Illuminate\\Notifications\\NotificationServiceProvider', + 14 => 'Illuminate\\Pagination\\PaginationServiceProvider', + 15 => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider', + 16 => 'Illuminate\\Pipeline\\PipelineServiceProvider', + 17 => 'Illuminate\\Queue\\QueueServiceProvider', + 18 => 'Illuminate\\Redis\\RedisServiceProvider', + 19 => 'Illuminate\\Session\\SessionServiceProvider', + 20 => 'Illuminate\\Translation\\TranslationServiceProvider', + 21 => 'Illuminate\\Validation\\ValidationServiceProvider', + 22 => 'Illuminate\\View\\ViewServiceProvider', + 23 => 'BezhanSalleh\\PluginEssentials\\PluginEssentialsServiceProvider', + 24 => 'BezhanSalleh\\FilamentShield\\FilamentShieldServiceProvider', + 25 => 'BladeUI\\Heroicons\\BladeHeroiconsServiceProvider', + 26 => 'BladeUI\\Icons\\BladeIconsServiceProvider', + 27 => 'Eclipse\\Common\\CommonServiceProvider', + 28 => 'Eclipse\\World\\EclipseWorldServiceProvider', + 29 => 'Filament\\Actions\\ActionsServiceProvider', + 30 => 'Filament\\FilamentServiceProvider', + 31 => 'Filament\\Forms\\FormsServiceProvider', + 32 => 'Filament\\Infolists\\InfolistsServiceProvider', + 33 => 'Filament\\Notifications\\NotificationsServiceProvider', + 34 => 'Filament\\Schemas\\SchemasServiceProvider', + 35 => 'Filament\\SpatieLaravelSettingsPluginServiceProvider', + 36 => 'Filament\\Support\\SupportServiceProvider', + 37 => 'Filament\\Tables\\TablesServiceProvider', + 38 => 'Filament\\Widgets\\WidgetsServiceProvider', + 39 => 'Kirschbaum\\PowerJoins\\PowerJoinsServiceProvider', + 40 => 'LaraZeus\\SpatieTranslatable\\SpatieTranslatableServiceProvider', + 41 => 'Laravel\\Pail\\PailServiceProvider', + 42 => 'Laravel\\Scout\\ScoutServiceProvider', + 43 => 'Laravel\\Tinker\\TinkerServiceProvider', + 44 => 'Livewire\\LivewireServiceProvider', + 45 => 'Nben\\FilamentRecordNav\\FilamentRecordNavServiceProvider', + 46 => 'Carbon\\Laravel\\ServiceProvider', + 47 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', + 48 => 'Termwind\\Laravel\\TermwindServiceProvider', + 49 => 'Orchestra\\Canvas\\LaravelServiceProvider', + 50 => 'Orchestra\\Canvas\\Core\\LaravelServiceProvider', + 51 => 'RyanChandler\\BladeCaptureDirective\\BladeCaptureDirectiveServiceProvider', + 52 => 'SolutionForest\\FilamentTree\\FilamentTreeServiceProvider', + 53 => 'Spatie\\MediaLibrary\\MediaLibraryServiceProvider', + 54 => 'Spatie\\Permission\\PermissionServiceProvider', + 55 => 'Spatie\\LaravelSettings\\LaravelSettingsServiceProvider', + 56 => 'Spatie\\Translatable\\TranslatableServiceProvider', + 57 => 'Eclipse\\Catalogue\\CatalogueServiceProvider', + 58 => 'Workbench\\App\\Providers\\WorkbenchServiceProvider', + ), + 'eager' => + array ( + 0 => 'Illuminate\\Auth\\AuthServiceProvider', + 1 => 'Illuminate\\Cookie\\CookieServiceProvider', + 2 => 'Illuminate\\Database\\DatabaseServiceProvider', + 3 => 'Illuminate\\Encryption\\EncryptionServiceProvider', + 4 => 'Illuminate\\Filesystem\\FilesystemServiceProvider', + 5 => 'Illuminate\\Foundation\\Providers\\FoundationServiceProvider', + 6 => 'Illuminate\\Notifications\\NotificationServiceProvider', + 7 => 'Illuminate\\Pagination\\PaginationServiceProvider', + 8 => 'Illuminate\\Session\\SessionServiceProvider', + 9 => 'Illuminate\\View\\ViewServiceProvider', + 10 => 'BezhanSalleh\\PluginEssentials\\PluginEssentialsServiceProvider', + 11 => 'BezhanSalleh\\FilamentShield\\FilamentShieldServiceProvider', + 12 => 'BladeUI\\Heroicons\\BladeHeroiconsServiceProvider', + 13 => 'BladeUI\\Icons\\BladeIconsServiceProvider', + 14 => 'Eclipse\\Common\\CommonServiceProvider', + 15 => 'Eclipse\\World\\EclipseWorldServiceProvider', + 16 => 'Filament\\Actions\\ActionsServiceProvider', + 17 => 'Filament\\FilamentServiceProvider', + 18 => 'Filament\\Forms\\FormsServiceProvider', + 19 => 'Filament\\Infolists\\InfolistsServiceProvider', + 20 => 'Filament\\Notifications\\NotificationsServiceProvider', + 21 => 'Filament\\Schemas\\SchemasServiceProvider', + 22 => 'Filament\\SpatieLaravelSettingsPluginServiceProvider', + 23 => 'Filament\\Support\\SupportServiceProvider', + 24 => 'Filament\\Tables\\TablesServiceProvider', + 25 => 'Filament\\Widgets\\WidgetsServiceProvider', + 26 => 'Kirschbaum\\PowerJoins\\PowerJoinsServiceProvider', + 27 => 'LaraZeus\\SpatieTranslatable\\SpatieTranslatableServiceProvider', + 28 => 'Laravel\\Pail\\PailServiceProvider', + 29 => 'Laravel\\Scout\\ScoutServiceProvider', + 30 => 'Livewire\\LivewireServiceProvider', + 31 => 'Nben\\FilamentRecordNav\\FilamentRecordNavServiceProvider', + 32 => 'Carbon\\Laravel\\ServiceProvider', + 33 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', + 34 => 'Termwind\\Laravel\\TermwindServiceProvider', + 35 => 'RyanChandler\\BladeCaptureDirective\\BladeCaptureDirectiveServiceProvider', + 36 => 'SolutionForest\\FilamentTree\\FilamentTreeServiceProvider', + 37 => 'Spatie\\MediaLibrary\\MediaLibraryServiceProvider', + 38 => 'Spatie\\Permission\\PermissionServiceProvider', + 39 => 'Spatie\\LaravelSettings\\LaravelSettingsServiceProvider', + 40 => 'Spatie\\Translatable\\TranslatableServiceProvider', + 41 => 'Eclipse\\Catalogue\\CatalogueServiceProvider', + 42 => 'Workbench\\App\\Providers\\WorkbenchServiceProvider', + ), + 'deferred' => + array ( + 'Illuminate\\Broadcasting\\BroadcastManager' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider', + 'Illuminate\\Contracts\\Broadcasting\\Factory' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider', + 'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => 'Illuminate\\Broadcasting\\BroadcastServiceProvider', + 'Illuminate\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider', + 'Illuminate\\Contracts\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider', + 'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => 'Illuminate\\Bus\\BusServiceProvider', + 'Illuminate\\Bus\\BatchRepository' => 'Illuminate\\Bus\\BusServiceProvider', + 'Illuminate\\Bus\\DatabaseBatchRepository' => 'Illuminate\\Bus\\BusServiceProvider', + 'cache' => 'Illuminate\\Cache\\CacheServiceProvider', + 'cache.store' => 'Illuminate\\Cache\\CacheServiceProvider', + 'cache.psr6' => 'Illuminate\\Cache\\CacheServiceProvider', + 'memcached.connector' => 'Illuminate\\Cache\\CacheServiceProvider', + 'Illuminate\\Cache\\RateLimiter' => 'Illuminate\\Cache\\CacheServiceProvider', + 'Illuminate\\Foundation\\Console\\AboutCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Cache\\Console\\ClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Cache\\Console\\ForgetCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ClearCompiledCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Auth\\Console\\ClearResetsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ConfigCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ConfigClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ConfigShowCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\DbCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\MonitorCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\PruneCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\ShowCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\TableCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\WipeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\DownCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EnvironmentCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EnvironmentDecryptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EnvironmentEncryptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EventCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EventClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EventListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Concurrency\\Console\\InvokeSerializedClosureCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\KeyGenerateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\OptimizeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\OptimizeClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\PackageDiscoverCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Cache\\Console\\PruneStaleTagsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\ClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\ListFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\FlushFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\ForgetFailedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\ListenCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\MonitorCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\PruneBatchesCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\PruneFailedJobsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\RestartCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\RetryCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\RetryBatchCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Queue\\Console\\WorkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\RouteCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\RouteClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\RouteListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\DumpCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Seeds\\SeedCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleFinishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleRunCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleClearCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleTestCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleWorkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleInterruptCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\ShowModelCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\StorageLinkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\StorageUnlinkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\UpCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ViewCacheCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ViewClearCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ApiInstallCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\BroadcastingInstallCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Cache\\Console\\CacheTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\CastMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ChannelListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ChannelMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ClassMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ComponentMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ConfigMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ConfigPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ConsoleMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Routing\\Console\\ControllerMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\DocsCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EnumMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\EventGenerateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\EventMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ExceptionMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Database\\Console\\Factories\\FactoryMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\InterfaceMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\JobMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\JobMiddlewareMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\LangPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ListenerMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\MailMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Routing\\Console\\MiddlewareMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ModelMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\NotificationMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Notifications\\Console\\NotificationTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ObserverMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\PolicyMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ProviderMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Queue\\Console\\FailedTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Queue\\Console\\TableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Queue\\Console\\BatchesTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\RequestMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ResourceMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\RuleMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ScopeMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Database\\Console\\Seeds\\SeederMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Session\\Console\\SessionTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\ServeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\StubPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\TestMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Illuminate\\Foundation\\Console\\TraitMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\VendorPublishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Foundation\\Console\\ViewMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'migrator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'migration.repository' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'migration.creator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Migrations\\Migrator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\MigrateCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\FreshCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\InstallCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\RefreshCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\ResetCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\RollbackCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\StatusCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\Migrations\\MigrateMakeCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'composer' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Concurrency\\ConcurrencyManager' => 'Illuminate\\Concurrency\\ConcurrencyServiceProvider', + 'hash' => 'Illuminate\\Hashing\\HashServiceProvider', + 'hash.driver' => 'Illuminate\\Hashing\\HashServiceProvider', + 'mail.manager' => 'Illuminate\\Mail\\MailServiceProvider', + 'mailer' => 'Illuminate\\Mail\\MailServiceProvider', + 'Illuminate\\Mail\\Markdown' => 'Illuminate\\Mail\\MailServiceProvider', + 'auth.password' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider', + 'auth.password.broker' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider', + 'Illuminate\\Contracts\\Pipeline\\Hub' => 'Illuminate\\Pipeline\\PipelineServiceProvider', + 'pipeline' => 'Illuminate\\Pipeline\\PipelineServiceProvider', + 'queue' => 'Illuminate\\Queue\\QueueServiceProvider', + 'queue.connection' => 'Illuminate\\Queue\\QueueServiceProvider', + 'queue.failer' => 'Illuminate\\Queue\\QueueServiceProvider', + 'queue.listener' => 'Illuminate\\Queue\\QueueServiceProvider', + 'queue.worker' => 'Illuminate\\Queue\\QueueServiceProvider', + 'redis' => 'Illuminate\\Redis\\RedisServiceProvider', + 'redis.connection' => 'Illuminate\\Redis\\RedisServiceProvider', + 'translator' => 'Illuminate\\Translation\\TranslationServiceProvider', + 'translation.loader' => 'Illuminate\\Translation\\TranslationServiceProvider', + 'validator' => 'Illuminate\\Validation\\ValidationServiceProvider', + 'validation.presence' => 'Illuminate\\Validation\\ValidationServiceProvider', + 'Illuminate\\Contracts\\Validation\\UncompromisedVerifier' => 'Illuminate\\Validation\\ValidationServiceProvider', + 'command.tinker' => 'Laravel\\Tinker\\TinkerServiceProvider', + 'Orchestra\\Canvas\\Console\\CastMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ChannelMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ClassMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ComponentMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ConsoleMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ControllerMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\EnumMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\EventMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ExceptionMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\FactoryMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\InterfaceMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\JobMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\JobMiddlewareMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ListenerMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\MailMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\MiddlewareMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\MigrateMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ModelMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\NotificationMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ObserverMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\PolicyMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ProviderMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\RequestMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ResourceMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\RuleMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ScopeMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\SeederMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\TestMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\ViewMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\BatchesTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\CacheTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\FailedTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\NotificationTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\QueueTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\SessionTableCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\UserFactoryMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Console\\UserModelMakeCommand' => 'Orchestra\\Canvas\\LaravelServiceProvider', + 'Orchestra\\Canvas\\Core\\PresetManager' => 'Orchestra\\Canvas\\Core\\LaravelServiceProvider', + ), + 'when' => + array ( + 'Illuminate\\Broadcasting\\BroadcastServiceProvider' => + array ( + ), + 'Illuminate\\Bus\\BusServiceProvider' => + array ( + ), + 'Illuminate\\Cache\\CacheServiceProvider' => + array ( + ), + 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider' => + array ( + ), + 'Illuminate\\Concurrency\\ConcurrencyServiceProvider' => + array ( + ), + 'Illuminate\\Hashing\\HashServiceProvider' => + array ( + ), + 'Illuminate\\Mail\\MailServiceProvider' => + array ( + ), + 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider' => + array ( + ), + 'Illuminate\\Pipeline\\PipelineServiceProvider' => + array ( + ), + 'Illuminate\\Queue\\QueueServiceProvider' => + array ( + ), + 'Illuminate\\Redis\\RedisServiceProvider' => + array ( + ), + 'Illuminate\\Translation\\TranslationServiceProvider' => + array ( + ), + 'Illuminate\\Validation\\ValidationServiceProvider' => + array ( + ), + 'Laravel\\Tinker\\TinkerServiceProvider' => + array ( + ), + 'Orchestra\\Canvas\\LaravelServiceProvider' => + array ( + ), + 'Orchestra\\Canvas\\Core\\LaravelServiceProvider' => + array ( + ), + ), +); \ No newline at end of file diff --git a/workbench/bootstrap/cache/testbench.yaml b/workbench/bootstrap/cache/testbench.yaml new file mode 100644 index 0000000..e037997 --- /dev/null +++ b/workbench/bootstrap/cache/testbench.yaml @@ -0,0 +1,36 @@ +laravel: '@testbench' + +env: + - DB_CONNECTION=sqlite + - DB_DATABASE=/app/workbench/database/database.sqlite + - APP_KEY=base64:ZQvPGC7uVADkjOgtGIIuCI8u3/Pzu+VaRObIbHsgjCc= + - APP_ENV=local + - APP_DEBUG=true + - SESSION_DRIVER=database + - CACHE_STORE=database + - QUEUE_CONNECTION=sync + +providers: + - Workbench\App\Providers\WorkbenchServiceProvider + +migrations: + - workbench/database/migrations + - database/migrations + +workbench: + start: '/' + install: true + health: false + discovers: + web: true + api: false + commands: true + components: false + views: false + build: + - asset-publish + - create-sqlite-db + - db-wipe + - migrate-fresh + assets: + - laravel-assets \ No newline at end of file diff --git a/workbench/bootstrap/cache/testbench.yaml.backup b/workbench/bootstrap/cache/testbench.yaml.backup new file mode 100644 index 0000000..e037997 --- /dev/null +++ b/workbench/bootstrap/cache/testbench.yaml.backup @@ -0,0 +1,36 @@ +laravel: '@testbench' + +env: + - DB_CONNECTION=sqlite + - DB_DATABASE=/app/workbench/database/database.sqlite + - APP_KEY=base64:ZQvPGC7uVADkjOgtGIIuCI8u3/Pzu+VaRObIbHsgjCc= + - APP_ENV=local + - APP_DEBUG=true + - SESSION_DRIVER=database + - CACHE_STORE=database + - QUEUE_CONNECTION=sync + +providers: + - Workbench\App\Providers\WorkbenchServiceProvider + +migrations: + - workbench/database/migrations + - database/migrations + +workbench: + start: '/' + install: true + health: false + discovers: + web: true + api: false + commands: true + components: false + views: false + build: + - asset-publish + - create-sqlite-db + - db-wipe + - migrate-fresh + assets: + - laravel-assets \ No newline at end of file diff --git a/workbench/composer.json b/workbench/composer.json new file mode 100644 index 0000000..2c579b1 --- /dev/null +++ b/workbench/composer.json @@ -0,0 +1,9 @@ +{ + "name": "workbench/app", + "type": "project", + "autoload": { + "psr-4": { + "Workbench\\App\\": "app/" + } + } +} diff --git a/workbench/config/app.php b/workbench/config/app.php new file mode 100644 index 0000000..f467267 --- /dev/null +++ b/workbench/config/app.php @@ -0,0 +1,126 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | the application so that it's available within Artisan commands. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. The timezone + | is set to "UTC" by default as it is suitable for most use cases. + | + */ + + 'timezone' => env('APP_TIMEZONE', 'UTC'), + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by Laravel's translation / localization methods. This option can be + | set to any locale for which you plan to have translation strings. + | + */ + + 'locale' => env('APP_LOCALE', 'en'), + + 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), + + 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is utilized by Laravel's encryption services and should be set + | to a random, 32 character string to ensure that all encrypted values + | are secure. You should do this prior to deploying the application. + | + */ + + 'cipher' => 'AES-256-CBC', + + 'key' => env('APP_KEY'), + + 'previous_keys' => [ + ...array_filter( + explode(',', env('APP_PREVIOUS_KEYS', '')) + ), + ], + + /* + |-------------------------------------------------------------------------- + | Maintenance Mode Driver + |-------------------------------------------------------------------------- + | + | These configuration options determine the driver used to determine and + | manage Laravel's "maintenance mode" status. The "cache" driver will + | allow maintenance mode to be controlled across multiple machines. + | + | Supported drivers: "file", "cache" + | + */ + + 'maintenance' => [ + 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), + 'store' => env('APP_MAINTENANCE_STORE', 'database'), + ], + +]; diff --git a/workbench/config/auth.php b/workbench/config/auth.php new file mode 100644 index 0000000..df32bc3 --- /dev/null +++ b/workbench/config/auth.php @@ -0,0 +1,117 @@ + [ + 'guard' => env('AUTH_GUARD', 'web'), + 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | which utilizes session storage plus the Eloquent user provider. + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | If you have multiple user tables or models you may configure multiple + | providers to represent the model / table. These providers may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => env('AUTH_MODEL', User::class), + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | These configuration options specify the behavior of Laravel's password + | reset functionality, including the table utilized for token storage + | and the user provider that is invoked to actually retrieve users. + | + | The expiry time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | window expires and users are asked to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800), + +]; diff --git a/workbench/config/blade-heroicons.php b/workbench/config/blade-heroicons.php new file mode 100644 index 0000000..e517a97 --- /dev/null +++ b/workbench/config/blade-heroicons.php @@ -0,0 +1,57 @@ + 'heroicon', + + /* + |----------------------------------------------------------------- + | Fallback Icon + |----------------------------------------------------------------- + | + | This config option allows you to define a fallback + | icon when an icon in this set cannot be found. + | + */ + + 'fallback' => '', + + /* + |----------------------------------------------------------------- + | Default Set Classes + |----------------------------------------------------------------- + | + | This config option allows you to define some classes which + | will be applied by default to all icons within this set. + | + */ + + 'class' => '', + + /* + |----------------------------------------------------------------- + | Default Set Attributes + |----------------------------------------------------------------- + | + | This config option allows you to define some attributes which + | will be applied by default to all icons within this set. + | + */ + + 'attributes' => [ + // 'width' => 50, + // 'height' => 50, + ], + +]; diff --git a/workbench/config/blade-icons.php b/workbench/config/blade-icons.php new file mode 100644 index 0000000..5aade2a --- /dev/null +++ b/workbench/config/blade-icons.php @@ -0,0 +1,183 @@ + [ + + // 'default' => [ + // + // /* + // |----------------------------------------------------------------- + // | Icons Path + // |----------------------------------------------------------------- + // | + // | Provide the relative path from your app root to your SVG icons + // | directory. Icons are loaded recursively so there's no need to + // | list every sub-directory. + // | + // | Relative to the disk root when the disk option is set. + // | + // */ + // + // 'path' => 'resources/svg', + // + // /* + // |----------------------------------------------------------------- + // | Filesystem Disk + // |----------------------------------------------------------------- + // | + // | Optionally, provide a specific filesystem disk to read + // | icons from. When defining a disk, the "path" option + // | starts relatively from the disk root. + // | + // */ + // + // 'disk' => '', + // + // /* + // |----------------------------------------------------------------- + // | Default Prefix + // |----------------------------------------------------------------- + // | + // | This config option allows you to define a default prefix for + // | your icons. The dash separator will be applied automatically + // | to every icon name. It's required and needs to be unique. + // | + // */ + // + // 'prefix' => 'icon', + // + // /* + // |----------------------------------------------------------------- + // | Fallback Icon + // |----------------------------------------------------------------- + // | + // | This config option allows you to define a fallback + // | icon when an icon in this set cannot be found. + // | + // */ + // + // 'fallback' => '', + // + // /* + // |----------------------------------------------------------------- + // | Default Set Classes + // |----------------------------------------------------------------- + // | + // | This config option allows you to define some classes which + // | will be applied by default to all icons within this set. + // | + // */ + // + // 'class' => '', + // + // /* + // |----------------------------------------------------------------- + // | Default Set Attributes + // |----------------------------------------------------------------- + // | + // | This config option allows you to define some attributes which + // | will be applied by default to all icons within this set. + // | + // */ + // + // 'attributes' => [ + // // 'width' => 50, + // // 'height' => 50, + // ], + // + // ], + + ], + + /* + |-------------------------------------------------------------------------- + | Global Default Classes + |-------------------------------------------------------------------------- + | + | This config option allows you to define some classes which + | will be applied by default to all icons. + | + */ + + 'class' => '', + + /* + |-------------------------------------------------------------------------- + | Global Default Attributes + |-------------------------------------------------------------------------- + | + | This config option allows you to define some attributes which + | will be applied by default to all icons. + | + */ + + 'attributes' => [ + // 'width' => 50, + // 'height' => 50, + ], + + /* + |-------------------------------------------------------------------------- + | Global Fallback Icon + |-------------------------------------------------------------------------- + | + | This config option allows you to define a global fallback + | icon when an icon in any set cannot be found. It can + | reference any icon from any configured set. + | + */ + + 'fallback' => '', + + /* + |-------------------------------------------------------------------------- + | Components + |-------------------------------------------------------------------------- + | + | These config options allow you to define some + | settings related to Blade Components. + | + */ + + 'components' => [ + + /* + |---------------------------------------------------------------------- + | Disable Components + |---------------------------------------------------------------------- + | + | This config option allows you to disable Blade components + | completely. It's useful to avoid performance problems + | when working with large icon libraries. + | + */ + + 'disabled' => false, + + /* + |---------------------------------------------------------------------- + | Default Icon Component Name + |---------------------------------------------------------------------- + | + | This config option allows you to define the name + | for the default Icon class component. + | + */ + + 'default' => 'icon', + + ], + +]; diff --git a/workbench/config/cache.php b/workbench/config/cache.php new file mode 100644 index 0000000..4319e97 --- /dev/null +++ b/workbench/config/cache.php @@ -0,0 +1,108 @@ + env('CACHE_STORE', 'array'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "array", "database", "file", "memcached", + | "redis", "dynamodb", "octane", "null" + | + */ + + 'stores' => [ + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_CACHE_CONNECTION'), + 'table' => env('DB_CACHE_TABLE', 'cache'), + 'lock_connection' => env('DB_CACHE_LOCK_CONNECTION'), + 'lock_table' => env('DB_CACHE_LOCK_TABLE'), + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + 'lock_path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_CACHE_CONNECTION', 'cache'), + 'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'), + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing the APC, database, memcached, Redis, and DynamoDB cache + | stores, there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), + +]; diff --git a/workbench/config/concurrency.php b/workbench/config/concurrency.php new file mode 100644 index 0000000..cb8022b --- /dev/null +++ b/workbench/config/concurrency.php @@ -0,0 +1,20 @@ + env('CONCURRENCY_DRIVER', 'process'), + +]; diff --git a/workbench/config/cors.php b/workbench/config/cors.php new file mode 100644 index 0000000..8a39e6d --- /dev/null +++ b/workbench/config/cors.php @@ -0,0 +1,34 @@ + ['api/*', 'sanctum/csrf-cookie'], + + 'allowed_methods' => ['*'], + + 'allowed_origins' => ['*'], + + 'allowed_origins_patterns' => [], + + 'allowed_headers' => ['*'], + + 'exposed_headers' => [], + + 'max_age' => 0, + + 'supports_credentials' => false, + +]; diff --git a/workbench/config/database.php b/workbench/config/database.php new file mode 100644 index 0000000..125949e --- /dev/null +++ b/workbench/config/database.php @@ -0,0 +1,173 @@ + env('DB_CONNECTION', 'sqlite'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Below are all of the database connections defined for your application. + | An example configuration is provided for each database system which + | is supported by Laravel. You're free to add / remove connections. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DB_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + 'busy_timeout' => null, + 'journal_mode' => null, + 'synchronous' => null, + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'mariadb' => [ + 'driver' => 'mariadb', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run on the database. + | + */ + + 'migrations' => [ + 'table' => 'migrations', + 'update_date_on_publish' => true, + ], + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as Memcached. You may define your connection settings here. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + ], + + ], + +]; diff --git a/workbench/config/eclipse-catalogue.php b/workbench/config/eclipse-catalogue.php new file mode 100644 index 0000000..3ac44ad --- /dev/null +++ b/workbench/config/eclipse-catalogue.php @@ -0,0 +1,5 @@ + [ + 'slug' => 'shield/roles', + 'show_model_path' => true, + 'cluster' => null, + 'tabs' => [ + 'pages' => true, + 'widgets' => true, + 'resources' => true, + 'custom_permissions' => false, + ], + ], + + 'tenant_model' => null, + + 'auth_provider_model' => Workbench\App\Models\User::class, + + 'super_admin' => [ + 'enabled' => true, + 'name' => 'super_admin', + 'define_via_gate' => false, + 'intercept_gate' => 'before', + ], + + 'panel_user' => [ + 'enabled' => true, + 'name' => 'panel_user', + ], + + 'permissions' => [ + 'separator' => '_', + 'case' => 'lower_snake', + 'generate' => true, + ], + + 'policies' => [ + 'path' => app_path('Policies'), + 'merge' => true, + 'generate' => true, + 'methods' => [ + 'viewAny', 'view', 'create', 'update', 'restore', 'restoreAny', + 'replicate', 'reorder', 'delete', 'deleteAny', 'forceDelete', 'forceDeleteAny', + ], + 'single_parameter_methods' => [ + 'viewAny', 'create', 'deleteAny', 'forceDeleteAny', 'restoreAny', 'reorder', + ], + ], + + 'localization' => [ + 'enabled' => false, + 'key' => 'filament-shield::filament-shield', + ], + + 'resources' => [ + 'subject' => 'model', + 'manage' => [ + RoleResource::class => [ + 'viewAny', 'view', 'create', 'update', 'delete', + ], + ], + 'exclude' => [], + ], + + 'pages' => [ + 'subject' => 'class', + 'prefix' => 'view', + 'exclude' => [ + Dashboard::class, + ], + ], + + 'widgets' => [ + 'subject' => 'class', + 'prefix' => 'view', + 'exclude' => [ + AccountWidget::class, + FilamentInfoWidget::class, + ], + ], + + 'custom_permissions' => [], + + 'discovery' => [ + 'discover_all_resources' => false, + 'discover_all_widgets' => false, + 'discover_all_pages' => false, + ], + + 'register_role_policy' => true, +]; diff --git a/workbench/config/filament.php b/workbench/config/filament.php new file mode 100644 index 0000000..488a01f --- /dev/null +++ b/workbench/config/filament.php @@ -0,0 +1,101 @@ + [ + + // 'echo' => [ + // 'broadcaster' => 'pusher', + // 'key' => env('VITE_PUSHER_APP_KEY'), + // 'cluster' => env('VITE_PUSHER_APP_CLUSTER'), + // 'wsHost' => env('VITE_PUSHER_HOST'), + // 'wsPort' => env('VITE_PUSHER_PORT'), + // 'wssPort' => env('VITE_PUSHER_PORT'), + // 'authEndpoint' => '/broadcasting/auth', + // 'disableStats' => true, + // 'encrypted' => true, + // 'forceTLS' => true, + // ], + + ], + + /* + |-------------------------------------------------------------------------- + | Default Filesystem Disk + |-------------------------------------------------------------------------- + | + | This is the storage disk Filament will use to store files. You may use + | any of the disks defined in the `config/filesystems.php`. + | + */ + + 'default_filesystem_disk' => env('FILAMENT_FILESYSTEM_DISK', 'public'), + + /* + |-------------------------------------------------------------------------- + | Assets Path + |-------------------------------------------------------------------------- + | + | This is the directory where Filament's assets will be published to. It + | is relative to the `public` directory of your Laravel application. + | + | After changing the path, you should run `php artisan filament:assets`. + | + */ + + 'assets_path' => null, + + /* + |-------------------------------------------------------------------------- + | Cache Path + |-------------------------------------------------------------------------- + | + | This is the directory that Filament will use to store cache files that + | are used to optimize the registration of components. + | + | After changing the path, you should run `php artisan filament:cache-components`. + | + */ + + 'cache_path' => base_path('bootstrap/cache/filament'), + + /* + |-------------------------------------------------------------------------- + | Livewire Loading Delay + |-------------------------------------------------------------------------- + | + | This sets the delay before loading indicators appear. + | + | Setting this to 'none' makes indicators appear immediately, which can be + | desirable for high-latency connections. Setting it to 'default' applies + | Livewire's standard 200ms delay. + | + */ + + 'livewire_loading_delay' => 'default', + + /* + |-------------------------------------------------------------------------- + | System Route Prefix + |-------------------------------------------------------------------------- + | + | This is the prefix used for the system routes that Filament registers, + | such as the routes for downloading exports and failed import rows. + | + */ + + 'system_route_prefix' => 'filament', + +]; diff --git a/workbench/config/filesystems.php b/workbench/config/filesystems.php new file mode 100644 index 0000000..3d671bd --- /dev/null +++ b/workbench/config/filesystems.php @@ -0,0 +1,80 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Below you may configure as many filesystem disks as necessary, and you + | may even configure multiple disks for the same driver. Examples for + | most supported storage drivers are configured here for reference. + | + | Supported drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app/private'), + 'serve' => true, + 'throw' => false, + 'report' => false, + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + 'throw' => false, + 'report' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + 'report' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/workbench/config/hashing.php b/workbench/config/hashing.php new file mode 100644 index 0000000..9eb408e --- /dev/null +++ b/workbench/config/hashing.php @@ -0,0 +1,67 @@ + env('HASH_DRIVER', 'bcrypt'), + + /* + |-------------------------------------------------------------------------- + | Bcrypt Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Bcrypt algorithm. This will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'bcrypt' => [ + 'rounds' => env('BCRYPT_ROUNDS', 12), + 'verify' => env('HASH_VERIFY', true), + ], + + /* + |-------------------------------------------------------------------------- + | Argon Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Argon algorithm. These will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'argon' => [ + 'memory' => env('ARGON_MEMORY', 65536), + 'threads' => env('ARGON_THREADS', 1), + 'time' => env('ARGON_TIME', 4), + 'verify' => env('HASH_VERIFY', true), + ], + + /* + |-------------------------------------------------------------------------- + | Rehash On Login + |-------------------------------------------------------------------------- + | + | Setting this option to true will tell Laravel to automatically rehash + | the user's password during login if the configured work factor for + | the algorithm has changed, allowing graceful upgrades of hashes. + | + */ + + 'rehash_on_login' => true, + +]; diff --git a/workbench/config/livewire.php b/workbench/config/livewire.php new file mode 100644 index 0000000..0d2ba89 --- /dev/null +++ b/workbench/config/livewire.php @@ -0,0 +1,160 @@ + 'App\\Livewire', + + /* + |--------------------------------------------------------------------------- + | View Path + |--------------------------------------------------------------------------- + | + | This value is used to specify where Livewire component Blade templates are + | stored when running file creation commands like `artisan make:livewire`. + | It is also used if you choose to omit a component's render() method. + | + */ + + 'view_path' => resource_path('views/livewire'), + + /* + |--------------------------------------------------------------------------- + | Layout + |--------------------------------------------------------------------------- + | The view that will be used as the layout when rendering a single component + | as an entire page via `Route::get('/post/create', CreatePost::class);`. + | In this case, the view returned by CreatePost will render into $slot. + | + */ + + 'layout' => 'components.layouts.app', + + /* + |--------------------------------------------------------------------------- + | Lazy Loading Placeholder + |--------------------------------------------------------------------------- + | Livewire allows you to lazy load components that would otherwise slow down + | the initial page load. Every component can have a custom placeholder or + | you can define the default placeholder view for all components below. + | + */ + + 'lazy_placeholder' => null, + + /* + |--------------------------------------------------------------------------- + | Temporary File Uploads + |--------------------------------------------------------------------------- + | + | Livewire handles file uploads by storing uploads in a temporary directory + | before the file is stored permanently. All file uploads are directed to + | a global endpoint for temporary storage. You may configure this below: + | + */ + + 'temporary_file_upload' => [ + 'disk' => null, // Example: 'local', 's3' | Default: 'default' + 'rules' => null, // Example: ['file', 'mimes:png,jpg'] | Default: ['required', 'file', 'max:12288'] (12MB) + 'directory' => null, // Example: 'tmp' | Default: 'livewire-tmp' + 'middleware' => null, // Example: 'throttle:5,1' | Default: 'throttle:60,1' + 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs... + 'png', 'gif', 'bmp', 'svg', 'wav', 'mp4', + 'mov', 'avi', 'wmv', 'mp3', 'm4a', + 'jpg', 'jpeg', 'mpga', 'webp', 'wma', + ], + 'max_upload_time' => 5, // Max duration (in minutes) before an upload is invalidated... + 'cleanup' => true, // Should cleanup temporary uploads older than 24 hrs... + ], + + /* + |--------------------------------------------------------------------------- + | Render On Redirect + |--------------------------------------------------------------------------- + | + | This value determines if Livewire will run a component's `render()` method + | after a redirect has been triggered using something like `redirect(...)` + | Setting this to true will render the view once more before redirecting + | + */ + + 'render_on_redirect' => false, + + /* + |--------------------------------------------------------------------------- + | Eloquent Model Binding + |--------------------------------------------------------------------------- + | + | Previous versions of Livewire supported binding directly to eloquent model + | properties using wire:model by default. However, this behavior has been + | deemed too "magical" and has therefore been put under a feature flag. + | + */ + + 'legacy_model_binding' => false, + + /* + |--------------------------------------------------------------------------- + | Auto-inject Frontend Assets + |--------------------------------------------------------------------------- + | + | By default, Livewire automatically injects its JavaScript and CSS into the + | and of pages containing Livewire components. By disabling + | this behavior, you need to use @livewireStyles and @livewireScripts. + | + */ + + 'inject_assets' => true, + + /* + |--------------------------------------------------------------------------- + | Navigate (SPA mode) + |--------------------------------------------------------------------------- + | + | By adding `wire:navigate` to links in your Livewire application, Livewire + | will prevent the default link handling and instead request those pages + | via AJAX, creating an SPA-like effect. Configure this behavior here. + | + */ + + 'navigate' => [ + 'show_progress_bar' => true, + 'progress_bar_color' => '#2299dd', + ], + + /* + |--------------------------------------------------------------------------- + | HTML Morph Markers + |--------------------------------------------------------------------------- + | + | Livewire intelligently "morphs" existing HTML into the newly rendered HTML + | after each update. To make this process more reliable, Livewire injects + | "markers" into the rendered Blade surrounding @if, @class & @foreach. + | + */ + + 'inject_morph_markers' => true, + + /* + |--------------------------------------------------------------------------- + | Pagination Theme + |--------------------------------------------------------------------------- + | + | When enabling Livewire's pagination feature by using the `WithPagination` + | trait, Livewire will use Tailwind templates to render pagination views + | on the page. If you want Bootstrap CSS, you can specify: "bootstrap" + | + */ + + 'pagination_theme' => 'tailwind', +]; diff --git a/workbench/config/logging.php b/workbench/config/logging.php new file mode 100644 index 0000000..8d94292 --- /dev/null +++ b/workbench/config/logging.php @@ -0,0 +1,132 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => env('LOG_DEPRECATIONS_TRACE', false), + ], + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Laravel + | utilizes the Monolog PHP logging library, which includes a variety + | of powerful log handlers and formatters that you're free to use. + | + | Available drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", "custom", "stack" + | + */ + + 'channels' => [ + + 'stack' => [ + 'driver' => 'stack', + 'channels' => explode(',', env('LOG_STACK', 'single')), + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => env('LOG_DAILY_DAYS', 14), + 'replace_placeholders' => true, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'), + 'emoji' => env('LOG_SLACK_EMOJI', ':boom:'), + 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ + 'stream' => 'php://stderr', + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER), + 'replace_placeholders' => true, + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + + ], + +]; diff --git a/workbench/config/permission.php b/workbench/config/permission.php new file mode 100644 index 0000000..85b8832 --- /dev/null +++ b/workbench/config/permission.php @@ -0,0 +1,206 @@ + [ + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * Eloquent model should be used to retrieve your permissions. Of course, it + * is often just the "Permission" model but you may use whatever you like. + * + * The model you want to use as a Permission model needs to implement the + * `Spatie\Permission\Contracts\Permission` contract. + */ + + 'permission' => Permission::class, + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your roles. Of course, it + * is often just the "Role" model but you may use whatever you like. + * + * The model you want to use as a Role model needs to implement the + * `Spatie\Permission\Contracts\Role` contract. + */ + + 'role' => Role::class, + + ], + + 'table_names' => [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'roles' => 'roles', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your permissions. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'permissions' => 'permissions', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your models permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_permissions' => 'model_has_permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models roles. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_roles' => 'model_has_roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'role_has_permissions' => 'role_has_permissions', + ], + + 'column_names' => [ + /* + * Change this if you want to name the related pivots other than defaults + */ + 'role_pivot_key' => null, // default 'role_id', + 'permission_pivot_key' => null, // default 'permission_id', + + /* + * Change this if you want to name the related model primary key other than + * `model_id`. + * + * For example, this would be nice if your primary keys are all UUIDs. In + * that case, name this `model_uuid`. + */ + + 'model_morph_key' => 'model_id', + + /* + * Change this if you want to use the teams feature and your related model's + * foreign key is other than `team_id`. + */ + + 'team_foreign_key' => 'team_id', + ], + + /* + * When set to true, the method for checking permissions will be registered on the gate. + * Set this to false if you want to implement custom logic for checking permissions. + */ + + 'register_permission_check_method' => true, + + /* + * When set to true, Laravel\Octane\Events\OperationTerminated event listener will be registered + * this will refresh permissions on every TickTerminated, TaskTerminated and RequestTerminated + * NOTE: This should not be needed in most cases, but an Octane/Vapor combination benefited from it. + */ + 'register_octane_reset_listener' => false, + + /* + * Events will fire when a role or permission is assigned/unassigned: + * \Spatie\Permission\Events\RoleAttached + * \Spatie\Permission\Events\RoleDetached + * \Spatie\Permission\Events\PermissionAttached + * \Spatie\Permission\Events\PermissionDetached + * + * To enable, set to true, and then create listeners to watch these events. + */ + 'events_enabled' => false, + + /* + * Teams Feature. + * When set to true the package implements teams using the 'team_foreign_key'. + * If you want the migrations to register the 'team_foreign_key', you must + * set this to true before doing the migration. + * If you already did the migration then you must make a new migration to also + * add 'team_foreign_key' to 'roles', 'model_has_roles', and 'model_has_permissions' + * (view the latest version of this package's migration file) + */ + + 'teams' => false, + + /* + * The class to use to resolve the permissions team id + */ + 'team_resolver' => DefaultTeamResolver::class, + + /* + * Passport Client Credentials Grant + * When set to true the package will use Passports Client to check permissions + */ + + 'use_passport_client_credentials' => false, + + /* + * When set to true, the required permission names are added to exception messages. + * This could be considered an information leak in some contexts, so the default + * setting is false here for optimum safety. + */ + + 'display_permission_in_exception' => false, + + /* + * When set to true, the required role names are added to exception messages. + * This could be considered an information leak in some contexts, so the default + * setting is false here for optimum safety. + */ + + 'display_role_in_exception' => false, + + /* + * By default wildcard permission lookups are disabled. + * See documentation to understand supported syntax. + */ + + 'enable_wildcard_permission' => false, + + /* + * The class to use for interpreting wildcard permissions. + * If you need to modify delimiters, override the class and specify its name here. + */ + // 'wildcard_permission' => Spatie\Permission\WildcardPermission::class, + + /* Cache-specific settings */ + + 'cache' => [ + + /* + * By default all permissions are cached for 24 hours to speed up performance. + * When permissions or roles are updated the cache is flushed automatically. + */ + + 'expiration_time' => DateInterval::createFromDateString('24 hours'), + + /* + * The cache key used to store all permissions. + */ + + 'key' => 'spatie.permission.cache', + + /* + * You may optionally indicate a specific cache driver to use for permission and + * role caching using any of the `store` drivers listed in the cache.php config + * file. Using 'default' here means to use the `default` set in cache.php. + */ + + 'store' => 'default', + ], +]; diff --git a/workbench/config/queue.php b/workbench/config/queue.php new file mode 100644 index 0000000..116bd8d --- /dev/null +++ b/workbench/config/queue.php @@ -0,0 +1,112 @@ + env('QUEUE_CONNECTION', 'database'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection options for every queue backend + | used by your application. An example configuration is provided for + | each backend supported by Laravel. You're also free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_QUEUE_CONNECTION'), + 'table' => env('DB_QUEUE_TABLE', 'jobs'), + 'queue' => env('DB_QUEUE', 'default'), + 'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90), + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'), + 'queue' => env('BEANSTALKD_QUEUE', 'default'), + 'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90), + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_QUEUE_CONNECTION', 'default'), + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90), + 'block_for' => null, + 'after_commit' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Job Batching + |-------------------------------------------------------------------------- + | + | The following options configure the database and table that store job + | batching information. These options can be updated to any database + | connection and table which has been defined by your application. + | + */ + + 'batching' => [ + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'job_batches', + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control how and where failed jobs are stored. Laravel ships with + | support for storing failed jobs in a simple file or in a database. + | + | Supported drivers: "database-uuids", "dynamodb", "file", "null" + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/workbench/config/session.php b/workbench/config/session.php new file mode 100644 index 0000000..ba0aa60 --- /dev/null +++ b/workbench/config/session.php @@ -0,0 +1,217 @@ + env('SESSION_DRIVER', 'database'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to expire immediately when the browser is closed then you may + | indicate that via the expire_on_close configuration option. + | + */ + + 'lifetime' => (int) env('SESSION_LIFETIME', 120), + + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it's stored. All encryption is performed + | automatically by Laravel and you may use the session like normal. + | + */ + + 'encrypt' => env('SESSION_ENCRYPT', false), + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When utilizing the "file" session driver, the session files are placed + | on disk. The default storage location is defined here; however, you + | are free to provide another location where they should be stored. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table to + | be used to store sessions. Of course, a sensible default is defined + | for you; however, you're welcome to change this to another table. + | + */ + + 'table' => env('SESSION_TABLE', 'sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using one of the framework's cache driven session backends, you may + | define the cache store which should be used to store the session data + | between requests. This must match one of your defined cache stores. + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the session cookie that is created by + | the framework. Typically, you should not need to change this value + | since doing so does not grant a meaningful security improvement. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application, but you're free to change this when necessary. + | + */ + + 'path' => env('SESSION_PATH', '/'), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | This value determines the domain and subdomains the session cookie is + | available to. By default, the cookie will be available to the root + | domain and all subdomains. Typically, this shouldn't be changed. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. It's unlikely you should disable this option. + | + */ + + 'http_only' => env('SESSION_HTTP_ONLY', true), + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" to permit secure cross-site requests. + | + | See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => env('SESSION_SAME_SITE', 'lax'), + + /* + |-------------------------------------------------------------------------- + | Partitioned Cookies + |-------------------------------------------------------------------------- + | + | Setting this value to true will tie the cookie to the top-level site for + | a cross-site context. Partitioned cookies are accepted by the browser + | when flagged "secure" and the Same-Site attribute is set to "none". + | + */ + + 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), + +]; diff --git a/workbench/config/tinker.php b/workbench/config/tinker.php new file mode 100644 index 0000000..c187942 --- /dev/null +++ b/workbench/config/tinker.php @@ -0,0 +1,50 @@ + [ + // App\Console\Commands\ExampleCommand::class, + ], + + /* + |-------------------------------------------------------------------------- + | Auto Aliased Classes + |-------------------------------------------------------------------------- + | + | Tinker will not automatically alias classes in your vendor namespaces + | but you may explicitly allow a subset of classes to get aliased by + | adding the names of each of those classes to the following list. + | + */ + + 'alias' => [ + // + ], + + /* + |-------------------------------------------------------------------------- + | Classes That Should Not Be Aliased + |-------------------------------------------------------------------------- + | + | Typically, Tinker automatically aliases classes as you require them in + | Tinker. However, you may wish to never alias certain classes, which + | you may accomplish by listing the classes in the following array. + | + */ + + 'dont_alias' => [ + 'App\Nova', + ], + +]; diff --git a/workbench/config/view.php b/workbench/config/view.php new file mode 100644 index 0000000..98dd666 --- /dev/null +++ b/workbench/config/view.php @@ -0,0 +1,36 @@ + [ + resource_path('views'), + ], + + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ + + 'compiled' => env( + 'VIEW_COMPILED_PATH', + storage_path('framework/views') + ), + +]; diff --git a/workbench/database/database.sqlite b/workbench/database/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..5eaccbdd7e8325e2387612d163a864caaac18d41 GIT binary patch literal 458752 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 literal 0 HcmV?d00001 diff --git a/workbench/database/factories/UserFactory.php b/workbench/database/factories/UserFactory.php index 8a58e9e..126f178 100644 --- a/workbench/database/factories/UserFactory.php +++ b/workbench/database/factories/UserFactory.php @@ -8,21 +8,14 @@ use Workbench\App\Models\User; /** - * @template TModel of \Workbench\App\Models\User - * - * @extends Factory + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Workbench\App\Models\User> */ class UserFactory extends Factory { - /** - * The current password being used by the factory. - */ - protected static ?string $password; - /** * The name of the factory's corresponding model. * - * @var class-string + * @var class-string<\Illuminate\Database\Eloquent\Model> */ protected $model = User::class; @@ -37,7 +30,7 @@ public function definition(): array 'name' => fake()->name(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), - 'password' => static::$password ??= Hash::make('password'), + 'password' => Hash::make('password'), 'remember_token' => Str::random(10), ]; } @@ -51,4 +44,4 @@ public function unverified(): static 'email_verified_at' => null, ]); } -} +} \ No newline at end of file diff --git a/workbench/database/migrations/0001_01_01_000000_testbench_create_users_table.php b/workbench/database/migrations/0001_01_01_000000_testbench_create_users_table.php new file mode 100644 index 0000000..05fb5d9 --- /dev/null +++ b/workbench/database/migrations/0001_01_01_000000_testbench_create_users_table.php @@ -0,0 +1,49 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + + Schema::create('password_reset_tokens', function (Blueprint $table) { + $table->string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + + Schema::create('sessions', function (Blueprint $table) { + $table->string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('users'); + Schema::dropIfExists('password_reset_tokens'); + Schema::dropIfExists('sessions'); + } +}; diff --git a/workbench/database/migrations/0001_01_01_000001_testbench_create_cache_table.php b/workbench/database/migrations/0001_01_01_000001_testbench_create_cache_table.php new file mode 100644 index 0000000..b9c106b --- /dev/null +++ b/workbench/database/migrations/0001_01_01_000001_testbench_create_cache_table.php @@ -0,0 +1,35 @@ +string('key')->primary(); + $table->mediumText('value'); + $table->integer('expiration'); + }); + + Schema::create('cache_locks', function (Blueprint $table) { + $table->string('key')->primary(); + $table->string('owner'); + $table->integer('expiration'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('cache'); + Schema::dropIfExists('cache_locks'); + } +}; diff --git a/workbench/database/migrations/0001_01_01_000002_testbench_create_jobs_table.php b/workbench/database/migrations/0001_01_01_000002_testbench_create_jobs_table.php new file mode 100644 index 0000000..425e705 --- /dev/null +++ b/workbench/database/migrations/0001_01_01_000002_testbench_create_jobs_table.php @@ -0,0 +1,57 @@ +id(); + $table->string('queue')->index(); + $table->longText('payload'); + $table->unsignedTinyInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + }); + + Schema::create('job_batches', function (Blueprint $table) { + $table->string('id')->primary(); + $table->string('name'); + $table->integer('total_jobs'); + $table->integer('pending_jobs'); + $table->integer('failed_jobs'); + $table->longText('failed_job_ids'); + $table->mediumText('options')->nullable(); + $table->integer('cancelled_at')->nullable(); + $table->integer('created_at'); + $table->integer('finished_at')->nullable(); + }); + + Schema::create('failed_jobs', function (Blueprint $table) { + $table->id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('jobs'); + Schema::dropIfExists('job_batches'); + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/workbench/database/migrations/2025_08_10_104332_create_sessions_table.php b/workbench/database/migrations/2025_08_10_104332_create_sessions_table.php new file mode 100644 index 0000000..ca5922d --- /dev/null +++ b/workbench/database/migrations/2025_08_10_104332_create_sessions_table.php @@ -0,0 +1,33 @@ +string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sessions'); + } +}; diff --git a/workbench/database/migrations/2025_08_28_113759_create_notifications_table.php b/workbench/database/migrations/2025_08_28_113759_create_notifications_table.php new file mode 100644 index 0000000..d738032 --- /dev/null +++ b/workbench/database/migrations/2025_08_28_113759_create_notifications_table.php @@ -0,0 +1,31 @@ +uuid('id')->primary(); + $table->string('type'); + $table->morphs('notifiable'); + $table->text('data'); + $table->timestamp('read_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('notifications'); + } +}; diff --git a/workbench/database/migrations/2025_08_28_142604_create_permission_tables.php b/workbench/database/migrations/2025_08_28_142604_create_permission_tables.php new file mode 100644 index 0000000..5f8d69a --- /dev/null +++ b/workbench/database/migrations/2025_08_28_142604_create_permission_tables.php @@ -0,0 +1,136 @@ +engine('InnoDB'); + $table->bigIncrements('id'); // permission id + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('guard_name'); // For MyISAM use string('guard_name', 25); + $table->timestamps(); + + $table->unique(['name', 'guard_name']); + }); + + Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) { + // $table->engine('InnoDB'); + $table->bigIncrements('id'); // role id + if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); + $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); + } + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('guard_name'); // For MyISAM use string('guard_name', 25); + $table->timestamps(); + if ($teams || config('permission.testing')) { + $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']); + } else { + $table->unique(['name', 'guard_name']); + } + }); + + Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) { + $table->unsignedBigInteger($pivotPermission); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } else { + $table->primary([$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } + + }); + + Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) { + $table->unsignedBigInteger($pivotRole); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } else { + $table->primary([$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } + }); + + Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) { + $table->unsignedBigInteger($pivotPermission); + $table->unsignedBigInteger($pivotRole); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + }); + + app('cache') + ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->forget(config('permission.cache.key')); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + $tableNames = config('permission.table_names'); + + if (empty($tableNames)) { + throw new Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + } + + Schema::drop($tableNames['role_has_permissions']); + Schema::drop($tableNames['model_has_roles']); + Schema::drop($tableNames['model_has_permissions']); + Schema::drop($tableNames['roles']); + Schema::drop($tableNames['permissions']); + } +}; diff --git a/workbench/public/index.php b/workbench/public/index.php new file mode 100644 index 0000000..6d3fffa --- /dev/null +++ b/workbench/public/index.php @@ -0,0 +1,55 @@ +make(Kernel::class); + +$response = $kernel->handle( + $request = Request::capture() +)->send(); + +$kernel->terminate($request, $response); diff --git a/workbench/public/robots.txt b/workbench/public/robots.txt new file mode 100644 index 0000000..1f53798 --- /dev/null +++ b/workbench/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/workbench/resources/views/errors/401.blade.php b/workbench/resources/views/errors/401.blade.php new file mode 100644 index 0000000..5c586db --- /dev/null +++ b/workbench/resources/views/errors/401.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Unauthorized')) +@section('code', '401') +@section('message', __('Unauthorized')) diff --git a/workbench/resources/views/errors/402.blade.php b/workbench/resources/views/errors/402.blade.php new file mode 100644 index 0000000..3bc23ef --- /dev/null +++ b/workbench/resources/views/errors/402.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Payment Required')) +@section('code', '402') +@section('message', __('Payment Required')) diff --git a/workbench/resources/views/errors/403.blade.php b/workbench/resources/views/errors/403.blade.php new file mode 100644 index 0000000..a5506f0 --- /dev/null +++ b/workbench/resources/views/errors/403.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Forbidden')) +@section('code', '403') +@section('message', __($exception->getMessage() ?: 'Forbidden')) diff --git a/workbench/resources/views/errors/404.blade.php b/workbench/resources/views/errors/404.blade.php new file mode 100644 index 0000000..7549540 --- /dev/null +++ b/workbench/resources/views/errors/404.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Not Found')) +@section('code', '404') +@section('message', __('Not Found')) diff --git a/workbench/resources/views/errors/419.blade.php b/workbench/resources/views/errors/419.blade.php new file mode 100644 index 0000000..c09216e --- /dev/null +++ b/workbench/resources/views/errors/419.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Page Expired')) +@section('code', '419') +@section('message', __('Page Expired')) diff --git a/workbench/resources/views/errors/429.blade.php b/workbench/resources/views/errors/429.blade.php new file mode 100644 index 0000000..f01b07b --- /dev/null +++ b/workbench/resources/views/errors/429.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Too Many Requests')) +@section('code', '429') +@section('message', __('Too Many Requests')) diff --git a/workbench/resources/views/errors/500.blade.php b/workbench/resources/views/errors/500.blade.php new file mode 100644 index 0000000..d9e95d9 --- /dev/null +++ b/workbench/resources/views/errors/500.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Server Error')) +@section('code', '500') +@section('message', __('Server Error')) diff --git a/workbench/resources/views/errors/503.blade.php b/workbench/resources/views/errors/503.blade.php new file mode 100644 index 0000000..c5a9dde --- /dev/null +++ b/workbench/resources/views/errors/503.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Service Unavailable')) +@section('code', '503') +@section('message', __('Service Unavailable')) diff --git a/workbench/resources/views/errors/layout.blade.php b/workbench/resources/views/errors/layout.blade.php new file mode 100644 index 0000000..019c2cd --- /dev/null +++ b/workbench/resources/views/errors/layout.blade.php @@ -0,0 +1,53 @@ + + + + + + + @yield('title') + + + + + +
+
+
+ @yield('message') +
+
+
+ + diff --git a/workbench/resources/views/errors/minimal.blade.php b/workbench/resources/views/errors/minimal.blade.php new file mode 100644 index 0000000..db69f25 --- /dev/null +++ b/workbench/resources/views/errors/minimal.blade.php @@ -0,0 +1,34 @@ + + + + + + + @yield('title') + + + + + + +
+
+
+
+ @yield('code') +
+ +
+ @yield('message') +
+
+
+
+ + diff --git a/workbench/resources/views/welcome.blade.php b/workbench/resources/views/welcome.blade.php new file mode 100644 index 0000000..3276668 --- /dev/null +++ b/workbench/resources/views/welcome.blade.php @@ -0,0 +1,66 @@ + + + + + + Eclipse Catalogue Plugin Workbench + + + +
+

Eclipse Catalogue Plugin

+

Workbench environment for developing the Eclipse Catalogue Filament plugin.

+ +
+ + diff --git a/workbench/routes/console.php b/workbench/routes/console.php index 7929725..b31e6c8 100644 --- a/workbench/routes/console.php +++ b/workbench/routes/console.php @@ -5,4 +5,4 @@ // Artisan::command('inspire', function () { // $this->comment(Inspiring::quote()); -// })->purpose('Display an inspiring quote'); +// })->purpose('Display an inspiring quote')->hourly(); \ No newline at end of file diff --git a/workbench/routes/web.php b/workbench/routes/web.php index 86a06c5..ad58fa2 100644 --- a/workbench/routes/web.php +++ b/workbench/routes/web.php @@ -4,4 +4,4 @@ Route::get('/', function () { return view('welcome'); -}); +}); \ No newline at end of file diff --git a/workbench/storage/.gitkeep b/workbench/storage/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workbench/storage/framework/.gitkeep b/workbench/storage/framework/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workbench/storage/framework/cache/.gitkeep b/workbench/storage/framework/cache/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workbench/storage/framework/data/.gitkeep b/workbench/storage/framework/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workbench/storage/framework/sessions/.gitkeep b/workbench/storage/framework/sessions/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workbench/storage/framework/testing/.gitkeep b/workbench/storage/framework/testing/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workbench/storage/framework/views/.gitkeep b/workbench/storage/framework/views/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/workbench/storage/logs/.gitkeep b/workbench/storage/logs/.gitkeep new file mode 100644 index 0000000..e69de29 From 51d3e6a443ae70737a640370b6fa9e1e46747ec2 Mon Sep 17 00:00:00 2001 From: Kilian Trunk Date: Wed, 29 Oct 2025 12:55:34 +0100 Subject: [PATCH 2/3] chore: formatting & phpunit db update --- phpunit.xml.dist | 2 +- workbench/app/Models/User.php | 2 +- workbench/app/Policies/CategoryPolicy.php | 7 +++---- workbench/app/Policies/GroupPolicy.php | 7 +++---- workbench/app/Policies/MeasureUnitPolicy.php | 7 +++---- workbench/app/Policies/PriceListPolicy.php | 7 +++---- workbench/app/Policies/ProductPolicy.php | 7 +++---- workbench/app/Policies/ProductStatusPolicy.php | 7 +++---- workbench/app/Policies/ProductTypePolicy.php | 7 +++---- workbench/app/Policies/PropertyPolicy.php | 7 +++---- workbench/app/Policies/PropertyValuePolicy.php | 7 +++---- workbench/app/Policies/RolePolicy.php | 7 +++---- workbench/app/Policies/TaxClassPolicy.php | 7 +++---- workbench/app/Providers/AdminPanelProvider.php | 2 +- workbench/app/Providers/WorkbenchServiceProvider.php | 2 +- workbench/bootstrap/app.php | 2 +- workbench/database/factories/UserFactory.php | 2 +- workbench/routes/console.php | 2 +- workbench/routes/web.php | 2 +- 19 files changed, 41 insertions(+), 52 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ee48e7b..2405929 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -19,7 +19,7 @@ - + diff --git a/workbench/app/Models/User.php b/workbench/app/Models/User.php index a660743..b5cd8e6 100644 --- a/workbench/app/Models/User.php +++ b/workbench/app/Models/User.php @@ -44,4 +44,4 @@ protected function casts(): array 'password' => 'hashed', ]; } -} \ No newline at end of file +} diff --git a/workbench/app/Policies/CategoryPolicy.php b/workbench/app/Policies/CategoryPolicy.php index 0429eff..6aac4f9 100644 --- a/workbench/app/Policies/CategoryPolicy.php +++ b/workbench/app/Policies/CategoryPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\Category; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class CategoryPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_category'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_category'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/GroupPolicy.php b/workbench/app/Policies/GroupPolicy.php index ccb4d2a..803e539 100644 --- a/workbench/app/Policies/GroupPolicy.php +++ b/workbench/app/Policies/GroupPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\Group; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class GroupPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_group'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_group'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/MeasureUnitPolicy.php b/workbench/app/Policies/MeasureUnitPolicy.php index cfeb64f..8ab2e3e 100644 --- a/workbench/app/Policies/MeasureUnitPolicy.php +++ b/workbench/app/Policies/MeasureUnitPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\MeasureUnit; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class MeasureUnitPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_measure_unit'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_measure_unit'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/PriceListPolicy.php b/workbench/app/Policies/PriceListPolicy.php index ecb0ee6..6c5cbd7 100644 --- a/workbench/app/Policies/PriceListPolicy.php +++ b/workbench/app/Policies/PriceListPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\PriceList; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class PriceListPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_price_list'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_price_list'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/ProductPolicy.php b/workbench/app/Policies/ProductPolicy.php index 52cc309..4d12fd9 100644 --- a/workbench/app/Policies/ProductPolicy.php +++ b/workbench/app/Policies/ProductPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\Product; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class ProductPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_product'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_product'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/ProductStatusPolicy.php b/workbench/app/Policies/ProductStatusPolicy.php index e0b0e2d..d572216 100644 --- a/workbench/app/Policies/ProductStatusPolicy.php +++ b/workbench/app/Policies/ProductStatusPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\ProductStatus; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class ProductStatusPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_product_status'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_product_status'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/ProductTypePolicy.php b/workbench/app/Policies/ProductTypePolicy.php index cd70a3a..d64a254 100644 --- a/workbench/app/Policies/ProductTypePolicy.php +++ b/workbench/app/Policies/ProductTypePolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\ProductType; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class ProductTypePolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_product_type'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_product_type'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/PropertyPolicy.php b/workbench/app/Policies/PropertyPolicy.php index 56499fe..29da7ee 100644 --- a/workbench/app/Policies/PropertyPolicy.php +++ b/workbench/app/Policies/PropertyPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\Property; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class PropertyPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_property'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_property'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/PropertyValuePolicy.php b/workbench/app/Policies/PropertyValuePolicy.php index 429c974..4403bd1 100644 --- a/workbench/app/Policies/PropertyValuePolicy.php +++ b/workbench/app/Policies/PropertyValuePolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\PropertyValue; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class PropertyValuePolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_property_value'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_property_value'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/RolePolicy.php b/workbench/app/Policies/RolePolicy.php index 151a1c3..7c960da 100644 --- a/workbench/app/Policies/RolePolicy.php +++ b/workbench/app/Policies/RolePolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; +use Illuminate\Auth\Access\HandlesAuthorization; use Illuminate\Foundation\Auth\User as AuthUser; use Spatie\Permission\Models\Role; -use Illuminate\Auth\Access\HandlesAuthorization; class RolePolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_role'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_role'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Policies/TaxClassPolicy.php b/workbench/app/Policies/TaxClassPolicy.php index 6ccd740..1aae5a7 100644 --- a/workbench/app/Policies/TaxClassPolicy.php +++ b/workbench/app/Policies/TaxClassPolicy.php @@ -4,14 +4,14 @@ namespace Workbench\App\Policies; -use Illuminate\Foundation\Auth\User as AuthUser; use Eclipse\Catalogue\Models\TaxClass; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Foundation\Auth\User as AuthUser; class TaxClassPolicy { use HandlesAuthorization; - + public function viewAny(AuthUser $authUser): bool { return $authUser->can('view_any_tax_class'); @@ -71,5 +71,4 @@ public function forceDeleteAny(AuthUser $authUser): bool { return $authUser->can('force_delete_any_tax_class'); } - -} \ No newline at end of file +} diff --git a/workbench/app/Providers/AdminPanelProvider.php b/workbench/app/Providers/AdminPanelProvider.php index 16b0f3d..25c9472 100644 --- a/workbench/app/Providers/AdminPanelProvider.php +++ b/workbench/app/Providers/AdminPanelProvider.php @@ -60,4 +60,4 @@ public function register(): void { parent::register(); } -} \ No newline at end of file +} diff --git a/workbench/app/Providers/WorkbenchServiceProvider.php b/workbench/app/Providers/WorkbenchServiceProvider.php index 4a70d57..62715cf 100644 --- a/workbench/app/Providers/WorkbenchServiceProvider.php +++ b/workbench/app/Providers/WorkbenchServiceProvider.php @@ -30,4 +30,4 @@ public function boot(): void { // } -} \ No newline at end of file +} diff --git a/workbench/bootstrap/app.php b/workbench/bootstrap/app.php index 01af2b1..3fa4760 100644 --- a/workbench/bootstrap/app.php +++ b/workbench/bootstrap/app.php @@ -18,4 +18,4 @@ }) ->withExceptions(function (Exceptions $exceptions) { // - })->create(); \ No newline at end of file + })->create(); diff --git a/workbench/database/factories/UserFactory.php b/workbench/database/factories/UserFactory.php index 126f178..9bc2a78 100644 --- a/workbench/database/factories/UserFactory.php +++ b/workbench/database/factories/UserFactory.php @@ -44,4 +44,4 @@ public function unverified(): static 'email_verified_at' => null, ]); } -} \ No newline at end of file +} diff --git a/workbench/routes/console.php b/workbench/routes/console.php index b31e6c8..29d4989 100644 --- a/workbench/routes/console.php +++ b/workbench/routes/console.php @@ -5,4 +5,4 @@ // Artisan::command('inspire', function () { // $this->comment(Inspiring::quote()); -// })->purpose('Display an inspiring quote')->hourly(); \ No newline at end of file +// })->purpose('Display an inspiring quote')->hourly(); diff --git a/workbench/routes/web.php b/workbench/routes/web.php index ad58fa2..86a06c5 100644 --- a/workbench/routes/web.php +++ b/workbench/routes/web.php @@ -4,4 +4,4 @@ Route::get('/', function () { return view('welcome'); -}); \ No newline at end of file +}); From 161516ce8c2dd0f23fb59157a4e1209527a609c3 Mon Sep 17 00:00:00 2001 From: Kilian Trunk Date: Sat, 8 Nov 2025 11:21:22 +0100 Subject: [PATCH 3/3] chore: fix tests & remove duplicate policies --- tests/Feature/CategoryResourceTest.php | 7 +- .../Feature/CustomPropertyPermissionTest.php | 14 ++-- tests/Feature/GroupCodeUniquenessTest.php | 16 ++-- tests/TestCase.php | 14 +++- workbench/app/Models/User.php | 18 +++++ workbench/app/Policies/CategoryPolicy.php | 74 ------------------- workbench/app/Policies/GroupPolicy.php | 74 ------------------- workbench/app/Policies/MeasureUnitPolicy.php | 74 ------------------- workbench/app/Policies/PriceListPolicy.php | 74 ------------------- workbench/app/Policies/ProductPolicy.php | 74 ------------------- .../app/Policies/ProductStatusPolicy.php | 74 ------------------- workbench/app/Policies/ProductTypePolicy.php | 74 ------------------- workbench/app/Policies/PropertyPolicy.php | 74 ------------------- workbench/app/Policies/TaxClassPolicy.php | 74 ------------------- .../app/Providers/AuthServiceProvider.php | 36 ++++++++- workbench/config/filament-shield.php | 2 +- 16 files changed, 88 insertions(+), 685 deletions(-) delete mode 100644 workbench/app/Policies/CategoryPolicy.php delete mode 100644 workbench/app/Policies/GroupPolicy.php delete mode 100644 workbench/app/Policies/MeasureUnitPolicy.php delete mode 100644 workbench/app/Policies/PriceListPolicy.php delete mode 100644 workbench/app/Policies/ProductPolicy.php delete mode 100644 workbench/app/Policies/ProductStatusPolicy.php delete mode 100644 workbench/app/Policies/ProductTypePolicy.php delete mode 100644 workbench/app/Policies/PropertyPolicy.php delete mode 100644 workbench/app/Policies/TaxClassPolicy.php diff --git a/tests/Feature/CategoryResourceTest.php b/tests/Feature/CategoryResourceTest.php index 8305f86..fd168cc 100644 --- a/tests/Feature/CategoryResourceTest.php +++ b/tests/Feature/CategoryResourceTest.php @@ -10,11 +10,14 @@ uses(RefreshDatabase::class); beforeEach(function (): void { - $this->setUpSuperAdmin(); + $this->migrate(); + $this->createPermissions(); + $this->createRoles(); + $this->setUpSuperAdminAndTenant(); }); it('can render category index page', function (): void { - $this->get(CategoryResource::getUrl('index')) + Livewire::test(CategoryResource\Pages\ListCategories::class) ->assertSuccessful(); }); diff --git a/tests/Feature/CustomPropertyPermissionTest.php b/tests/Feature/CustomPropertyPermissionTest.php index 0ea48a4..75bd8ac 100644 --- a/tests/Feature/CustomPropertyPermissionTest.php +++ b/tests/Feature/CustomPropertyPermissionTest.php @@ -46,8 +46,11 @@ }); it('super admin can manage custom properties', function () { - // Set up super admin - $this->setUpSuperAdmin(); + // Ensure permissions and roles are created + $this->createPermissions(); + $this->createRoles(); + // Set up super admin with tenant + $this->setUpSuperAdminAndTenant(); // Create test custom property $customProperty = Property::create([ @@ -58,12 +61,9 @@ 'is_multilang' => false, ]); - // View table - $this->get(PropertyResource::getUrl()) - ->assertOk(); - - // Create property + // View table and verify super admin can manage properties livewire(ListProperties::class) + ->assertSuccessful() ->assertActionEnabled('create'); // Edit property diff --git a/tests/Feature/GroupCodeUniquenessTest.php b/tests/Feature/GroupCodeUniquenessTest.php index 885b31c..6ca4c3e 100644 --- a/tests/Feature/GroupCodeUniquenessTest.php +++ b/tests/Feature/GroupCodeUniquenessTest.php @@ -8,16 +8,20 @@ }); it('allows same code across different sites', function () { + // Ensure we have at least 2 sites + $site1 = \Workbench\App\Models\Site::first() ?? \Workbench\App\Models\Site::factory()->create(); + $site2 = \Workbench\App\Models\Site::factory()->create(); + // Create groups with same code on different sites $group1 = Group::create([ - 'site_id' => 1, + 'site_id' => $site1->id, 'code' => 'same-code', 'name' => 'Group 1', 'is_active' => true, ]); $group2 = Group::create([ - 'site_id' => 2, + 'site_id' => $site2->id, 'code' => 'same-code', 'name' => 'Group 2', 'is_active' => true, @@ -25,18 +29,18 @@ expect($group1->code)->toBe('same-code'); expect($group2->code)->toBe('same-code'); - expect($group1->site_id)->toBe(1); - expect($group2->site_id)->toBe(2); + expect($group1->site_id)->toBe($site1->id); + expect($group2->site_id)->toBe($site2->id); $this->assertDatabaseHas('pim_group', [ 'id' => $group1->id, - 'site_id' => 1, + 'site_id' => $site1->id, 'code' => 'same-code', ]); $this->assertDatabaseHas('pim_group', [ 'id' => $group2->id, - 'site_id' => 2, + 'site_id' => $site2->id, 'code' => 'same-code', ]); }); diff --git a/tests/TestCase.php b/tests/TestCase.php index a464d77..1b664b1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -21,6 +21,10 @@ abstract class TestCase extends BaseTestCase protected function getEnvironmentSetUp($app): void { $app['config']->set('filament-shield.register_role_policy', false); + + // Configure tenancy for tests so migrations create the site_id column + $app['config']->set('eclipse-catalogue.tenancy.model', 'Workbench\App\Models\Site'); + $app['config']->set('eclipse-catalogue.tenancy.foreign_key', 'site_id'); } protected function setUp(): void @@ -64,7 +68,9 @@ protected function setUpSuperAdmin(): self $this->superAdmin = User::factory()->create(); // Assign super admin role and give all permissions - $superAdminRole = \Spatie\Permission\Models\Role::where('name', 'super_admin')->first(); + $superAdminRole = \Spatie\Permission\Models\Role::where('name', 'super_admin') + ->where('guard_name', 'web') + ->first(); if ($superAdminRole) { $this->superAdmin->assignRole($superAdminRole); // Give all permissions to super admin role @@ -72,6 +78,12 @@ protected function setUpSuperAdmin(): self $superAdminRole->syncPermissions($permissions); } + // Clear permission cache to ensure roles are recognized + app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions(); + + // Refresh user to reload roles + $this->superAdmin->refresh(); + $this->actingAs($this->superAdmin); return $this; diff --git a/workbench/app/Models/User.php b/workbench/app/Models/User.php index b5cd8e6..1d3f7de 100644 --- a/workbench/app/Models/User.php +++ b/workbench/app/Models/User.php @@ -3,9 +3,11 @@ namespace Workbench\App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Spatie\Permission\Traits\HasRoles; +use Workbench\Database\Factories\UserFactory; class User extends Authenticatable { @@ -44,4 +46,20 @@ protected function casts(): array 'password' => 'hashed', ]; } + + /** + * Create a new factory instance for the model. + */ + protected static function newFactory() + { + return UserFactory::new(); + } + + /** + * Get the sites that belong to the user. + */ + public function sites(): BelongsToMany + { + return $this->belongsToMany(Site::class, 'site_has_user', 'user_id', 'site_id'); + } } diff --git a/workbench/app/Policies/CategoryPolicy.php b/workbench/app/Policies/CategoryPolicy.php deleted file mode 100644 index 6aac4f9..0000000 --- a/workbench/app/Policies/CategoryPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_category'); - } - - public function view(AuthUser $authUser, Category $category): bool - { - return $authUser->can('view_category'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_category'); - } - - public function update(AuthUser $authUser, Category $category): bool - { - return $authUser->can('update_category'); - } - - public function restore(AuthUser $authUser, Category $category): bool - { - return $authUser->can('restore_category'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_category'); - } - - public function replicate(AuthUser $authUser, Category $category): bool - { - return $authUser->can('replicate_category'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_category'); - } - - public function delete(AuthUser $authUser, Category $category): bool - { - return $authUser->can('delete_category'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_category'); - } - - public function forceDelete(AuthUser $authUser, Category $category): bool - { - return $authUser->can('force_delete_category'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_category'); - } -} diff --git a/workbench/app/Policies/GroupPolicy.php b/workbench/app/Policies/GroupPolicy.php deleted file mode 100644 index 803e539..0000000 --- a/workbench/app/Policies/GroupPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_group'); - } - - public function view(AuthUser $authUser, Group $group): bool - { - return $authUser->can('view_group'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_group'); - } - - public function update(AuthUser $authUser, Group $group): bool - { - return $authUser->can('update_group'); - } - - public function restore(AuthUser $authUser, Group $group): bool - { - return $authUser->can('restore_group'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_group'); - } - - public function replicate(AuthUser $authUser, Group $group): bool - { - return $authUser->can('replicate_group'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_group'); - } - - public function delete(AuthUser $authUser, Group $group): bool - { - return $authUser->can('delete_group'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_group'); - } - - public function forceDelete(AuthUser $authUser, Group $group): bool - { - return $authUser->can('force_delete_group'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_group'); - } -} diff --git a/workbench/app/Policies/MeasureUnitPolicy.php b/workbench/app/Policies/MeasureUnitPolicy.php deleted file mode 100644 index 8ab2e3e..0000000 --- a/workbench/app/Policies/MeasureUnitPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_measure_unit'); - } - - public function view(AuthUser $authUser, MeasureUnit $measureUnit): bool - { - return $authUser->can('view_measure_unit'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_measure_unit'); - } - - public function update(AuthUser $authUser, MeasureUnit $measureUnit): bool - { - return $authUser->can('update_measure_unit'); - } - - public function restore(AuthUser $authUser, MeasureUnit $measureUnit): bool - { - return $authUser->can('restore_measure_unit'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_measure_unit'); - } - - public function replicate(AuthUser $authUser, MeasureUnit $measureUnit): bool - { - return $authUser->can('replicate_measure_unit'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_measure_unit'); - } - - public function delete(AuthUser $authUser, MeasureUnit $measureUnit): bool - { - return $authUser->can('delete_measure_unit'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_measure_unit'); - } - - public function forceDelete(AuthUser $authUser, MeasureUnit $measureUnit): bool - { - return $authUser->can('force_delete_measure_unit'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_measure_unit'); - } -} diff --git a/workbench/app/Policies/PriceListPolicy.php b/workbench/app/Policies/PriceListPolicy.php deleted file mode 100644 index 6c5cbd7..0000000 --- a/workbench/app/Policies/PriceListPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_price_list'); - } - - public function view(AuthUser $authUser, PriceList $priceList): bool - { - return $authUser->can('view_price_list'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_price_list'); - } - - public function update(AuthUser $authUser, PriceList $priceList): bool - { - return $authUser->can('update_price_list'); - } - - public function restore(AuthUser $authUser, PriceList $priceList): bool - { - return $authUser->can('restore_price_list'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_price_list'); - } - - public function replicate(AuthUser $authUser, PriceList $priceList): bool - { - return $authUser->can('replicate_price_list'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_price_list'); - } - - public function delete(AuthUser $authUser, PriceList $priceList): bool - { - return $authUser->can('delete_price_list'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_price_list'); - } - - public function forceDelete(AuthUser $authUser, PriceList $priceList): bool - { - return $authUser->can('force_delete_price_list'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_price_list'); - } -} diff --git a/workbench/app/Policies/ProductPolicy.php b/workbench/app/Policies/ProductPolicy.php deleted file mode 100644 index 4d12fd9..0000000 --- a/workbench/app/Policies/ProductPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_product'); - } - - public function view(AuthUser $authUser, Product $product): bool - { - return $authUser->can('view_product'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_product'); - } - - public function update(AuthUser $authUser, Product $product): bool - { - return $authUser->can('update_product'); - } - - public function restore(AuthUser $authUser, Product $product): bool - { - return $authUser->can('restore_product'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_product'); - } - - public function replicate(AuthUser $authUser, Product $product): bool - { - return $authUser->can('replicate_product'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_product'); - } - - public function delete(AuthUser $authUser, Product $product): bool - { - return $authUser->can('delete_product'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_product'); - } - - public function forceDelete(AuthUser $authUser, Product $product): bool - { - return $authUser->can('force_delete_product'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_product'); - } -} diff --git a/workbench/app/Policies/ProductStatusPolicy.php b/workbench/app/Policies/ProductStatusPolicy.php deleted file mode 100644 index d572216..0000000 --- a/workbench/app/Policies/ProductStatusPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_product_status'); - } - - public function view(AuthUser $authUser, ProductStatus $productStatus): bool - { - return $authUser->can('view_product_status'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_product_status'); - } - - public function update(AuthUser $authUser, ProductStatus $productStatus): bool - { - return $authUser->can('update_product_status'); - } - - public function restore(AuthUser $authUser, ProductStatus $productStatus): bool - { - return $authUser->can('restore_product_status'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_product_status'); - } - - public function replicate(AuthUser $authUser, ProductStatus $productStatus): bool - { - return $authUser->can('replicate_product_status'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_product_status'); - } - - public function delete(AuthUser $authUser, ProductStatus $productStatus): bool - { - return $authUser->can('delete_product_status'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_product_status'); - } - - public function forceDelete(AuthUser $authUser, ProductStatus $productStatus): bool - { - return $authUser->can('force_delete_product_status'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_product_status'); - } -} diff --git a/workbench/app/Policies/ProductTypePolicy.php b/workbench/app/Policies/ProductTypePolicy.php deleted file mode 100644 index d64a254..0000000 --- a/workbench/app/Policies/ProductTypePolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_product_type'); - } - - public function view(AuthUser $authUser, ProductType $productType): bool - { - return $authUser->can('view_product_type'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_product_type'); - } - - public function update(AuthUser $authUser, ProductType $productType): bool - { - return $authUser->can('update_product_type'); - } - - public function restore(AuthUser $authUser, ProductType $productType): bool - { - return $authUser->can('restore_product_type'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_product_type'); - } - - public function replicate(AuthUser $authUser, ProductType $productType): bool - { - return $authUser->can('replicate_product_type'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_product_type'); - } - - public function delete(AuthUser $authUser, ProductType $productType): bool - { - return $authUser->can('delete_product_type'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_product_type'); - } - - public function forceDelete(AuthUser $authUser, ProductType $productType): bool - { - return $authUser->can('force_delete_product_type'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_product_type'); - } -} diff --git a/workbench/app/Policies/PropertyPolicy.php b/workbench/app/Policies/PropertyPolicy.php deleted file mode 100644 index 29da7ee..0000000 --- a/workbench/app/Policies/PropertyPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_property'); - } - - public function view(AuthUser $authUser, Property $property): bool - { - return $authUser->can('view_property'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_property'); - } - - public function update(AuthUser $authUser, Property $property): bool - { - return $authUser->can('update_property'); - } - - public function restore(AuthUser $authUser, Property $property): bool - { - return $authUser->can('restore_property'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_property'); - } - - public function replicate(AuthUser $authUser, Property $property): bool - { - return $authUser->can('replicate_property'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_property'); - } - - public function delete(AuthUser $authUser, Property $property): bool - { - return $authUser->can('delete_property'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_property'); - } - - public function forceDelete(AuthUser $authUser, Property $property): bool - { - return $authUser->can('force_delete_property'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_property'); - } -} diff --git a/workbench/app/Policies/TaxClassPolicy.php b/workbench/app/Policies/TaxClassPolicy.php deleted file mode 100644 index 1aae5a7..0000000 --- a/workbench/app/Policies/TaxClassPolicy.php +++ /dev/null @@ -1,74 +0,0 @@ -can('view_any_tax_class'); - } - - public function view(AuthUser $authUser, TaxClass $taxClass): bool - { - return $authUser->can('view_tax_class'); - } - - public function create(AuthUser $authUser): bool - { - return $authUser->can('create_tax_class'); - } - - public function update(AuthUser $authUser, TaxClass $taxClass): bool - { - return $authUser->can('update_tax_class'); - } - - public function restore(AuthUser $authUser, TaxClass $taxClass): bool - { - return $authUser->can('restore_tax_class'); - } - - public function restoreAny(AuthUser $authUser): bool - { - return $authUser->can('restore_any_tax_class'); - } - - public function replicate(AuthUser $authUser, TaxClass $taxClass): bool - { - return $authUser->can('replicate_tax_class'); - } - - public function reorder(AuthUser $authUser): bool - { - return $authUser->can('reorder_tax_class'); - } - - public function delete(AuthUser $authUser, TaxClass $taxClass): bool - { - return $authUser->can('delete_tax_class'); - } - - public function deleteAny(AuthUser $authUser): bool - { - return $authUser->can('delete_any_tax_class'); - } - - public function forceDelete(AuthUser $authUser, TaxClass $taxClass): bool - { - return $authUser->can('force_delete_tax_class'); - } - - public function forceDeleteAny(AuthUser $authUser): bool - { - return $authUser->can('force_delete_any_tax_class'); - } -} diff --git a/workbench/app/Providers/AuthServiceProvider.php b/workbench/app/Providers/AuthServiceProvider.php index e047e85..460e912 100644 --- a/workbench/app/Providers/AuthServiceProvider.php +++ b/workbench/app/Providers/AuthServiceProvider.php @@ -2,7 +2,29 @@ namespace Workbench\App\Providers; +use Eclipse\Catalogue\Models\Category; +use Eclipse\Catalogue\Models\Group; +use Eclipse\Catalogue\Models\MeasureUnit; +use Eclipse\Catalogue\Models\PriceList; +use Eclipse\Catalogue\Models\Product; +use Eclipse\Catalogue\Models\ProductStatus; +use Eclipse\Catalogue\Models\ProductType; +use Eclipse\Catalogue\Models\Property; +use Eclipse\Catalogue\Models\PropertyValue; +use Eclipse\Catalogue\Models\TaxClass; +use Eclipse\Catalogue\Policies\CategoryPolicy; +use Eclipse\Catalogue\Policies\GroupPolicy; +use Eclipse\Catalogue\Policies\MeasureUnitPolicy; +use Eclipse\Catalogue\Policies\PriceListPolicy; +use Eclipse\Catalogue\Policies\ProductPolicy; +use Eclipse\Catalogue\Policies\ProductStatusPolicy; +use Eclipse\Catalogue\Policies\ProductTypePolicy; +use Eclipse\Catalogue\Policies\PropertyPolicy; +use Eclipse\Catalogue\Policies\TaxClassPolicy; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Spatie\Permission\Models\Role; +use Workbench\App\Policies\PropertyValuePolicy; +use Workbench\App\Policies\RolePolicy; class AuthServiceProvider extends ServiceProvider { @@ -12,7 +34,17 @@ class AuthServiceProvider extends ServiceProvider * @var array */ protected $policies = [ - // + Category::class => CategoryPolicy::class, + Group::class => GroupPolicy::class, + MeasureUnit::class => MeasureUnitPolicy::class, + PriceList::class => PriceListPolicy::class, + Product::class => ProductPolicy::class, + ProductStatus::class => ProductStatusPolicy::class, + ProductType::class => ProductTypePolicy::class, + Property::class => PropertyPolicy::class, + PropertyValue::class => PropertyValuePolicy::class, + TaxClass::class => TaxClassPolicy::class, + Role::class => RolePolicy::class, ]; /** @@ -20,6 +52,6 @@ class AuthServiceProvider extends ServiceProvider */ public function boot(): void { - // + $this->registerPolicies(); } } diff --git a/workbench/config/filament-shield.php b/workbench/config/filament-shield.php index d818cce..54e4002 100644 --- a/workbench/config/filament-shield.php +++ b/workbench/config/filament-shield.php @@ -43,7 +43,7 @@ 'policies' => [ 'path' => app_path('Policies'), 'merge' => true, - 'generate' => true, + 'generate' => false, // Disabled: policies are registered via AuthServiceProvider using existing ones from src/Policies/ 'methods' => [ 'viewAny', 'view', 'create', 'update', 'restore', 'restoreAny', 'replicate', 'reorder', 'delete', 'deleteAny', 'forceDelete', 'forceDeleteAny',