community-forum
community-forum copied to clipboard
[v6][Idea] Trigger events during Operations and CRUD process
Quite a few times, we've needed to do stuff before or after Backpack is doing something. We could implement hooks (before_x_operation or before_setup etc) but I think a more long-term solution would be implementing an event system. Backpack triggering events at different touchpoints, so that Backpack itself or the developer can hook into those events, and do stuff there.
Before we do that, we need a list of events. Here's mine:
- inside
CrudController:- 🟡 before & after
setupRoutes() - 🔴 before & after
setupDefaults() - 🔴 before & after
setup() - 🔴 before & after
setupConfigurationForCurrentOperation()
- 🟡 before & after
- inside each Operation:
- I don't think this is actually needed; some operations might offer events... maybe... but it should be a requirement;
- inside CrudPanel
- 🔵 before & after
setModel()? - 🔵 before & after
setRoute()? - 🔵 before $after
setRouteName()? - the above aren't really needed IMHO since that is done in
EntityCrudController::setup()- dev already has access to them; if we move those toCrudControlleras properties though... then it would make sense; - 🔵 before & after
create()? - 🔵 before & after
createRelationsForItem()? - 🔵 before & after
update()? - I don't think the above are needed either;
- 🔵 before & after
What else would be needed? What other events would be nice to have? What naming could we use for this? What prefixing system do events usually use, so they don't conflict with other events?
Food for thought.
Ping @pxpm
You know what I think about this, let's brainstorm it and get out of here with a solution we are confortable with maintaining 👍
I think a good name structure/rules could be something like:
before/afterFunctionNameEvent, eg:
- beforeSetupEvent
- afterSetupEvent
- beforeSetupConfigurationForCurrentOperationEvent
- afterSetupConfigurationForCurrentOperationEvent
I think we only need the request as the event parameter, since the crud object we can get from the container.
Another scenario is building the event system not coupled with the functions, but we create the events for our "lifecycle". So having listeners with more general names like BeforeOperationListener extends OperationListener, where you could for example define a property or have a static method or use regexed functions
class `BeforeOperationListener extends OperationListener`
{
public function listenToCreate() {
}
public function listenToUpdate() {
}
public function listenToInlineCreate() {
}
}
I need to put this event system on our "real" use case like inline create or dropzone to have a better picture of what are the real requirements.
When we are done with the uploads I will invest some time in a simple poc for the event implementation. We need to take into consideration scenarios like defining operation stuff with closures inside setup() or using the setupOperation methods.
Cheers
I think a good name structure/rules could be something like: before/afterFunctionNameEvent, eg:
- beforeSetupEvent
- afterSetupEvent
- beforeSetupConfigurationForCurrentOperationEvent
- afterSetupConfigurationForCurrentOperationEvent
Yeah that would be the easy way out but... they're so ugly... and very different from Laravel's Eloquent event names. But honestly, I've yanked my brains and can't find a solution that would look laravelly... So let's go with these event names on the CrudPanel object, yes. Though I don't think we need Event at the end... right? So we could just do:
- 🟡
beforeSetupRoutes&afterSetupRoutes - 🔴
beforeSetupDefaults&afterSetupDefaults - 🔴
beforeSetup&afterSetup - 🔴
beforeSetupConfigurationForCurrentOperation&afterSetupConfigurationForCurrentOperation
And I just realised... those are useful when you want to target ALL operations... but they aren't really useful when you want to target a particular operation. So perhaps we should also trigger some operation-specific events by default? eg.
- 🟡
beforeSetupCreateRoutes&afterSetupCreateRoutes - 🟡
beforeSetupCreateDefaults&afterSetupCreateDefaults
Another scenario is building the event system not coupled with the functions, but we create the events for our "lifecycle". So having listeners with more general names like BeforeOperationListener extends OperationListener, where you could for example define a property or have a static method or use regexed functions
I... didn't understand any of this, sorry 😅 The way I see it, we shouldn't provide a way to consume/use those events. We just trigger them, like any Laravel events. And if we DO provide a custom way to use them... that way should probably be similar to using Eloquent Model events - that's what I would find most intuitive. Instead of doing Product::deleting($closure) you'd do CRUD::beforeSetupRoutes($closure) 🤷♂️ or if we don't want a catch-all (to minimize the potential impact) we could do CRUD::onEvent('beforeSetupRoutes', $closure) or something like that. That's what I find intuitive, at least.