test-policy mit mkro zum Filtern von Datensätzen in Tabelle

This commit is contained in:
2026-02-09 01:49:28 +00:00
parent 16085c67f8
commit 1e273deb47
4 changed files with 132 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
namespace App\Providers;
use Filament\Tables\Table;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@@ -19,6 +20,58 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
//
# Makro, um die Zeilen zu filtern.
# geklaut hier: https://filamentglow.com/trick/implementing-row-level-security-in-filament-tables-with-applyrowaccesspolicy-30090998
Table::macro('applyRowAccessPolicy', function (\Closure | bool $condition = true): Table {
if ($condition instanceof \Closure) {
$condition = $this->evaluate($condition);
}
/**
* Store the view row scope condition in Laravel's service container.
*
* How this works:
* 1. We generate a unique ID for each Table instance using spl_object_hash()
* 2. We create a container binding with a key specific to this Table instance
* 3. The condition value (true/false) is stored in the container
*
* The container binding will be automatically cleaned up when the Table instance
* is garbage collected, as the binding key is unique to this instance.
*/
$tableId = spl_object_hash($this);
app()->instance('filament.table.viewRowScope.' . $tableId, $condition);
return $this->modifyQueryUsing(function (\Illuminate\Database\Eloquent\Builder $query) use ($tableId): \Illuminate\Database\Eloquent\Builder {
// Check the container for this Table's specific viewRowScope setting
// Defaults to true if no binding exists (fallback for safety)
$shouldApply = app()->bound('filament.table.viewRowScope.' . $tableId)
? app()->make('filament.table.viewRowScope.' . $tableId)
: true;
if (! $shouldApply) {
return $query;
}
$model = $query->getModel();
if (! $model) {
return $query;
}
$policy = \Gate::getPolicyFor($model);
if (! $policy || ! method_exists($policy, 'applyRowAccessPolicy')) {
return $query;
}
$modifiedQuery = $policy->applyRowAccessPolicy(auth()->user(), $query);
if (! $modifiedQuery instanceof \Illuminate\Database\Eloquent\Builder) {
throw new \RuntimeException("The applyRowAccessPolicy method for " . $policy::class . " must return an instance of Illuminate\Database\Eloquent\Builder.");
}
return $modifiedQuery;
});
});
}
}