diff --git a/src/FilamentClearCachePlugin.php b/src/FilamentClearCachePlugin.php index bb283b1..9ca7603 100644 --- a/src/FilamentClearCachePlugin.php +++ b/src/FilamentClearCachePlugin.php @@ -6,6 +6,8 @@ use CmsMulti\FilamentClearCache\Http\Livewire\ClearCache; use Composer\InstalledVersions; use Filament\Contracts\Plugin; +use Filament\Facades\Filament; +use Filament\Pages\SimplePage; use Filament\Panel; use Illuminate\Support\Facades\Blade; use Livewire\Livewire; @@ -20,11 +22,25 @@ class FilamentClearCachePlugin implements Plugin const VERSION = '3.0.1'; + protected bool $hiddenOnSimplePages = true; + public static function make(): static { return app(static::class); } + public function hiddenOnSimplePages(bool $condition = true): static + { + $this->hiddenOnSimplePages = $condition; + + return $this; + } + + public function isHiddenOnSimplePages(): bool + { + return $this->hiddenOnSimplePages; + } + public function getId(): string { return static::ID; @@ -44,10 +60,12 @@ public function register(Panel $panel): void $panel->renderHook( name: 'panels::user-menu.before', - hook: fn (): string => Blade::render( - '@livewire($component)', - ['component' => $component] - ), + hook: fn (): string => $this->shouldRenderClearCacheButton() + ? Blade::render( + '@livewire($component)', + ['component' => $component] + ) + : '', ); } @@ -71,4 +89,29 @@ private static function isLivewireV3(): bool return version_compare($version, '4.0.0', '<'); } + + private function shouldRenderClearCacheButton(): bool + { + if (! Filament::auth()->check()) { + return false; + } + + if (! $this->isHiddenOnSimplePages()) { + return true; + } + + $routeAction = request()->route()?->getActionName(); + + if (! is_string($routeAction) || $routeAction === 'Closure') { + return true; + } + + $routeClass = str($routeAction)->before('@')->toString(); + + if (! class_exists($routeClass)) { + return true; + } + + return ! is_subclass_of($routeClass, SimplePage::class); + } } diff --git a/tests/Unit/FilamentClearCachePluginTest.php b/tests/Unit/FilamentClearCachePluginTest.php index 5f90043..e3c1d2d 100644 --- a/tests/Unit/FilamentClearCachePluginTest.php +++ b/tests/Unit/FilamentClearCachePluginTest.php @@ -1,8 +1,14 @@ toBeTrue(); }); +it('does not render the clear cache button when unauthenticated', function () { + $hook = captureClearCacheRenderHook(); + + Blade::shouldReceive('render')->never(); + + expect($hook())->toBe(''); +}); + +it('does not render the clear cache button on simple pages', function () { + $hook = captureClearCacheRenderHook(); + + $this->actingAs(createClearCacheUser()); + setClearCacheRouteAction(FilamentClearCachePluginTestSimplePage::class); + + Blade::shouldReceive('render')->never(); + + expect($hook())->toBe(''); +}); + +it('can render the clear cache button on simple pages when enabled', function () { + $hook = captureClearCacheRenderHook( + FilamentClearCachePlugin::make()->hiddenOnSimplePages(false), + ); + + $this->actingAs(createClearCacheUser()); + setClearCacheRouteAction(FilamentClearCachePluginTestSimplePage::class); + + Blade::shouldReceive('render') + ->once() + ->with('@livewire($component)', Mockery::type('array')) + ->andReturn('clear-cache-button'); + + expect($hook())->toBe('clear-cache-button'); +}); + +it('renders the clear cache button on non-simple pages', function () { + $hook = captureClearCacheRenderHook(); + + $this->actingAs(createClearCacheUser()); + setClearCacheRouteAction(Dashboard::class); + + Blade::shouldReceive('render') + ->once() + ->with('@livewire($component)', Mockery::type('array')) + ->andReturn('clear-cache-button'); + + expect($hook())->toBe('clear-cache-button'); +}); + it('no-ops during boot when disabled', function () { $panel = Mockery::mock(Panel::class); @@ -23,3 +78,37 @@ ->boot($panel)) ->not->toThrow(Throwable::class); }); + +function captureClearCacheRenderHook(?FilamentClearCachePlugin $plugin = null): Closure +{ + $hook = null; + $panel = Mockery::mock(Panel::class); + $panel + ->shouldReceive('renderHook') + ->once() + ->with('panels::user-menu.before', Mockery::on(function (Closure $renderHook) use (&$hook): bool { + $hook = $renderHook; + + return true; + })) + ->andReturnSelf(); + + ($plugin ?? FilamentClearCachePlugin::make())->register($panel); + + return $hook; +} + +function createClearCacheUser(): User +{ + return User::create([ + 'name' => 'John', + 'email' => 'test@test.com', + ]); +} + +function setClearCacheRouteAction(string $action): void +{ + $route = Route::get('/clear-cache-test-route', $action); + + request()->setRouteResolver(fn () => $route); +}