Fix a regression introduced by version 1.7.8.4 of Prestashop on the management of hooks

Fix Hooks bug on PrestaShop 1.7.8.4

Following the successive feedback from several users of the latest version 1.7.8.4 of Prestashop on modules not working or not displaying properly on their store, it was discovered a problematic evolution in the code of the management of PrestaShop hooks.

What is a Hook on PrestaShop

PrestaShop integrates a management of the display locations of the elements on the stores in the form of hooks or any module or any code can be attached so be executed each time the Hook is called.

There are several types of Hook.

  • Display Hooks which are used to simply display elements in specific locations.
  • Action Hooks that are called when an action is performed in Prestashop, for example, when a product is updated, or when an order is validated.

We often encounter modules that are developed without knowing the existence and uses of these hooks, which can cause major problems. Many developers prefer to use their own custom scripts without ever using these systems and therefore prevent other modules that are properly attached from being informed of the changes made and therefore risk causing database errors, data inconsistencies or other problems.

The use of Hooks is essential for any development of modules respecting the functioning of PrestaShop.

The bug (regression) of PrestaShop version 1.7.8.4.

Version 1.7.8.4 has changed the code for retrieving hooks from the database.

This change is coherent but it has forgotten a key element: The case sensitive.

Thus, if you code the name of the called Hook incorrectly, it does not work anymore.

Before you call the hook this way hookDisplayHeader or hookdisplayheader, it worked, which is no longer the case with this version.

The code

The code before the modification:

    public static function getHookStatusByName($hook_name): bool
    {
        $sql = new DbQuery();
        $sql->select('active');
        $sql->from('hook', 'h');
        $sql->where('h.name = "' . pSQL($hook_name) . '"');

        return (bool) Db::getInstance()->getValue($sql);
    }

The code that causes the error:

    public static function getHookStatusByName($hook_name): bool
    {
        $hook_names = [];
        if (Cache::isStored('active_hooks')) {
            $hook_names = Cache::retrieve('active_hooks');
        } else {
            $sql = new DbQuery();
            $sql->select('name');
            $sql->from('hook', 'h');
            $sql->where('h.active = 1');
            $active_hooks = Db::getInstance()->executeS($sql);
            if (!empty($active_hooks)) {
                $hook_names = array_column($active_hooks, 'name');
                if (is_array($hook_names)) {
                    Cache::store('active_hooks', $hook_names);
                }
            }
        }

        return in_array($hook_name, $hook_names);
    }

The explanation of the problem

In the old code we see that only a simple SQL query is used which is not case sensitive.

While in the second code, we find a text in_array() which is case sensitive, hence the processing error that is generated due to different denominations with or without capital letters of Hooks.

The correction

To solve this problem it is quite simple to always process the data in lower case to eliminate the problem of capitalization.

This seems to be a matter of course and many developers use this system precisely to avoid having to deal with naming errors.

To correct the problem, you need to open the :

classes/Hook.php

replace line 1280

$sql->select('name');

by

$sql->select('lower(name) as name');

then replace line 1292

return in_array($hook_name, $hook_names);

by

return in_array(strtolower($hook_name), $hook_names);

Glossaire

Conclusion

Whatever your level of development, you must learn to anticipate potential errors of this type, because they are insidious and can make you waste a lot of time looking for solutions because they are difficult to identify, so think about it during your next developments.

Sources : https://github.com/PrestaShop/PrestaShop/pull/27874

Comments