PrestaShop Blog

Get updates, news, and insider tips from the PrestaTeam. From help on how to open an online store to e-commerce news, the PrestaShop blog provides the best resources for all to enjoy.

PrestaShop Blog
 

< Back to the Blog home

Modules, Classes and Controller Override by Julien Breux

Introduction

PrestaShop allows you to override various components and behaviours. PrestaShop version 1.4 consists of two major points:

- The first is overriding the visible parts of modules (Templates, JavaScript and style sheet language) so the themes can adapt better to them.

- The second is overridding software behaviour (class files and controller files) to target a specific section of the required components.

Module override

The modules are usually in the following format:

   /modules/mon_module/mon_module.tpl

   /modules/mon_module/mon_module.css

   /modules/mon_module/mon_module.js

PrestaShop allows you to override or replace certain visible module files with new ones with the same theme. It couldn’t be simpler, just do the following:

   /themes/prestashop/modules/mon_module/mon_module.tpl

   /themes/prestashop/css/modules/mon_modules/mon_module.css

   /themes/prestashop/js/modules/mon_modules/mon_module.js

The new files will be used when you display your website.

Class override

Overriding is a way to “override” class files and controller files.

PrestaShop’s ingenious class auto-loading function makes the “switch” to other files fairly simple.

Use inheritance to modify and add new behaviour using the various classes’ properties and methods.

They are usually constructed the following way (product example):

/classes/Product.php

   This class would be called “ProductCore”

/controllers/ProductController.php

   This controller would be called “ProductControllerCore”

You will need to create a file in the “override/classes/” folder to “override” the resulting class model such as:

   /override/classes/Product.php

This class would be called “Product” and spans the “ProductCore” class.

Just a flick of PrestaShop’s magic wand and the spell is working!

You can also use this principle with the controllers and “override” in the following way:

   /override/controllers/ProductController.php

This controller would be called “ProductController” and spans the “ProductControllerCore” class.

PrestaShop has certain folders you can use to override elements such as displaying redirections (_Tools.php) and measuring hook execution time (_Module.php) etc.

Example 1 :

Using data class MySQL.php is simply impossible while trying to type data into a database different from PrestaShop on the same MySQL Server. (Really!)

The solution is to use the following override of the MySQLCore class:


<?php

class MySQL extends MySQLCore

{

	public function __construct($server, $user, $password, $database, $newlink = false)

	{

		$this->_server = $server;

		$this->_user = $user;

		$this->_password = $password;

		$this->_type = _DB_TYPE_;

		$this->_database = $database;

		$this->connect($newlink);

	}

	public function connect($newlink = false)

	{

		if (!defined('_PS_DEBUG_SQL_'))

			define('_PS_DEBUG_SQL_', false);

		if ($this->_link = mysql_connect($this->_server, $this->_user, $this->_password, $newlink))

		{

			if(!$this->set_db($this->_database))

				die(Tools::displayError('The database selection cannot be made.'));

		}

		else

			die(Tools::displayError('Link to database cannot be established.'));

		/* UTF-8 support */

		if (!mysql_query('SET NAMES 'utf8'', $this->_link))

			die(Tools::displayError('PrestaShop Fatal error: no utf-8 support. Please check your server configuration.'));

		// removed SET GLOBAL SQL_MODE : we can't do that (see PSCFI-1548)

		return $this->_link;

	}

}

?>

To use it you have to instanciate the class as follows:

  • For local connection : new MySQL(_DB_SERVER_, _DB_USER_, _DB_PASSWD_, ‘DB_name’, true);
  • For remote connection : new MySQL(_DB_SERVER_, _DB_USER_, _DB_PASSWD_, ‘DB_name’, true);

The last parameter forces the creation of a MySQL connection.

Example 2 :


/*

 * This override allows you to use ajax-tab.php to make any admin action.

 * Use it for crontask for example

*/

class AdminTab extends AdminTabCore{

