Developing a simple module with CRUD for PrestaShop

In this article, we will develop a module to be used in the administrative panel of the shop. This module implements the four basic CRUD operations, taking advantage of a lot of features that is already present in the PrestaShop’s core. Our forms and grids will all be generated automatically by the PrestaShop, in such a way that they will have the same layout as the pages of the shop. Also, it should make the module compatible with newer versions of the PrestaShop.

The following topics will be detailed:

  1. Automatic creation of database tables;
  2. Automatic reparation of the database in the module reinstallation;
  3. Listing data in a grid using only PrestaShop core features;
  4. Creating forms to create/update data using only PrestaShop core features;
  5. Deleting data from the database using individual and bulk actions.
  6. Utilization of multilanguage fields.

The items 1 and 2 will use the CustomObjectModel class. I developed this class to add some features to the PrestaShop’s ObjectModel class. So, our Model (we will have only one) must be defined in the same way that the PrestaShop’s ones are defined. I will show how to to this definition in this article. Once the model is defined, the 3., 4. and 5. items will demand little effort; the hard work is already implemented in the core of PrestaShop.

The full source of the module is available in this GitHub repository. You just have to extract it to /modules/crud folder. I strongly recommend that you read this article using the module in your own PrestaShop instance.

Module Configuration

In the begin of crud.php, we have the line

The models property must contain the name of every model that your module uses. This is not a PrestaShop requirement, but it is necessary to automatically create and repair the database. After that, we define the tabs that will be created in the backend menu.

With this definition, a tab name complete CRUD will be created in the backend menu, and will have the CRUD Model and Custom Operation children. The tabs are created using the addTab() method in the following code.

In line 17, we set the tab name for each language used in the shop. In line 25, we use the same addTab() function to create the children tabs. To remove the tabs, we use the following method.

With this basic methods, we may declare the model’s constructor, and install it.

The code above is self-explained, so we may continue to the install() method.

Firstly, we create the table associated to our model, if they didn’t exist yet. If they exist, but had some missing column, we create these missing columns in order to repair the database of the module. This is useful to fix errors that may occur after the upgrade to newer versions of the module.

Now, the following code displays the uninstall() method.

I really avoid to remove any database information when my modules are uninstalled, to avoid the losing of sensitive information. You may, instead, create a clean database method in the configuration page of your module, with the appropriated warning messages.

Model Creation

The model’s code is not that hard. We only need to detail the database configurations associated to the model (table name, column names/types, and so on). The following code may be found in the classes/CrudModel.php file.

The primary parameter is a column that will be assumed by the PrestaShop that is unique for each row in the database. Usually it will be the primary key of the table. The TYPE_INT, TYPE_STRING , TYPE_BOOL and TYPE_DATE constants are declared in the ObjectModel classvalidate refers to the name of some method of the Validation class, and will be automatically used to validate your model data before saving it in the database. Lastly, the db_type parameter required by CustomObjectModel for the database creation.

Controller Creation

As in the model, we does not have much work to do in the controller. Basically, we have to set the fields that will be displayed in our grid and the inputs that will be displayed in our create/update form. With this setup, PrestaShop will generate the grid and the forms automatically.

The controller must be placed in controllers/admin/AdminCrudModels.php. All the setup we need to do is made inside the class constructor, so we begin with the controller’s basic definition.

In line 7, we tell the controller to include the bootstrap files in the html of the page. The other parameters refers to our model table, primary key and class name. Now, we have to set the fields to be displayed in the list page.

The reader is invited to read the documentation of the HelperList class for more details of the code above. With line 14, the user will be able to change the status of our model by just clicking in the “v” or “x” icons. Also, the grid also gains the “Enable selected” and “Disable selected” bulk actions.

For the “Delete selected” bulk action, we need to insert the following code.

And to finish our list, let’s include some individual action buttons, as the following image.

This is easily achieved with the following code.

When the user clicks in the Edit button, he will see the following form, which will be automatically filled by PrestaShop.

He may also insert new register in the database, clicking in the “Insert new” button in the toolbar of the list.

(sorry, my shop is in pt-br)

To generate this form, we only have to add the following code to the controller’s constructor.

Again the reader is invited to check the documentation of the HelperForm class to understand the code above.

