-
Notifications
You must be signed in to change notification settings - Fork 903
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
Lifecycle hooks for CrudPanel functionality #5687
base: next
Are you sure you want to change the base?
Conversation
Playground for syntax: <?php
static::created(function (User $user) {
// ...
});
OperationHook::register(
OperationHooks::AFTER_OPERATION_SETUP,
'list',
function () { $this->runCustomViews(); }
);
// equivalent
Backpack::hook(
event: OperationHooks::AFTER_OPERATION_SETUP,
operation: 'list',
run: function() { $this->runCustomViews(); }
);
// equivalent
Backpack::hook(
event: 'afterOperationSetup',
operation: 'list',
run: function() { $this->runCustomViews(); }
);
// nah
BackpackHook::afterOperationSetup('list', function() {
$this->runCustomViews();
});
// nah
BackpackHook::on(OperationHooks::AFTER_OPERATION_SETUP)
->operation('list')
->do(function() {
$this->runCustomViews();
});
// -----
BackpackHook::moderated(
operation: 'moderate',
run: function() { $this->runCustomViews(); }
);
'moderated' => [
'operation' => 'moderate',
'closure' => (function() {})
]
// ModerateOperation
public function saveModeration() {
// do something
$args = [
$entry,
];
BackpackHook::run('moderated', $args);
}
// -----
BackpackHook::operation('list', function() {});
BackpackHook::operation('list', function() {});
Backpack::hookInto('moderated', function() {});
Backpack::hookIntoOperation('list', 'moderated', function() {});
|
Todo: docs for this PR (original PR, with separate PanelHooks and OperationHooks). |
OperationHooksOperationHooks are a way to hook into the operation process. They are used to modify the operation process in some way, before or after the operation is setup. There are three types of OperationHooks: BEFORE_OPERATION_SETUP, AFTER_OPERATION_SETUP and OPERATION_SETUP_CONFIGS. BEFORE_OPERATION_SETUPThis hook is called before the operation is setup. It is used to modify the operation in some way, before it is setup.
AFTER_OPERATION_SETUPThis hook is called after the operation is setup. It is used to modify the operation in some way, after it is setup.
OPERATION_SETUP_CONFIGSThis hook is used to modify the behavior of some setup settings, like from what file should the operation load his configs.
PanelHooksPanelHooks can be seen a general purpose hooks, they are used to modify the panel, modify operations at different operation points etc. BEFORE_SETUP_ROUTES If you are creating a custom operation, you can use the PanelHooks to create a point in your operation where developers using your operation can "hook" to modify the default behavior of your operation: eg: // ModerateOperation.php
// .. setup routes, defaults etc ..
public function moderate($id)
{
// do some moderation functions ...
PanelHooks::run('after-moderation', ['id' => $id, 'moderatedEntry' => $entry]);
}
// developers can then register they own behavior for the 'after-moderation' hook
// for example in a middleware, or in the `setup()` of the controller where they use your operation:
public function setup()
{
PanelHooks::register('after-moderation', function($id, $moderatedEntry) {
// do something with the moderated entry
});
} The main point of Hooks is to reduce the amount of overwrites, promoting a more modular and reusable code without the need to catter to all different |
CRUD Lifecycle EventsAt important points in the CRUD Lifecycle, Backpack triggers what we call "lifecycle events". You can hook into those events - by registering custom code that will run when that lifecycle event happens. This allows you to customize the process, without having to override any of the core files for CRUD or an Operation. For example, in a Backpack CRUD all routes are setup on the CrudController using methods like LifecycleEvent::hookInto('crud:before_all_route_setup', function($controller, $operation) {
// do something useful
}); Here are all the Lifecycle Events we currently have:
In addition to the general lifecycle events above, each operation can trigger its own lifecycle events. For example, here are the lifecycle events triggered by the Create operation:
LifecycleEvent::hookInto(['create:before_setup', 'list:before_setup', 'moderate:before_setup'], function() {
$this->crud->addButton('top', 'create', 'view', 'crud::buttons.create');
});
LifecycleEvent::trigger('moderate:after_moderation', [
'controller' => $controller,
'operation' => $operation,
]); |
[ci skip] [skip ci]
[ci skip] [skip ci]
[ci skip] [skip ci]
[ci skip] [skip ci]
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.
Thanks for the details Pedro. I replied inline. I understand why you've made the decisions you've made now. And I agree with most of them.
Not sure about moving the config-loading on the CRUD side though. It really looks like it's making this something it's not supposed to be.
I think the safest thing to do would be to move that to a different PR. Then we can move this PR forward, merge it, and think about that separately as an improvement to the DX of creating operations.
[ci skip] [skip ci]
0cffae1
to
8ece6d2
Compare
The objective of this PR is to streamline the usage of "hooks" in our software, so that developer can do the most possible, without overwrites.
We have already concluded that overwrites are the pain point when updating backpack, and it also limits our options when we want to push new features. It's not uncommon to find conditionals in our codebase to account for overwritten files.
This is very very wip. I just got the liberty from @tabacitu to work on some concepts for stuff we aim to do, this is one of those.