Book Image

PrestaShop Module Development

By : Serny
Book Image

PrestaShop Module Development

By: Serny

Overview of this book

If you are a developer who is new to PrestaShop and wants to get a good foundation in development on the PrestaShop framework, this book is for you. It's assumed that you will have some experience with PHP5, jQuery, and HTML/CSS (no need to be an expert on it).
Table of Contents (13 chapters)
12
Index

Making a simple configuration form

We will now make a small configuration form with two options: one to enable grades and the other one to enable comments on a product.

Let's fill in the getContent.tpl file we created previously with a small form.

Since PrestaShop 1.6, the back office now uses the CSS Framework Bootstrap. You can either write basic HTML (and make the display compliant with an older version of PrestaShop), or write Bootstrap templates.

If you choose to use Bootstrap (as I'll do later), you have to set the Bootstrap flag in your module constructor first.

In the __construct method of your module's mymodcomments.php main class, add the following line before parent::__construct:

$this->bootstrap = true;

If you do not set this flag to true (and if you are using PrestaShop 1.6), PrestaShop will include a retrocompatibility CSS file to make the template that you used in PrestaShop 1.5 compliant with the PrestaShop 1.6 display. Here is the Bootstrap HTML code that we will use to display the configuration:

<fieldset>
  <h2>My Module configuration</h2>
  <div class="panel">
    <div class="panel-heading">
      <legend><img src="../img/admin/cog.gif" alt="" width="16" />Configuration</legend>
    </div>
    <form action="" method="post">
      <div class="form-group clearfix">
        <label class="col-lg-3">Enable grades:</label>
        <div class="col-lg-9">
          <img src="../img/admin/enabled.gif" alt="" />
          <input type="radio" id="enable_grades_1" name="enable_grades" value="1" />
          <label class="t" for="enable_grades_1">Yes</label>
          <img src="../img/admin/disabled.gif" alt="" />
          <input type="radio" id="enable_grades_0" name="enable_grades" value="0" />
          <label class="t" for="enable_grades_0">No</label>
        </div>
      </div>

      <div class="form-group clearfix">
        <label class="col-lg-3">Enable comments:</label>
        <div class="col-lg-9">
          <img src="../img/admin/enabled.gif" alt="" />
          <input type="radio" id="enable_comments_1" name="enable_comments" value="1" />
          <label class="t" for="enable_comments_1">Yes</label>
          <img src="../img/admin/disabled.gif" alt="" />
          <input type="radio" id="enable_comments_0" name="enable_comments" value="0" />
          <label class="t" for="enable_comments_0">No</label>
        </div>
      </div>
      <div class="panel-footer">
        <input class="btn btn-default pull-right" type="submit" name="mymod_pc_form" value="Save" />
      </div>
    </form>
  </div>
</fieldset>

The HTML tags used here are the tags generally used in the native module, but you have no real limitations except your imagination.

Note

I will not go further in my explanation of this code since HTML basics are beyond the scope of this book.

If you refresh your browser, you will see the form appear, but for the moment, submitting the form will do nothing. So, we need to take care of saving the configuration options chosen by the merchant when he submits the form.

In order to not overload the getContent method, let's create a new method dedicated to handling the submission of the module configuration form. The name processConfiguration seems a good name to me for such a function. Since getContent is the only method called by PrestaShop when we enter in a module's configuration, we still have to call the newly created processConfiguration method in the getContent method:

public function processConfiguration()
{
}
public function getContent()
{
  $this->processConfiguration();
  return $this->display(__FILE__, 'getContent.tpl');
}

In the processConfiguration method, we will check whether the form has been sent with the Tools::isSubmit method:

if (Tools::isSubmit('mymod_pc_form'))
{
}

As you might have noticed, we set the mymod_pc_form name attribute on the Submit button. PrestaShop's Tools::isSubmit method checks whether a key matches the attribute name in the POST and GET values. If it exists, we will know that the form has been sent for sure.

We will now save the data of the form sent. We will use the following two methods for this action:

  • Tools::getValue: This function will retrieve the POST value of the key passed in the parameter. If the POST value does not exist, it will automatically check for the GET value. We can set a second parameter (optional), which will correspond to the default value if neither POST nor GET value is found.
  • Configuration::updateValue: This function is used to save simple value in the configuration table of PrestaShop. You just have to set the key as the first parameter and the value as the second. The updateValue function makes a new entry in the configuration table if the provided configuration is not found, and will update the configuration value if it is already in the configuration table. This method can have other parameters, but we will cover them later since we do not need them for the moment.

So in practice, we will have this:

if (Tools::isSubmit('mymod_pc_form'))
{
$enable_grades = Tools::getValue('enable_grades');
$enable_comments = Tools::getValue('enable_comments');
Configuration::updateValue('MYMOD_GRADES', $enable_grades);
Configuration::updateValue('MYMOD_COMMENTS', $enable_comments);
}

Note

It is a PrestaShop best practice to set the key in uppercase. Since any module can add configuration value, it's also a best practice to add a prefix to avoid conflict between modules. That's why I added MYMOD_.

Now, I invite you to refresh the configuration page in your browser, change the value of one or both options, and then submit the form.

Apparently, nothing has changed. However, if you go into your phpMyAdmin (or any administration tool), and see the content of PrestaShop's configuration table (if you kept the default database prefix, its name should be ps_configuration), you will see that the last two entries of the table are your values. You can play with the form and submit it again; the value will be updated.

We still have to display a confirmation message to let the merchant know that their configuration has been saved. For this, we just have to assign a confirmation variable to Smarty in the isSubmit condition just after the Configuration::updateValue calls.

The Smarty object is available in the $this->context->smarty variable in your module class. We will use the assign method of Smarty:

$this->context->smarty->assign('confirmation', 'ok');

This function takes two parameters: the name of the variable in which the value will be stored, and the value.

Note

If you want more information about this, you can check the official Smarty documentation at http://www.smarty.net/docsv2/en/api.assign.tpl.

In the Smarty template, you will now have a variable named $confirmation, which contains the value ok.

Note

We will see later exactly what the Context object contains. It is not important at this point.

If the $confirmation variable has been assigned to Smarty, then we display a confirmation message in getContent.tpl:

{if isset($confirmation)}
  <div class="alert alert-success">Settings updated</div>
{/if}

You can add these lines wherever you want in the template. However, you should add it just before the fieldset since this is a PrestaShop standard.

Now, you can submit the form again. If you did it right, the confirmation message should appear, as shown in the following screenshot:

Making a simple configuration form

We've almost finished the first version of the configuration form. However, you might have noticed that if you close the configuration form and reopen it, the options you set to Yes won't be preselected correctly. This will give the impression to the merchant that their configuration has not been saved properly.

To fix this problem, we just have to retrieve the configuration values and assign them to Smarty. We will use another function from the Configuration class: Configuration::get.

This function takes the key of the configuration wanted as a parameter, and returns the associated value:

$enable_grades = Configuration::get('MYMOD_GRADES');
$enable_comments = Configuration::get('MYMOD_COMMENTS');

Then, to assign these variables to Smarty, we will use the same method we saw previously to set the confirmation message flag:

$this->context->smarty->assign('enable_grades', $enable_grades);
$this->context->smarty->assign('enable_comments', $enable_comments);

To keep a short getContent method, my advice is to create a new method that we will call assignConfiguration, and write the code in it. So, at the end, we will have something like this:

public function assignConfiguration()
{
  $enable_grades = Configuration::get('MYMOD_GRADES');
  $enable_comments = Configuration::get('MYMOD_COMMENTS');
  $this->context->smarty->assign('enable_grades', $enable_grades);
  $this->context->smarty->assign('enable_comments', $enable_comments);
}

public function getContent()
{
  $this->processConfiguration();
  $this->assignConfiguration();
  return $this->display(__FILE__, 'getContent.tpl');
}

We just have to add some Smarty code in getContent.tpl to make it work. I will take the Enable grades option as an example, but it will be the same for Enable comments. If the Yes option is enabled, we will precheck the radio button whose value is 1. If the option value is not set or is set to 0, we will precheck the other radio button. The following is the Smarty code:

<img src="../img/admin/enabled.gif" alt="" />
<input type="radio" id="enable_grades_1" name="enable_grades" value="1" {if $enable_grades eq '1'}checked{/if} />
<label class="t" for="enable_grades_1">Yes</label>
<img src="../img/admin/disabled.gif" alt="" />
<input type="radio" id="enable_grades_0" name="enable_grades" value="0" {if empty($enable_grades) || $enable_grades eq '0'}checked{/if} />
<label class="t" for="enable_grades_0">No</label>

If we close the configuration form and reopen it, you will now see that the configuration values are prechecked correctly.

Congratulations, you finished the first step of your module!

If you don't know Smarty well yet, take time to read the official documentation to learn about functions of the Smarty object and template syntax. This will save you time for future developments.