Prestashop back office hooks

Although we will go through the basics of setting up a module, this tutorial assumes you already know how to create one from scratch. If you are totally new to Prestashop, I strongly recommend that you read the Official documentation on how to create a Prestashop Module before approaching this tutorial.

Now, in order to add new fields to Prestashop’s products’ back office, it is essential to be aware of the hooks that can be used to perform various operations in the admin panel. Specifically, we will be using the following ones:

DisplayAdminProductsExtra: this hook adds new tabs to the product’s back office interface, thus, we will use this hook to plug in our new content’s input field with translations

ActionAdminControllerSetMedia: if we ever need to style our new tab, or add custom javascript functions, this is the ideal hook to use to plug css and js files. This is called for every Prestashop Admin page, thus we will need to prevent it from running in pages that are not the product’s configuration.

ActionProductUpdate: the new field needs to be saved in the database. Specifically, we will add a new column (custom_field) to the product_lang table and add a new translatable field, without using overrides at all. By plugging code snippets into this hook, we can easily update the column when the product itself is updated.

At this point, we can line out our plan of action: after giving the module a basic setup, we will first create the template file that will display the new field’s input box on its own table. Then, we will see how to overcome a little issue with translatable fields, using the ActionAdminControllerSetMedia hook, and lastly, on data submission, we will update the new custom field once the product is updated. We will create a new field for demonstrational purposes only, but feel free to dare beyond the limits of this tutorial if you want!

Setting up the module

First of all, let’s start with a simple module template. You can download the blank module folder from the link at the beginning of the article. Drop the newfieldstut folder (the one from the “Start here” archive!) in the modules/ folder of your Prestashop Root. Then open up newfieldstut.php and start by adding some regular module’s code.

Now that the basic structure is laid out, we want to specify the install and uninstall functions. Let’s add a new column to product_lang with an ALTER TABLE, and provide a way to remove it if this module is uninstalled:

Explanation: A couple of things here! First, in the install method, we

1- As with every module, call the parent’s install method

2- Alter the product_lang table, to add the new field

3- Register all the hooks we will use

Notice how I decided to structure the alterTable method. To avoid creating two functions, I stacked together the drop and add statements, passing a $method variable to determine what the function should do. Therefore, we call alterTable with ‘add’ when installing, and ‘remove’ when uninstalling.

Now, just to be sure we did everything correctly without errors, let’s try installing the module! Reach the Modules page in the back office and look for New Fields Tutorial in the modules list, as shown below.

Click install, and see if it works. If it does, move on to the next step!

Creating a new tab in the Product Back Office (DisplayAdminProductsExtra)

Okay, our module is installed, and the hooks have been registered as well. Time to test it out! Add the following function to your module:

Explanation: first, we make sure the current product object is correctly loaded; if so we display the content of the module’s tpl file. Reach a product’s back office page; you should see something like this, by clicking on the new tab:

At this point, we can start filling in the tpl file. Open up newfieldstut.tpl, get rid of the placeholder text and add the following instead:

Do not test this out yet! It will not work. Why? Let’s have a look at what we just did: first, we setup a simple table structure imitating the one Prestashop uses by default in the Product configuration page. Then, inside the rightmost table cell (td), we include a template file Prestashop kindly provides. This file is input_text_lang.tpl, and it is located in the admin theme folder, inside the controller section for products. What it does, is it provides a standardized way to add new translatable fields without having to mess with foreach loops in our own code. We can assign the currently available languages, name of the new input field and its value.

However, if we were to refresh the page now, and turn on error reporting, this is what we would see:

This happens because we have not assigned any of those 2 variables we mention in the code: $languages and $custom_field. Let’s take care of this.

For the time being, we will not bother adding a real value to the new field. As for the other 2 variables, we get the currently available languages by the controller itself, and the default language for our store.

The new tab is ready! ….BUT! Hey, watch closely at what happens if you wait a couple of seconds before accessing it, or click its label right after the page reloads!

The language flags pops out after a while, or does not appear at all!

