Collection hook

Forest Admin allows customizing at a very low level the behavior of any given Collection via the usage of Collection Hooks.

Collection Hooks are a very powerful feature and require special care when using them.

How it works

Any given Collection should implement all of the following functions:

  • list

  • create

  • update

  • delete

  • aggregate

The Collection Hooks feature allows executing code before and/or after any of these functions, providing an easy way to interact with your Collections.

To declare a Hook on a Collection, the following information is required:

  • A lifecycle position (Before | After)

  • An action type (List | Create | Update | Delete | Aggregate)

  • A callback, that will receive a context matching the provided hook position and hook definition.

Basic use cases

In the following example, we want to prevent a set of users from updating any records of the Transactions table. We want to check if the user email is allowed to update a record via an external API call.

use ForestAdmin\AgentPHP\DatasourceCustomizer\CollectionCustomizer;

$forestAgent->customizeCollection(
    'Transactions',
    function (CollectionCustomizer $builder) {
        $builder->addHook('Before', 'Update', function ($context) {
            // $context->getCaller() contains information about the current user, the defined timezone, etc.
            // In this case, $context->getCaller()->getValue('email') is the email used in Forest Admin by the user that initiated the call
            $email = $context->getCaller()->getValue('email');
            $isAllowed = myFunctionToCheckIfUserIsAllowed($email);

            if (!$isAllowed) {
                $context->throwForbiddenError($context->getCaller()->getValue('email') . ' is not allowed!');
            }
        });
    }
);

Another good example would be the following: Each time a new User is created in the database, I want to send him an email.

use ForestAdmin\AgentPHP\DatasourceCustomizer\CollectionCustomizer;
use MyEmailSender;

$forestAgent->customizeCollection(
    'User',
    function (CollectionCustomizer $builder) {
        $builder->addHook('After', 'Create', function ($context) {
            // The result of the create function always return a record
            $email = $context->getRecord()['email'];
            MyEmailSender::sendEmail(
                [
                    'from'    => '[email protected]',
                    'to'      => $email,
                    'message' => 'Hey, a new account was created with this email.',
                ]
            );
        });
    }
);

Last updated

Was this helpful?