-
Notifications
You must be signed in to change notification settings - Fork 19
Hooks
In order to do several actions in PrestaShop, theps_mbo
module is using hooks (Developer doc for hooks).
The module use a lot of hooks, so to have a clean code structure, and to avoid making the root ps_mbo.php
file
bigger and bigger we choose to separate hooks in PHP Traits.
PrestaShop\Module\Mbo\Traits\UseHooks is the base to register new hooks.
Every registered hook is a separate trait, and is stored in this folder.
Both, file and trait names, must be Use{PascalCaseHookName}
in order to be loaded correctly :
-
UseDisplayBackOfficeEmployeeMenu
fordisplayBackOfficeEmployeeMenu
-
UseDashboardZoneOne
fordashboardZoneOne
- ...
Then, the minimum is to have the hook function in it :
-
hookDisplayBackOfficeEmployeeMenu
forUseDisplayBackOfficeEmployeeMenu
-
hookDashboardZoneOne
forUseDashboardZoneOne
- ...
Here an example of a valid hook :
<?php
declare(strict_types=1);
namespace PrestaShop\Module\Mbo\Traits\Hooks;
trait UseDashboardZoneTwo
{
/**
* Display addons link on the middle column of the dashboard
*
* @param array $params
*
* @return false|string
*/
public function hookDashboardZoneTwo(array $params)
{
$this->context->smarty->assign(
[
'shop_context' => json_encode($this->get('mbo.cdc.context_builder')->getViewContext()),
'cdcErrorUrl' => $this->get('router')->generate('admin_mbo_module_cdc_error'),
]
);
return $this->display($this->name, 'dashboard-zone-two.tpl');
}
}
This is done through the method registerHook
by the Module Core.
But, no need to list all hooks there is an helper UseHooks::getHooksNames
If you add new hooks, or remove some between module versions, you can just call UseHooks::updateHooks in your upgrade file.
<?php
function upgrade_module_x_x_x(Module $module): bool
{
$module->updateHooks();
}
This hook allows us to register JS & CSS file in the current page.
As we may want to separate files for each usage, we don't want to register all assets in this trait.
For instance, if we have a specific CSS file to be loaded only on the dashboard for something displayed by another hook, we want to have the logic which register this file in the dashboard hook trait.
So, the UseActionAdminControllerSetMedia
trait is designed to be called by other traits to register their assets.
Other hooks can call boot{HookClassName}
function, documented just below to register a callback which will be executed
on the actionAdminControllerSetMedia
hook runtime.
Let's look at an example :
// In ps_mbo/Traits/Hooks/UseDashboardZoneOne.php
// Declaring the boot{HookClassName} function
public function bootUseDashboardZoneOne(): void
{
// Be sure the addAdminControllerMedia function exists (created in the UseActionAdminControllerSetMedia trait)
if (method_exists($this, 'addAdminControllerMedia')) {
// Register a callback to be called by the actionAdminControllerSetMedia hook when needed
$this->addAdminControllerMedia('loadMediaDashboardZoneOne');
}
}
And then, on actionAdminControllerSetMedia
runtime each callback will be called to register assets.
// Still in ps_mbo/Traits/Hooks/UseDashboardZoneOne.php
protected function loadMediaDashboardZoneOne(): void
{
// Assets need to be displayed only when on dashboard
if (\Tools::getValue('controller') === 'AdminDashboard') {
$this->context->controller->addJs($this->getPathUri() . 'views/js/cdc-error-templating.js');
$this->context->controller->addCss($this->getPathUri() . 'views/css/cdc-error-templating.css');
}
}
If you want to register assets globally, you can add them directly to the loadMediaForAdminControllerSetMedia
function in the UseActionAdminControllerSetMedia
trait.
In some cases, we want to make some operations linked to the hook, but external of the actual hook runtime.
The classic case is to register assets, as seen just above.
The boot functions are executed on each module load, in the __construct
method, when the module is active.
This method is called only once, when the hook is registered. It can allow you to make some special configurations, in DB for instance.
They are listed in the ps_mbo/Traits/Hooks
folder.
This hook sends to you some data :
Hook::exec('actionMboRecommendedModules', [
'recommendedModulesDisplayed' => &$recommendedModulesDisplayed,
'controller' => $controller,
]);
-
recommendedModulesDisplayed
=> Boolean, always true -
controler
=> String, the current controller name
So you can choose, for a given controller, to hide the recommended modules section.
If your set the $recommendedModulesDisplayed
to false
it will :
- Recommended modules are displayed as button in the navbar : completely hide the button
- Displayed in page, under content : it will move them in a modal, and add the button "Recommended modules & Services" in the navbar instead.