This is (I believe) yet another Prestashop bug. If we want our new translatable field to work correctly every time, we absolutely need to take this bug off. How to?

Properly enabling multilanguage fields in the product Back Office

What on earth is going on here? Basically, Prestashop loads the language translations flags using javascript. Not only this, but it also loads each tab asynchronously with Ajax, and ‘forgets’ to call the function which assigns those flags for custom tabs. This is where the ActionAdminControllerSetMedia hook becomes useful! We will plug in a new javascript file to take it into account, so that flags are assigned to our new tab as well.

First off, open up newfieldstut.js, which you can find in the project’s module folder you already know. Here is how it will look:

$(document).ready(function() {
});

Nothing but a simple jQuery ready statement. Inside, add the following

And that’s it, really. A few notes though: Notice the ID we are checking the load status for. This will vary depending on the name you give your module, and you can check it by inspecting the tab element with the browser’s developer tools:

Explanation: As we saw at the beginning of the article, this hook runs for every page of the back office. Thus, we need to be sure we are embedding our javascript for the single product configuration page only. Therefore, we first check the the current controller is AdminProducts, then, to be sure we are not viewing the products list, we also make sure a product id is set in the current url. After performing these checks, we simply use a regular addJS to embed the code.

Save & refresh, at this point the language flags are always added to the new tab!

Saving and retrieving the new value

Everything is in place, but we are not doing anything now. We are not displaying the new field value, nor are we able to save its content!

First off, let’s save the value for each language inside the database. Append the following method to our beloved newfieldstut.php:

Explanation: the hook we are targeting here(ActionProductUpdate) runs at the very same time a product’s data is stored inside the database. The perfect time to add our new content! First, we retrieve the current product ID, and then get all the currently active languages. For each of the languages, we update the database field for the matching language and product id. If the update operation cannot be completed, we spawn an error using the default Prestashop error handler for Admin tabs.

A small note on Tools::getValue(‘custom_field_’.$lang[‘id_lang’]): if you remember, we called our new field ‘custom_field’ when embedding the translatable input box. This means Prestashop generates one field, appending each language id, for each language. Thus, we end up having custom_field_1, custom_field_2 etc… Where the number after the second underscore represents the language ID. That’s why we are targeting it like this ‘custom_field_’.$lang[‘id_lang’], to be sure each language is correctly added.

Now, let’s try inputting different values for each languages, and hit ‘Save and stay’. Then, since we are not yet retrieving the field, let’s check it out in the database.

Okay, it’s done! At this point, we only need to retrieve those values! Let’s add a new method to our friend newfieldstut.php:

Explanation: Quite simply, using the product id as source data, we retrieve all entries for the custom_field column. Then, we format it for an array whose keys are language ids, and values the custom field value for that specific language. This is how Prestashop will be able to use them in the template: array(‘5′ => ‘value for id_lang 5), …’).

Of course, as a last step we call this function when assigning variables in prepareNewTab:

Conclusion

As you could see, adding new fields to products using modules, without any remote sign of overrides, is not as complex as it might seem. Moreover, it’s a much more maintainable practice than messing with the original back office templates and controllers! Of course, at this point, you can take this tutorial further and add front office hooks to display your new, translatable field!

I tried this module, its really helpful for my project and also its working fine.

Boris

Hi Nemo,

I’m on PS 1.6 and I use your module with success but I only see one small bug…

I found how to use Tinymce on the textearea.

Add class=”rte” and some javascript :

$(function() {
tinySetup();
});

But when I click on the new field, it show each input for each language… not just the default… and when I click on “save and stay”, page is refreshed and shown with the good one input with the good language…

Have you an idea ?

Anyway, great module, thank you !

NemoPS

Hmmm it might be missing id_language as js variable. You might need to add this hideOtherLanguage(id_language)

andrew

Hi Nemo,
Is it possible that the custom_field content to appear into pdf invoice that i generate in BO? Thanx!

NemoPS

It is, but definitely complex. Depending on where you need it, you will have to edit the OrderInvoice method that gets products, as well as the HTMLTemplateInvoice.php and pdf/invoice,tpl

