generated from DataLinx/eclipsephp-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 4
feat(worbench-setup): make plugin development self-contained #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
2e38866
feat(worbench-setup): prepare base setup
KilianTrunk 64917d2
chore(workbench-setup): setup fixes
KilianTrunk d92393a
chore(workbench-setup): fixes
KilianTrunk 919cb87
chore(workbench-setup): further fixes
KilianTrunk ac3d8c9
fix(migrations): only create table if not already
KilianTrunk f73d10a
chore(workbench-setup): final fixes
KilianTrunk 4fe23d8
fix(workbench-setup): fix composer test and format
KilianTrunk 2488f55
fix(workflows): fix github workflows
KilianTrunk 9de4466
chore(workbench-setup): remove config files
KilianTrunk ed3b2b0
chore(workbench-setup): seeder fixes
KilianTrunk 3c46c3c
build(workbench): set more gitignores
SlimDeluxe d865d36
build(workbench): fix workbench .env file setup
SlimDeluxe 496d65c
build(workbench): add permissions migration
SlimDeluxe c0449c1
build(workbench): fix app migrations
SlimDeluxe 509d473
fix: setup fixes
KilianTrunk dbd8516
fix: more fixes :(
KilianTrunk 4b4c382
fix: remove duplicate lando file
KilianTrunk 787aece
fix: remove duplicate migration
KilianTrunk 527b92a
fix: remove publishing from composer scirpt
KilianTrunk 07d0296
fix: fix ci
KilianTrunk d6dd7b6
fix: more test fixes
KilianTrunk 7493467
fix: revert tests changes
KilianTrunk 6cf7a1c
fix: fix phpunit file
KilianTrunk 8d76155
fix: add ci setup composer
KilianTrunk 0503693
Revert "fix: add ci setup composer"
KilianTrunk 099069a
fix: conditional publishing of permissions
KilianTrunk f571284
Revert "fix: conditional publishing of permissions"
KilianTrunk 2b8ad07
Revert "fix: remove publishing from composer scirpt"
KilianTrunk bd34417
fix: add empty migration, fix db namespace
KilianTrunk 18d3422
chore: add spatie laravel permission migration
KilianTrunk 9723879
chore: fix attempt of db setup
KilianTrunk d54f0af
chore: more fixes
KilianTrunk a717169
chore: add minimal composer json for workbench
KilianTrunk 6a29503
Merge branch 'main' into feat/workbench-setup
KilianTrunk 79e0c66
chore: setup improvements & fixes
KilianTrunk af00a7f
chore: permission fixes try
KilianTrunk c9c9b1e
chore: re-add migration
KilianTrunk af1291c
chore: more fixes
KilianTrunk 16e07f6
build(lando): update landofile
SlimDeluxe fbf57b8
build(workbench): add cache dir in storage
SlimDeluxe 50df5bf
chore(readme): update workbench instructions
KilianTrunk 2ff16ee
chore: temp commit
KilianTrunk 9763f18
Revert "chore: temp commit"
KilianTrunk eb5e9cd
fix: use local migrations
KilianTrunk 20193a3
chore: fix spatie permission publishing
KilianTrunk 1e2758a
chore: remove Spatie PermissionServiceProvider from composer setup
KilianTrunk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,23 @@ | ||
| .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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| <?php | ||
|
|
||
| namespace Workbench\App\Http\Middleware; | ||
|
|
||
| use Closure; | ||
| use Illuminate\Http\Request; | ||
| use Illuminate\Support\Facades\Artisan; | ||
| use Illuminate\Support\Facades\Auth; | ||
| use Illuminate\Support\Facades\Cache; | ||
| use Illuminate\Support\Facades\DB; | ||
| use Illuminate\Support\Facades\Hash; | ||
| use Illuminate\Support\Facades\Log; | ||
| use Spatie\Permission\Models\Permission; | ||
| use Spatie\Permission\Models\Role; | ||
| use Spatie\Permission\PermissionRegistrar; | ||
| use Workbench\App\Models\User; | ||
|
|
||
| class WorkbenchBootstrap | ||
| { | ||
| public function handle(Request $request, Closure $next) | ||
| { | ||
| if (config('app.env') === 'local' && ! Auth::guard('web')->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); | ||
| } | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about why you switched to a file instead of :memory:, there must have been a reason? To my surprise both are equally fast (/slow).