Policy depends on request path

Hello All, I have the following problem: I have a [event] resource and the resource view page have a couple of relations (eg. attendees, vendors, etc). I want to add policies to these relations, but to determine if the given user has access to an operation I need the event id {record}. I tried to reach the request route parameter (request()->route()->parameter('record');), it works, but when I change tab, the livewire call (livewire/update) behind the scene refresh the data and the given operation will be refused due to the livewire call does not have the {record} parameter in the url . As a workaround I thought to save the event_id to a session variable, but this will cause a problem when a user have multiple browser window with different event to view. Question how can I reach an URL parameter and make it available for the subsequent livewire calls?
4 Replies
Povilas K
Povilas K2w ago
I personally wouldn't do that in Policies but rather when querying the data - showing only records belonging to specific relationship. Either modifying the query of the tables/forms, or via Global Scope. So those users wouldn't even see the data that doesn't belong to them, in any Eloquent queries, on the Eloquent level and not Filament/Livewire
Roland Barkóczi
Hello Povilas, First of all thank you for your answer. Also thanks for your youtube tutorials, they're very helpful! Let me explain a little bit more the use case: - each event has an own set of roles and each roles has a set of (customizable) permissions - the event has staff and each staff member has a role, roles has permissions (not the spatie role/permission solution) - the staff member can manage attendees, vendors, etc, but only in case the assigned role has the appropriate permission - therefore to show the appropriate relation tab (e.g. attendee) I created the attendeePolicy, but in this policy I need to query which event is being displayed and query the authenticated user_id against its roles and permissions
- as I wrote in my original post, I can reach the url parameter, but the subsequent livewire queries does not have such parameter, therefore after the first click all tabs disappear (because the policy will return false) I need somehow access the actual event id in the subsequent livewire calls as well.
Povilas K
Povilas K2w ago
Mm, yeah, then I guess my advice doesn't really apply. Sorry, I don't have any quick answer here, without debugging the actual situation.
Roland Barkóczi
I finally found a solution, maybe not professional. In order to reach the given event id, my first attempt was
$event_id = request()->route()->parameter('record');
$event_id = request()->route()->parameter('record');
But it was null at any subsequent Livewire call. I checked the filament source code, and it is not possible to somehow inject the Event dependency to the given policy. I also checked the Livewire class static functions, and I found one which contains the current path:
$event_id = explode("/", Livewire::originalPath())[2] ?? null;
$event_id = explode("/", Livewire::originalPath())[2] ?? null;
I am not 100% happy with the solution (hardcoded parameter position) but it works so far, because this function returns the original path of every subsequent livewire update and actually at the original query as well.
Want results from more Discord servers?
Add your server