andrew

ahh.. Look .. i need to generate a warranty file (add new page to the pdf invoice).
And the new page should contain 1. Name of the product and 2. An unique serial number defined by manufacturer (which i have to insert manually). Do you have any idea how can i do this?

NemoPS

Complex. You need a new method in the AdminPDFController class that triggers a new html template (say, call it HTMLTemplateWarranty) that loads a new template located in the main pdf/ folder
In the HTMLTemplateWarranty file, you can load all the files you need, but it’s still going to be bound to an order

Mickael

Hi, did you find a solution ? I have the same problem..

Nguyễn Hưởng

How can to add the save button?

NemoPS

Strange, check if you have any javascript error on the page

Mickael

in the tpl,

replace the right file and on 1.6 add class “autoload_rte” allow to view the textarea with the tinyMCE…

Hi . . Now i know thats a rookie’s question but i am new to prestashop and php.
I have registered a hook in the desired place in product.tpl. Can some1 guide me how to display the contents of the field in that hook?

tree

Hello Nemo,

I follow this steps in PS v.1.6.

After added the function hookActionProductUpdate,I cannot see the button “save and stay” in my back office.

So I couldn’t add a field in the product_lang.

Should I add any code in the version 1.6?

NemoPS

Does it get back if you remove the hook? It’s odd, that is no visual hook, it should not affect your visuals

tree

Thank you for your reply.

Do you mean unhook and re-hook the module? It didn’t work.

Marianne

I have nearly the same problem, there is no button to save the field (no flags either, but less important at this point) PS 1.6.1.1 would be great if we get it to work!

NemoPS

Hi there!
What do you exactly mean by didn’t work? Spawning any error? The validation type of the array should really work

jeanjeanjeana

Hello !!

Thanks for your quick answer !!

I put my verification in public “function hookActionProductUpdate($params)” just after the foreach so that if the validation isn’t ok, the database didn’t update ! and i put this for the verification :

Firt I don’t know if my verification realy has to go in this class and then when i submit, the database never update even if my entre is an INT… and my display Error spawn no error.. I think I have the wrong syntaxe !

(I’m sorry for the spelling mistakes im not native English)

Thank you in advance ! =)

jeanjeanjeana

Solved my problem alone =)

Thank you anyway =)

jeanjeanjeana

Hello,

I would like to add a form verification for the “custom_field”, for exemple just int or just text, I tried with validate.php who is in prestashop but i didn’t work… If someone has an idea or a link it will be very nice ! =)

Thanks !

slonn

How generate the form with HelperForm?

Vijay

Can we resolve the compability issue with PS 1.6 & this module? Right now tab was not loaded in PS 1.6.

Wotek

how can i active TinyMce in the textarea ?

http://blog.eaposztrof.com eaposztrof

adding the class=”autoload_rte” can solve this.

armez

And how to add class=”autoload_rte” to this textarea?

NemoPS

You just have to add it in the html

Wotek

Hi

I have problem with add two extra fields.
On admin page views the same value in both fields.
How can i change ?

hey nimo…nimo can you please guide me how to add this module too product.tpl file? i tryed {$custom_field} inside my product tpl and it shows nothing so whats the point if you add some field to your admin area but cant show them to user?please let me know how to…thx

http://ps13.org maio

hi nemo,

I don’ get any errors even if I don’t create the ‘ public function prepareNewTab() ‘ method,

I can make too many guesses on why this is happening….

I’m using last PS V.1.6.9…
what do you think about it?

NemoPS

well it can be anything really, did you enable error display?

http://ps13.org maio

sure

I still haven’t had a lot of time ot try but it probably depends on tpl structure or the backoffice of 1.6,

as soon as I try I’ll give you feedback,

Com

I need help!
Hi, how I can display the new field in product-list.tpl

Nishant Vadgama

how can I validate data on hookActionProductUpdate() and return error if exist..? with your code I have written ” $this->context->controller->_errors[]” but this is not display error,