A deeper look at Prestashop Hooks

Today, we are going to cover one of the most overlooked feature of Prestashop: Hooks. I’ll be teaching you what these mysterious entities really are, and how to bend them to your will, and bring your site to the next level of customization.Download Project Files

What are hooks?

If you have been using Prestashop for quite some time, I bet you found yourself saying “Why in the world can’t I place something there? I really want to do it!” in more than one occasion. Yes, it can be frustrating, because Prestashop only allows you to execute your modules in specific spots, defined by the software itself. These places are commonly known as hooks. And this is actually all what hooks are, as the name suggests: they represent definite points of the code which you can use to run your own module’s functions.

If this may be considered as a limitation, since it forces the developer to only use those specific points to run a module’s code without touching the core files, it’s also a powerful and easy solution to greatly improve Prestashop’s basics functionalities. Actually, hooks make your life A LOT easier when extending the package. At least, you don’t have to mess for ages with XML and Zend Framework ugly PHP (have I heard someone screaming Magento?).

Anyway, if you are a developer, and know how to code a prestashop module, you’ll be quite used to the following structure:

public function hookLeftColumn($params)
{
/* Code to be executed */
}

This function allows the module to be hooked to the left column, and running proper code from there, be it something to display to the user, or stas gathering stuff. In any case, you will always need to run a hookSomewhere function to run the module’s code in a specific place.

Visual Hooks VS Action Hooks

Hooks can be basically grouped into 2 main groups: Visual Hooks, and Action Hooks.

The first ones are generally used to display content to your website, and provide a visual feedback to the customer. While there are in fact back Office visual hooks, like the one used to display new tabs on the Stats page, most of them are defined by controllers in front office, and assigned to variables to be executed within the template. An example of this is the “Left Column” hook we saw previously, used to show modules on the left column of the base template

Action hooks are, on the other side, deputed to only run code, without actually display content. They are placed both in class and controller files, and may come in handy when we need to gather data thrown by a class, manipulate it, or use it for purposes other than Prestashop’s default one. As the name suggests, they occur when a spacific action takes place. An example of action hook is the “cart” hook, executed in the Cart.php Class when a cart is created or updated.

To exemplify, let’s say we have a “best sales” module, and it uses database caching to optimize performance. It retrieves best sellers from a cached version of the product list created once in a while. Well, this once in a while can be set in two ways: the traditional way is to set up a cron job, and refresh the list once every hour, or day, or so; the other way would be using hooks. We could hook the module to “newOrder”, which is a hook that executes when a new order is placed, and code a function that refreshes data in that particular moment. This way, there would be now need to fetch all product data every time the page reloads, thus increasing our site’s speed. Of course, this is just an example (taken from one of my modules, Best sales of the day/week/month/period, which you can find here), and there are other many things you can do with action hooks.

Whichever purpose hooks have, they all share the same basic structure:

A database entry in the ps_hook table

This is the core part of the hooks, since it’s what makes Prestashop know whether the specific hook we are currently calling exists or not.

The hookExec() function which executes it

It’s the function that runs the hooks execution, and therefore all hookNameOfTheHook() function associated to it(see next). The function is defined in the Module Class, and can be passed a number of parameters to be stored in the $params variable of the executing function.

Module::hookExec('nameofthehook')

Module::hookExec('nameofthehook', $params_array)

When creating a front office visual hook, instead of directly executing the hooks attached modules, the action is assigned to a variable to be called by smarty within the template.

In this case, you would also need to add the following code to the template file where you wanted to display the hook’s content

{$HOOK_NAMEOFTHEHOOK}

A hookNameOfTheHook() function to be placed in modules in order to hook them

Without this, a module would not be hooked to anything and would never execute. This last function is the most important one, since it allows you to perform any action for the desired hook. We already saw the code for the HookLeftColumn() function.

public function hookLeftColumn($params)
{
/* Code to be executed */
}

This function usually returns a template file in front office hooks

return $this->display(__FILE__, 'filename.tpl')

Let’s go into action: creating a new Hook in Prestashop

Now that we know enough about hooks, let’s create a new hook that will allow us to display modules content at the beginning of each category page.

The first step will be to let Prestashop know the hook exists, so let’s add it to the database. We can go 2 ways: log in to phpmyadmin (or any sql manager) and add the column manually; or create a module which, when installed, will add the hook.

The database way:

Log in to your sql manager. In your prestashop database, look for the table ps_hook (remember, ps_ is just the default prefix, you can have anything instead of that! Take note of your prefix). If you’re using phpMyAdmin, click on the yourprefixHook table, then Insert, and add values for the name (which should be all underscore and without spaces), title and description then click add. Alternatively, you can use run this SQL query:

The $check part is useful to know if another hook with the same name exists, since creating douplicates will definitely cause problems!

Executing the hook

Now that prestashop has the hook data stored, it’s time to run it’s execution

self::$smarty->assign('HOOK_CATEGORY', Module::hookExec('category'));

We can place this code in the FrontController.php file, or any other controller, since we are going to use the hook for display purposes. Using the FrontController saves us the time of thinking where exactly it should run, because assigning the variable in the DisplayHeader function will set it for every front page, before even one of the other hooks is assigned. So, to add the assignment to the Front Controller, let’s create a new FrontController.php file, place it into override/classes, and fill it with the following code.

Note the if (!self::$initialized) $this->init(); snippet at the beginning of the function. This ensures the controller is properly initialized, and fixes problems in pages such as payment or order confirmation..

