forked from PrestaShop/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Pablo Borowicz
committed
Oct 25, 2021
1 parent
e9c0228
commit 9d991f8
Showing
6 changed files
with
230 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,91 +1,22 @@ | ||
--- | ||
title: The Hook component | ||
menuTitle: Hook | ||
chapter: true | ||
--- | ||
|
||
# The Hook component | ||
|
||
|
||
The preferred way to customize PrestaShop is using Modules. Modules allow to customize PrestaShop in many ways. | ||
|
||
The main path for Module integration are extension points called "Hooks", which are placed throughout the system. Modules can subscribe to hooks in order to provide or alter features. | ||
One of the main ways Modules interact with PrestaShop is through "Hooks" – PrestaShop's event system. Hooks are extension points which are placed throughout the system, allowing subscribing Modules to be notified of system events, inject content, or even alter the behavior of PrestaShop. | ||
|
||
There are two types of hooks: | ||
|
||
- **Display hooks** – Integrated mainly (but not exclusively) in templates, they allow modules to provide content that will be injected somewhere in a page. | ||
- **Action hooks** – Allow modules to be informed of something happening in the system, and optionally alter the system’s behavior by modifying provided data. | ||
|
||
## Subscription registry | ||
|
||
PrestaShop's `Hook` component acts as a registry for hook subscriptions. It stores which modules have subscribed to which hook. Multiple modules can subscribe to the same hook, and a single module can subscribe to multiple hooks. | ||
|
||
Here is how a Module subscribes to hook `registerGDPRConsent`: | ||
|
||
```php | ||
<?php | ||
class Somemodule extends Module | ||
{ | ||
public function install() | ||
{ | ||
return parent::install() && $this->registerHook('registerGDPRConsent'); | ||
} | ||
} | ||
``` | ||
You can also register multiple hooks. Here is how a Module subscribes to hook `registerGDPRConsent` and `displayProductAdditionalInfo`: | ||
|
||
|
||
```php | ||
<?php | ||
class Somemodule extends Module | ||
{ | ||
const AVAILABLE_HOOKS = [ | ||
'registerGDPRConsent', | ||
'displayProductAdditionalInfo', | ||
]; | ||
|
||
public function install() | ||
{ | ||
return parent::install() && $this->registerHook(self::AVAILABLE_HOOKS); | ||
} | ||
} | ||
``` | ||
|
||
|
||
## Hook dispatcher | ||
|
||
Throughout the software, multiple hooks are dispatched: this means at some point the system will look at all modules which subscribe to a given hook and trigger them, waiting for a result. | ||
|
||
This is how a hook can be dispatched using `Hook` class: | ||
|
||
```php | ||
$id = Hook::exec('actionModifyZoning', ['address_id' => $addressID]); | ||
``` | ||
|
||
## Module callback | ||
|
||
Modules which have previously subscribed to this hook will be notified and will be able to act on this hook. Depending on the hook's nature, they can alter the data being passed, trigger an event or even return a result (a data structure or raw HTML) to be used within PrestaShop. | ||
|
||
In order to be notified when the subscribed hooks are dispatched, in addition to subscribing to them, modules must also declare one public callback function per subscribed hook, following this naming schema: `hook<SubscribedHookName>`. That way, when a hook is dispatched, the dispatcher will be able to identify and call the appropriate callback on each subscriber. | ||
- **Display hooks** – Integrated mainly (but not exclusively) in templates, they allow modules to provide content that will be injected at a specific place in a page. Display hook names usually start with _"display"_. | ||
- **Action hooks** – Allow modules to be informed of something happening in the system, and optionally alter the system’s behavior by modifying the provided data. Action hook names usually start with _"action"_. | ||
|
||
This means that in order to fully subscribe to a hook, a module must call `registerHook()` **and** declare a callback. For example: | ||
## In this section | ||
|
||
```php | ||
<?php | ||
class Somemodule extends Module | ||
{ | ||
public function install() | ||
{ | ||
return parent::install() && $this->registerHook('registerGDPRConsent'); | ||
} | ||
{{% children /%}} | ||
|
||
public function hookRegisterGDPRConsent($parameters) | ||
{ | ||
// This is where you can modify/alter the behavior of PrestaShop. | ||
// The content of $parameters will depend on what is sent when the hook is dispatched. | ||
} | ||
} | ||
``` | ||
## Related reading | ||
|
||
{{% notice tip %}} | ||
Notice how hook names start with a lower case letter (`registerGDPRConsent`), and hook callbacks use the capitalized name `hookRegisterGDPRConsent`. | ||
{{% /notice %}} | ||
- [List of hooks]({{< relref "/8/modules/concepts/hooks/list-of-hooks" >}}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
--- | ||
title: Dispatching a Hook | ||
weight: 20 | ||
--- | ||
|
||
# Dispatching a Hook | ||
|
||
Hooks are placed everywhere throughout the software. Whenever a given hook is dispatched, the Hook component will check which modules subscribed to that hook and notify them by successively calling each subscriber's callback. | ||
|
||
Hooks are dispatched using the `Hook::exec()` function. | ||
|
||
```php | ||
Hook::exec( | ||
string $hookName, | ||
array $arguments, | ||
?int $moduleId = null, | ||
bool $returnArray = false, | ||
bool $checkExceptions = true, | ||
bool $usePush = false, | ||
int $shopId = null, | ||
bool $chain = false | ||
): mixed | ||
``` | ||
|
||
This method returns the result of all hook notification callbacks. The return type will depend on the notification callbacks and the value of `$returnArray`. | ||
|
||
##### Parameters | ||
|
||
`$hookName` | ||
: | ||
Name of the hook to dispatch. | ||
|
||
`$arguments` | ||
: | ||
Parameters to send with the hook event to subscribers. | ||
|
||
`$moduleId` | ||
: | ||
If defined, only the specified module will be notified for this hook event. | ||
**Note:** the module needs to have subscribed to the hook already. | ||
|
||
`$returnArray` | ||
: | ||
This parameter governs the return type for this method. By default, the return values from each callback will be concatenated and returned. If `$returnArray` is set to true, then this method will return an associative array of return values, indexed by module name. | ||
Note that this argument is incompatible with `$chain` and will be disabled automatically disabled if chaining is enabled. | ||
|
||
`$checkExceptions` | ||
: | ||
Modules can opt out from being notified for a hook if it's triggered in specific pages (module hook exceptions). If this parameter is set to false, these exceptions will be ignored and the modules will be notified anyway. | ||
**Note:** if the hook is triggered in the Back office, disabling this feature will bypass access restrictions to modules, allowing modules to be notified of the hook event even when the current employee's access restrictions to that module wouldn't normally allow it. | ||
|
||
`$usePush` | ||
: | ||
If enabled, the hook dispatcher will wait for the push file of any subscribed module to be updated before notifying it of the hook event. | ||
|
||
`$shopId` | ||
: | ||
This parameter is related to multistore. If set, the shop context will be switched to the specified shop for the duration of the dispatch. | ||
|
||
`$chain` | ||
: | ||
If this parameter is set to true, then the result of each subscriber callback will be used as parameters of the next subscriber's callback. | ||
|
||
##### Example | ||
|
||
```php | ||
$id = Hook::exec('actionModifyZoning', ['address_id' => $addressID]); | ||
``` | ||
|
||
In the example above, we dispatch the `actionModifyZoning` hook, along the `address_id` parameter. `$id` will contain the concatenation of all the values returned by subscribers' callbacks (if any). | ||
|
||
## Dispatching a hook from a template | ||
|
||
Hooks can be dispatched from templates as well. | ||
|
||
### Smarty | ||
|
||
```smarty | ||
{hook h='displayProductPriceBlock' product=$product type="unit_price"} | ||
``` | ||
|
||
### Twig | ||
|
||
```twig | ||
{{ renderhook('displayAdminProductsMainStepLeftColumnMiddle', { 'id_product': productId }) }} | ||
``` | ||
|
||
## Creating a new hook | ||
|
||
Dispatching a new hook doesn't require any special steps, you can simply choose a hook name, and call your new hook from wherever you need – even from within a module! | ||
|
||
{{% notice tip %}} | ||
Remember that hook names are global – choose your hook names carefully to reduce risks of collision with other modules or future Core hooks. | ||
{{% /notice %}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.