    public function ajaxProcess()

    {

        return $this->postProcess();

    }

}

Example 3 :


/*

 * Create a cron task to make periodical database backup

 * (please test before use, I didn't tested it yet)

*/

class AdminTab extends AdminTabCore{

    public function ajaxProcess()

    {       

        // here we call the same thing as if we do the old way

        // + with "if" : maybe we want to limit its use to only adding backup :

        // note : find yourself a way to get the file link if you want to send it by mail !

        if (isset($_REQUEST['addbackup']))

            return $this->postProcess();

} 

public function displayAjax()

{

    if(sizeof($this->_errors)>0)

    {

        // handle errors 

        // for example, send mail with all error msg

        $content = '';

        foreach($this->_errors as $errorMsg)

            $content .= $errorMsg;'';

           $lang =  Configuration::get('PS_LANG_DEFAULT');

           // here we send a mail to give the result of the process

           // notice : you have to create template mails files

           Mail::Send($lang, 'backuptaskdone', '[autobackup] report backup error', array('backup_link'=>)), $to); 

    }

    else

    {

        // no error, but maybe we want a mail ?

        if(Configuration::get('PS_NOTICE_SUCCEED_BACKUP')) 

        {

           // fileAttachment available, see 9th param of Send() method in classes/Mail.php

               // + we can add a condition "if(Configuration::get('PS_AUTOBACKUP_SEND_FILE'))"

           Mail::Send($lang, 'backuptaskerror', '[autobackup] report backup error', array('vars to use in tpl'), $to); 

        }

    }

    return true;

}

}

Example 4 :


/*

 * with this override, you have a new smarty variable "currentController"

 * available in header.tpl

 * This allows you to use a different header if you are

 * on a product page, category page or home.

 */

class FrontController extends FrontControllerCore{

  public function displayHeader()

  {

    self::$smarty->assign('currentController',get_class($this));

    return parent::displayHeader();

  }

}

Conclusions

Core files are not modified by overrideing. This technique allows you to personalise your PrestaShop boutique and monitor how the software evolves. Updates are facilitated.

  1. Author: drgren

    Date: February 16, 2012 at 11:02 am

    Lovely tutorial, Sandrine.

    Thanks!

  2. Author: sixthmind

    Date: February 23, 2012 at 12:15 pm

    I liked your article, I just find it a bit difficult to understand how to override something in the file as I am not that advanced with php. You wrote: “Use inheritance to modify and add new behaviour using various classes’ properties and methods”.
    So once we create an override file, what are the steps when writing the code? Above examples show that it all starts with Class and then extends. Which class do you use? And then the next step? Your detailed explanation would be really appreciated.

  3. Author: renzo

    Date: February 29, 2012 at 1:40 pm

    how define the path to the images in a module inside the theme?

  4. Author: fbas

    Date: March 30, 2012 at 3:20 pm

    @sixthmind:

    for classes and controllers,

    the original class file will begin with something like this:
    class MySQLCore extends Db

    your override class file should inherit from the core file:
    class MySQL extends MySQLCore

    when overriding a class, I generally copy and paste the original file, modify this class definition, then make my modifications, but because of inheritance, you wouldn’t need to override (or redeclare) the original class’ public methods and variables.

    I think prestashop ships with a file at /override/classes/_MySQL.php which can serve as an example. (because of the underscore “_”, this file doesn’t override anything.. removing it will cause it to override /classes/MySQL.php). (It seems this _MySQL.php file was put there long ago, though is unused, and was never removed)

  5. Author: riverspart

    Date: April 17, 2012 at 1:23 am

    What about override php file in module? Or simply copy a new one and free to change it? They don’t have xxxCore name!

  6. Author: snajuro

    Date: April 17, 2012 at 7:18 pm

    I have a question related to controllers, what do I do in the case where I create a new controller. Where do I put the new controller?.

    Its actually part of a new module I am building for Facebook connect.

Leave a Reply

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

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>