And this is everything we have to do to create a simple CRUD in the backend with PrestaShop. If you does not want so much customizations, this is really an easy task. However, if you wanna customize several elements of the page, you have to deeply check and understand what is behind the scenes. To do so, check the AdminControllerHelperList and HelperForm classes. They have almost all the code that is used to generate the pages that use used in this tutorial.

Using Multilanguage Fields

Multilanguage fields are fields that may have a different value for each language enabled in your shop. This is achieved with a table named <your_model_table>_lang, that contain a field named id_lang, a field named <your_model_primary_key> and any multi lang field of the model. This column and its fields will be created automatically by the CustomObjectModel class.

To configure a field as multilanguage in your model, you only have to modify the $definition property.

So, when you (re)install your module, the multilanguage table will be created automatically.

After the database is correctly created, we have to configure our controller in such a way that PrestaShop will allow us to easily create multilanguage records. This is achieved through the the $fields_form property of your controller.

Then, the form automatically created by PrestaShop will be like the following image.

Multi language fields created by the HelperForm class.

In the list action of your controller, PrestaShop will automatically display the value in the language that is configured by your user. With these two simple modifications, aided by the CustomObjectModel class, you have a fully functional multilanguage CRUD!

10 thoughts on “Developing a simple module with CRUD for PrestaShop”

  1. Hey, thank you for writing this article its a help in need thing.

    I am new to prestashop. I followed the basic tutorial to create module in ps. I was searching for creating CRUD and found your article.

    I have followed the steps you have mentioned, but during module installation I got an error

    I’m using ps v1.6.

    Another question. Is this a complete example because I didn’t any template(s) in your example and listing/storing logic.

    1. Hi, sorry for taking too long to reply. This is a complete example. The listing/sorting logic is handled automatically by PrestaShop AdminController class.

      You just have to setup the fields that you want to display in the grid in the fields_list array, and PrestaShop will handle the sorting, filters and pagination for you, using the admin theme that is configured in the Shop.

      About the error that you mentioned… are you sure that you used 0 or 1 in the active property of your Tab instance? This is a boolean property, and boolean for PrestaShop means 0 or 1 (not true and false). Other values will throw the exception that you saw.

      Try to debug the Tab instance using var_dump($tabModel) or d($tabModel) and check if the active property is 0 or 1.

  2. Thank you Amauri,

    Yes it worked, when I just copied the code from GitHub and replace it with the one I created.

    I have found that link ‘GitHub repository.’ is not pointing to write place. In fact it will open link:

    When I compared file PrestaShopCustomObjectModel downloaded from the above mentioned link with the file placed under module code in GitHub. Found two minor changes please update them in file at:

    – At line # 85 remove # p($column);
    – Add method dropDatabase()

    Thank you for your help and it worked fine now. It is a good example to develop full understanding of how a administrator module create and work.

    1. I am glad to know that it worked fine to you!

      Thank you for your feedback, I will fix the github link and the CustomObjectModel file.

  3. Hi,
    I had installed your module and it is working fine I want to create one more table upon installation, I had added in the model but when I had given $definition it is showing “cannot redeclare fatal error”. can you please help me regarding this?

    1. Hi, sorry for the delay.

      You can do server-side validations through the PrestaShop Validate class. In my CrudModel, the property active has a definition 'validate' => 'isBool'. So, when you try to use the add() and edit() methods of the ObjectModel class, PrestaShop will check if the the value of the active property is a boolean. can use any method of the Validate class for this.

      For client-side validation, you have to do your magic with JavaScript. As far as I know, PrestaShop will not help you in this.

  4. Hi,

    I learned using extending classes of ObjectModel for my modules the hard way (by reading code). Your post could have helping me a lot if I thought about Googling it!

    I just have two “thoughts” after reading your post.

    1. I personally prefered to create an abstraction of a DbTable class in charge of creating database tables. I think it is better separation of concerns and it allows to externalize this class as a shared class between modules. I made it as Composer package in order to get autoloading as a bonus.

    2. When using a multishop model, it’s necessary to declare shop table associations in your model constructor. It is called before each CRUD operation but associations are looked up from a static list of models set in Shop::init.

Leave a Reply

Your email address will not be published. Required fields are marked *