Child pages
  • Creating a PrestaShop module

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The mymodule.php file must start with the following test:

Code Block
if ( !defined( '_PS_VERSION_' ) )
  exit;

This checks for the existence of a PHP constant, and if it doesn't exist, it quits. The sole purpose of this is to prevent visitors to load this file directly.

...

Code Block
titlemymodule.php
borderStylesolid
<?php
if ( !defined( '_PS_VERSION_' ) )
  exit;

class MyModule extends Module
  {
  public function __construct()
    {
    $this->name = 'mymodule';
    $this->tab = 'Test';
    $this->version = 1.0;
    $this->author = 'Firstname Lastname';
    $this->need_instance = 0;

    parent::__construct();

    $this->displayName = $this->l( 'My module' );
    $this->description = $this->l( 'Description of my module.' );
    }

  public function install()
    {
    if ( parent::install() == false )
      return false;
    return true;
    }
  }
?>

...

Code Block
$this->displayName = $this->l( 'My module' );

Assigning a public name for the module, which will be displayed in the back-office's modules list.
The l() method is part of PrestaShop translation's tools, and is explained further below.

Code Block
$this->description = $this->l( 'Description of my module.' );

Assigning a public description for the module, which will be displayed in the back-office's modules list.

Code Block
public function install()
  {
  return ( parent::install() );
  }

In this first and extremely simplistic incarnation, this method is useless, since all it does is check the value returned by the Module class' install() method. Moreover, if we hadn't created that method, the superclass' method would have been called instead anyway, making the end result identical.
Nevertheless, we must mention this method, because it will be very useful once we have to perform checks and actions during the module's installation process: creating SQL tables, copying files, creation configuration variables, etc.

...

Code Block
public function uninstall()
  {
  if ( !parent::uninstall() )
    Db::getInstance()->Execute( 'DELETE FROM `' . _DB_PREFIX_ . 'mymodule`' );
  parent::uninstall();
  }

...

Code Block
titlemymodule.php (partial)
borderStylesolid
public function install()
  {
  if ( parent::install() == false OR !$this->registerHook( 'leftColumn' ) )
    return false;
  return true;
  }

...

public function hookLeftColumn( $params )
  {
  global $smarty;
  return $this->display( __FILE__, 'mymodule.tpl' );
  }

public function hookRightColumn( $params )
  {
  return $this->hookLeftColumn( $params );
  }

Let's explore these new or changed lines.

Code Block
if ( parent::install() == false OR !$this->registerHook( 'leftColumn' ) )
  return false;
return true;

...

Code Block
public function hookLeftColumn( $params )
  {
  global $smarty;
  return $this->display(__FILE__, 'mymodule.tpl');
  }

...

Code Block
public function hookRightColumn( $params )
  {
  return $this->hookLeftColumn( $params );
  }

Likewise, hookRightColumn() gives access to the theme's right column. In this example, we simply call the hookLeftColumn() method, in order to have the very same display, whatever the column.

...

Code Block
titlemymodule_page.php
borderStylesolid
<?php
global $smarty;
include( '../../config/config.inc.php' );
include( '../../header.php' );

$smarty->display( dirname(__FILE__) . '/mymodule_page.tpl' );

include( '../../footer.php' );
?>

We first load the current Smarty instance. This must be done before any call to the display() method.

...

Code Block
titlemymodule_page.php
borderStylesolid
<?php
global $smarty;

include( '../../config/config.inc.php' );
include( '../../header.php' );

$mymodule = new MyModule();
$message = $mymodule->l( 'Welcome to my shop!' );
$smarty->assign( 'messageSmarty', $message ); // creation of our variable
$smarty->display( dirname(__FILE__) . '/mymodule_page.tpl' );

include( '../../footer.php' );
?>

...

Code Block
titlemymodule.php (partial)
borderStylesolid
...
$this->displayName = $this->l( 'My module' );
$this->description = $this->l( 'Description of my module.' );
...

Strings in TPL files will need to be turned into dynamic content, which Smarty will replace by the translation for the chosen language. In our sample module, this file:

...

Code Block
titleTest.php
borderStylesolid
<?php
class Test extends ObjectModel 
  {
  /** @var string Name */
  public $test;

  protected $fieldsRequired = array( 'test' );
  protected $fieldsSize = array( 'test' => 64 );
  protected $fieldsValidate = array( 'test' => 'isGenericName' );
  protected $table = 'test';
  protected $identifier = 'id_test';

  public function getFields() 
    {
    parent::validateFields();
    $fields[ 'test' ] = pSQL( $this->test );
    return $fields;
    }
  }
?>

...

Code Block
titleAdminTest.php
borderStylesolid
<?php
include_once( PS_ADMIN_DIR . '/../classes/AdminTab.php' );

class AdminTest extends AdminTab
  {
  public function __construct()
    {
    $this->table = 'test';
    $this->className = 'Test';
    $this->lang = false;
    $this->edit = true;
    $this->delete = true;
    $this->fieldsDisplay = array(
      'id_test' => array(
        'title' => $this->l( 'ID' ),
        'align' => 'center',
        'width' => 25 ),
      'test' => array(
        'title' => $this->l( 'Name' ),
        'width' => 200 )
    );

    $this->identifier = 'id_test';

    parent::__construct();
    }

  public function displayForm()
    {
    global $currentIndex;

    $defaultLanguage = intval( Configuration::get( 'PS_LANG_DEFAULT' ) );
    $languages = Language::getLanguages();
    $obj = $this->loadObject( true );

    echo '
      <script type="text/javascript">
        id_language = Number('.$defaultLanguage.');
      </script>';

    echo '
      <form action="' . $currentIndex . '&submitAdd' .  $this->table . '=1&token=' . $this->token . '" method="post" class="width3">
        ' . ($obj->id ? '<input type="hidden" name="id_' . $this->table . '" value="' . $obj->id . '" />' : '').'
        <fieldset><legend><img src="../img/admin/profiles.png" />' . $this->l( 'Profiles' ) . '</legend>
          <label>'.$this->l( 'Name:' ).' </label>
          <div class="margin-form">';
    foreach ( $languages as $language )
      echo '
          <div id="name_' . $language['id_lang'|'id_lang'] . '" style="display: ' . ($language['id_lang'|'id_lang'] == $defaultLanguage ? 'block' : 'none') . '; float: left;">
            <input size="33" type="text" name="name_' . $language['id_lang'|'id_lang'] . '" value="' . htmlentities( $this->getFieldValue( $obj, 'name', intval( $language['id_lang'|'id_lang'] ) ), ENT_COMPAT, 'UTF-8' ) . '" /><sup>*</sup>
          </div>';
    $this->displayFlags( $languages, $defaultLanguage, 'name', 'name' );
    echo '
          <div class="clear"></div>
        </div>
        <div class="margin-form">
          <input type="submit" value="' . $this->l( ' Save ' ) . '" name="submitAdd' . $this->table . '" class="button" />
        </div>
        <div class="small"><sup>*</sup> ' . $this->l( 'Required field' ) . '</div>
      </fieldset>
    </form> ';
    }
  }
?>

...