Even though using the front controller saves us the time of having to scrub through all other controllers to find the right position to execute it, be aware that it will be assigning the execution for every front page of the shop. So, for our purposes, it would have been better to add the assignment in the process() function of the CategoryController. In the end, of course, the choice is all up to you. For the sake of it, here is what adding the code to a categoryController override would have looked like

Let’s open up the category.tpl file of our template.Just before this code

{if $products}

Which is line 90 of the prestashop_new template, add the following

{$HOOK_CATEGORY}

Most of the work it’s done, and we have just successfully added a new hook in Prestashop!

Creating a module to be hooked

…Yay, okay, but we need to test this new hook, or else we don’t know if it really works or not. I’ve prepared a testing module, which can be found as an attachment at the beginning of the post. Grab it, copy the “testing” folder inside the modules folder and open the testing.php file.

If you know something about modules, you’ll definitely know they have to be registered to a hook before they can be executed. If you don’t want to do it manually from the positions tab in back office, add the following code in the install() function:

Let’s install the module, go to a category page of the shop and see if the template’s content appears where we placed the hook variable. It’s likely we won’t see anything at the moment, but don’t fear. Since Prestashop uses caching, we must first re-compile the cache to see changes. Let’s go to preferences, then performance in back office, and turn on the option “Force Compile”, then refresh the category page. At this point, we should see a piece of text saying “Howdy guys! testing new hooks” If you don’t, since the Force Compile feature is a bit buggy, go to the Tools/Smarty/Compile folder and delete everything except the index.php. This should fix it, and you should be able to see the text.

Conclusion

We’re done! Thanks for reading. If you still have questions about how to create new hooks, feel free to contact me and I’ll be glad to help you.

Hi,
I bought your module development tutorial for ps1.6. You have done a great job. What about ps 1.7? I am waiting it.

NemoPS

Ok, I got what you mean. Hooks are not generate by modules, but ran from prestashop directly. Each of them just runs modules functions with the same name. Now, getting to your point, I think what you are looking for is something similar to a wordpress filter. What I’d do is again modify that controller and run your own method. Since you need to grab get and post variables, it’s the best way. If yo uhook the current payment module to paymentReturn, and your own module to orderconfirmation, you might even get away without mods, as they both run on the page, without conflicting

Rubens

So, I had a look to “getHookModuleExecList” in Hook.php file, and now is more than clear that those Payment hooks I was trying handle will never run unless I have a Payment Module. Specially because they are front-end Hooks.

I’d love to follow your suggestion – and I bet it should work out – doing some modifications directly to the OrderConfirmationController, but unfortunately modifying directly this module or even through any overriding, my module would become automatically ineligible for Prestashop as we can see here:

“It is not recommended to use an override in a module that you intend to distribute (for instance through the PrestaShop Addons marketplace), and they are forbidden in partner modules.”

I really appreciate every efforts you did answering my questions and trying to help me. It’s been very rare to get answers from any Prestashop communities we have.

I’m stuck dude

Rubens

Hi Nemo,

A Big thanks for your posts. They are so helpful

I’m trying to install a “hookPaymentReturn” on my module in order to get some specifics parameter values returned by any other payment module that could be executed.

I can see my module hook in “ps_hook_module” table at 2nd position, the activated payment module executes its own “hookDisplayPaymentReturn”, but the one I’ve installed is not being executed.

The hooks are not only executed once right? What I’m doing wrong?

Thanks

NemoPS

As far as I know it’s executed once. However, it’s ran when you reach the order confirmation page only, is this what you were looking for?

Rubens

Hi Nemo,

Thanks for your reply.

The hookDisplayPaymentReturn is being normmally executed by the payment module when the orderis confirmed. Anyway I created another hookDisplayPaymentReturn in my own module (its not a payment module) in order to handle the params and get some specific values that are useful to my module and store these values on my way.

In other words, I want to execute MY CUSTOM hookDisplayPaymentReturn right after ANY OTHER module has executed yours. That’s all.

And…. Sorry if it sounds clueless but if the hooks are only executed once, what’s the reason for their positions for each module?

NemoPS

Not exactly, no. It displays on the order confirmation page, as long as the user reaches it. And these are the only parameters sent over

When we upgrade prestashop, may it` will gone so again we have to add hook function in module class right.

what`s solution for this

http://nemops.com Nemo

HI,
I don’t know if I got the meaning of your question. If you meant “do I have to add new hooks again after the upgrade”? That depends on where you added them. If you used overrides, no, you probably won’t have to do it. Otherwise, yes.

rrdavik

First of all.

Well done! nice article..

I have some doubts about it.

I was wondering how the controller extension class is package in the module…
If I wanna make an independent module? Where I should place this controller?

Inside the module foler? inside override?

Also I don’t have clear where to override the tpl’s… I tried in the module directory, and in theme directory… and I couldnt make it work…

Thanks in advance!

http://nemops.com Nemo

Hi,
Controller extensions were introduced in 1.5, and in any case it’s a whole different story from hooks. It’s hard to explain the entire concept in a post, maybe i’ll make a tut about it sometime soon.
At any rate, the controller must be placed in the module’s folder, inside a “controller” folder and has tobe given a specific name (you can find info in the prestashop doc i believe).
For the tpls, you have to go to the template folder, them modules, create a folder with the module name inside it and place the tpl. Of course, if the module uses different views it’s another whole story