Переопределение поведения по умолчанию

Опубликовано Опубликовано в рубрике prestashop, Русская документация PrestaShop 1.6, Учебник разработчика PrestaShop 1.6

Переопределение поведения по умолчанию

PrestaShop позволяет вам переопределять различные компоненты и поведение по умолчанию. Эта система состоит из двух основных моментов:

  1. Переопределение собственного поведения PrestaShop (файлы классов и файлов контроллера), чтобы настроить таргетинг на определенный раздел требуемых компонентов.
  2. Переопределение видимых частей модулей (Шаблоны, JavaScript, таблицы стилей …), чтобы темы могли лучше адаптироваться к ним.

 

Реализуйте переопределения только для своего магазина

Переопределения в PrestaShop являются эксклюзивными. Это означает, что если ваш модуль переопределяет одно из поведений PrestaShop, другой модуль не сможет правильно использовать это поведение или переопределить его предсказуемым образом.

Поэтому, переопределения должны использоваться только для ваших собственных локальных модулей, когда у вас есть конкретная потребность, и которую невозможно решить без этого.

Не рекомендуется использовать переопределение в модуле, который вы собираетесь распространять (например, через торговую площадку PrestaShop Addons)), и они запрещены в партнерских модулях.

Переопределение классов и контроллеров PrestaShop

Переопределение — это способ «переопределить» файлы классов и файлы контроллера. Превосходная функция автозагрузки PrestaShop делает «переключатель» для других файлов довольно простым. Благодаря полностью объектно-ориентированному коду PrestaShop вы можете полагаться на наследование объектов, чтобы модифицировать и добавлять новые поведения, используя свойства и методы различных существующих классов.

Классы и контроллеры обычно строятся по определенной норме. Вот класс товара и контроллер:

  • /classes/Product.php
    Этот класс будет называться ProductCore.
  • /controllers/front/ProductController.php
    Этот контроллер будет называться ProductControllerCore.

Вам нужно будет создать файл PHP и поместить его в одну из переопределенных папок, в зависимости от того, является ли этот файл частью модуля или поставляется «как есть». Начиная с PrestaShop 1.5, есть два места, в которых вы вы можете разместить свои переопределяющие файлы: либо в корне установки PrestaShop, либо внутри модуля.

Переопределение класса

Чтобы переопределить Product класс, ваш файл должен быть вызван Product.php и должен использовать Product класс, который затем расширяется ProductCore классом.

Файл может быть помещен в любое из этих мест:

  • /override/classes/Product.php
  • /modules/my_module/override/classes/Product.php

Переопределение контроллера

Чтобы переопределить ProductController класс, ваш файл должен быть вызван ProductController.php и должен использовать ProductController класс который затем расширяется ProductControllerCore классом.

Файл может быть помещен в любое из этих мест:

  • /override/controllers/front/ProductController.php
  • /modules/my_module/override/controllers/front/ProductController.php

Переопределение других видов поведения

В PrestaShop есть определенные файлы, которые можно использовать для переопределения таких элементов, как отображение перенаправления (Tools.php) и время выполнения контрольного хука (_Module.php), и т. д., вы можете включить их, удалив «_» префикс. Например, переименовать _Tools.php в Tools.php. Если уже существует Tools.php переопределение, вам придется объединить его с вашим.

Переопределение поведения модуля

Модули обычно имеют следующий формат:

  • /modules/my_module/my_module.tpl
  • /modules/my_module/my_module.css
  • /modules/my_module/my_module.js

Начиная с PrestaShop 1.5, они могут и должны также быть в следующем формате:

  • /modules/my_module/views/templates/front/my_module.tpl
  • /modules/my_module/views/templates/front/my_module.css
  • /modules/my_module/views/templates/front/my_module.js

PrestaShop позволяет вам переопределять или заменять некоторые файлы модулей фронт-офиса новыми в той же теме. Переопределение определяется темой: если она содержит /modules папку (или несколько!), PrestaShop будет просматривать его содержимое для файлов, имеющих то же имя и путь, что и существующие модули, и заменит их на новые.

Это означает, что для PrestaShop 1.4-совместимых модулей:

  • /themes/my_theme/modules/my_module/my_module.tpl
  • /themes/my_theme/css/modules/my_module/my_module.css
  • /themes/my_theme/js/modules/my_module/my_module.js

Для PrestaShop 1.5, путь немного длиннее

  • /themes/my_theme/modules/my_module/views/templates/front/my_module.tpl
  • /themes/my_theme/css/modules/my_module/views/templates/front/my_module.css
  • /themes/my_theme/js/modules/my_module/views/templates/front/my_module.js

В общем, правильный путь для переопределения .tpl.js или .css файл зависящий от расположения модуля. Вот почему, если PrestaShop должен работать с модулем без view папки, ему понадобится тот же путь переопределения.
Короче говоря, вы можете сохранить переопределяющий код в 1.6, так как как и в 1.4.

Новые файлы будут использоваться, когда клиент загрузит ваш магазин.

В отличие от кода переопределения, который должен быть помещен вручную в /override папку, переопределение модулей включается сразу после установки модуля.. Во время установки переопределяющий код объединяется с уже существующими (если есть), в противном случае он копируется в /override папку в корневой папке магазина.

Манипулирование переопределением кода вручную

Модули и темы могут добавить переопределение к поведению по умолчанию, и PrestaShop позаботится о переустановке /cache/class_index.php файла.

Но иногда вам нужно добавить этот главный код самостоятельно, вручную загрузив файл на свой сервер. В этом случае вам необходимо сделать регенерацию /cache/class_index.php файла самостоятельно. Это делается простым удалением файла: если PrestaShop не может найти файл, он будет регенерировать его, принимая во внимание все переопределения.

То же самое происходит при ручном удалении переопределения: для восстановления поведения по умолчанию вы должны удалить /cache/class_index.php файл.

Пример кода

Example 1

Использование MySQL.php класса данных невозможно при попытке ввода данных в другую базу данных из PrestaShop на том же сервере MySQL. (В самом деле!)

Решение состоит в использовании следующего переопределения MySQLCore класса:

<?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.'));
        return $this->_link;
    }
}
?>

Чтобы использовать его, вы должны создать экземпляр класса следующим образом:

  • For local connection: new MySQL(DB_SERVERDB_USERDB_PASSWD, 'DB_name', true);
  • For remote connection: new MySQL(DB_SERVERDB_USERDB_PASSWD, 'DB_name', true);

Последний параметр заставляет создать соединение MySQL.

Example 2

/*
 * Создание задачи cron для создания периодической резервной копии базы данных
*/
class AdminTab extends AdminTabCore{
    public function ajaxProcess()
    {           
        // Here we call the same thing as if we did 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;
    }
}
/*
 * Это переопределение позволяет вам использовать ajax-tab.php для любого действия администратора.
 * Используйте его для crontask например
*/
class AdminTab extends AdminTabCore {
    public function ajaxProcess()
    {
        return $this->postProcess();
    }
}

Example 3

/*
 * С помощью этого переопределения у вас будет новая переменная Smarty, называемая «currentController», доступная в header.tpl
 * Это позволит использовать другой заголовок, если вы находитесь на странице продукта, странице категории или на главной.
 */
class FrontController extends FrontControllerCore {
    public function initHeader()
    {
        self::$smarty->assign('currentController', get_class($this));
        return parent::initHeader();
    }
}