Как работать с Overrides?

Byteman

Мой дом здесь!
Регистрация
18 Мар 2008
Сообщения
484
Реакции
242
Может кто-то популярно объяснить как работать с overrides в престе и для чего они, вообще, нужны?
Или хотя бы укажет ссылку, где на русском языке популярно и не слишком длинно это объясняется?

Поиск даёт англоязычную документацию немалого объёма, на что пока в цейтноте времени не хватает.

Завожу отдельную ветку, так как думаю, что эта тема была бы многим интересна и здесь её легче найти будет и не нужно будет искать фрагменты ответов, разбросанных вперемешку с другими темами, в одной огромной ветке.
 
без хотя бы английского, а ещё круче французского - в кишках престы делать нечего :(

Самая свежая документация по системе 1.6 здесь English:
Для просмотра ссылки Войди или Зарегистрируйся

На русском языке для более ранних версий здесь:
Для просмотра ссылки Войди или Зарегистрируйся

Оверрайды тут:
Для просмотра ссылки Войди или Зарегистрируйся
для 1.5-1.6 практически также работает
 
Может кто-то популярно объяснить как работать с overrides в престе и для чего они, вообще, нужны?
Если в двух словах, то название говорит само за себя: override - переопределение, замена.
В папке сайта есть каталог OVERRIDE
Аналогичный каталог есть в папке темы и в некоторых модулях как самой престы, например FieldBlockSearch, так и модулях темы.

А дальше все происходит по принципу переменной PATH по поиску нужного файла, какой файл найден первым, тот и используется.

Значит надо просто понять последовательность поиска. Или точнее сказать ПРИОРИТЕТ этих папок. Насколько я понимаю, чем глубже папка, тем выше у нее должен быть приоритет.
То есть сначала обрабатываются каталоги модулей темы, затем темы и только потом престы.
Таким образом можно не меняя саму престу и тему изменять разнообразные вещи. Легко удалять модули с овером, востанавливая старую среду.

При установке модулей начинаются конфликты модулей, пытающихся переопределить один и тот же обьект. То есть обьект начинает действовать не так как было задумано в предудущем модуле.
В общем все те приколы, что и в CSS

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

Это если в двух словах.

Самые яркий пример использования овера - это быстрый поиск
Переопределяя класс SEARCH

Главное надо помнить что замену надо производить на идентичный обьект, то есть
не тулить квадрат в круглое отверстие.
По сути овер нужен для РАСШИРЕНИЯ либо свойств, либо возможностей обьекта.
 
Последнее редактирование:
Если в двух словах, то название говорит само за себя: override - переопределение, замена.
В папке сайта есть каталог OVERRIDE
Аналогичный каталог есть в папке темы и в некоторых модулях как самой престы, например FieldBlockSearch, так и модулях темы.

А дальше все происходит по принципу переменной PATH по поиску нужного файла, какой файл найден первым, тот и используется.

Значит надо просто понять последовательность поиска. Или точнее сказать ПРИОРИТЕТ этих папок. Насколько я понимаю, чем глубже папка, тем выше у нее должен быть приоритет.
То есть сначала обрабатываются каталоги модулей темы, затем темы и только потом престы.
Таким образом можно не меняя саму престу и тему изменять разнообразные вещи. Легко удалять модули с овером, востанавливая старую среду.

При установке модулей начинаются конфликты модулей, пытающихся переопределить один и тот же обьект. То есть обьект начинает действовать не так как было задумано в предудущем модуле.
В общем все те приколы, что и в CSS

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

Это если в двух словах.

Самые яркий пример использования овера - это быстрый поиск
Переопределяя класс SEARCH

Главное надо помнить что замену надо производить на идентичный обьект, то есть
не тулить квадрат в круглое отверстие.
По сути овер нужен для РАСШИРЕНИЯ либо свойств, либо возможностей обьекта.


Не совсем корректный ответ. Преста работает иначе. Если в override каталоге находится файл то он должен быть оформлен как потомок класса из каталога classes. Именно поэтому в каталоге classes файлы классов лежать с поистфиксом Core, а в каталоге override классы прописываются как Classname extends ClassnameCore.
 
Не совсем корректный ответ. Преста работает иначе. Если в override каталоге находится файл то он должен быть оформлен как потомок класса из каталога classes. Именно поэтому в каталоге classes файлы классов лежать с поистфиксом Core, а в каталоге override классы прописываются как Classname extends ClassnameCore.

Согласен. Это идет процедура наследования. Новый класс дополняет функционал старого.

Код:
class FrontController extends FrontControllerCore
{
  public function initContent()
  {
  parent::initContent();

  $this->context->smarty->assign(array( ...
  ....
Строчка вызова parent:initContent()
Когда вызывается функция обьекта, что происходит с одноименной функцией предка. Вызывается ли она или ее надо вызывать.
Помоему папка ovrride создается только для корректного удаления нового класса.
То есть большинство кооректировок нужно реализовывать через овер.
Заодно видно какие именно изменения внесены.
Но может я заблуждаюсь.
Вот цитата из доки:
Код:
Core files are not modified by overriding. 
This technique allows you to personalize your PrestaShop boutique 
and monitor how the software evolves. Updates are facilitated.
Google перевод:
Основные файлы не изменяются при переопределении. Этот метод позволяет вам персонализировать свой бутик PrestaShop и следить за развитием программного обеспечения. Обновления облегчаются.
 
Последнее редактирование:
Когда вызывается функция обьекта, что происходит с одноименной функцией предка. Вызывается ли она или ее надо вызывать.

Нет. При порождении объекта-потомка происходит лишь заимствование функций предка и их замещение одноименными функциями класса-потомка. Чтобы функции предка сработали их обязательно нужно вызывать явно. Это основы объекто-ориентированного программирования во всех языках, насколько я знаю.
Да, и исходные файлы, то есть файлы классов-предков не меняются. Это как раз основная идея такого подхода в программировании, когда можно организовать совместную работу над сложным функционалом не создавая конфликтов при правке кода. Например один программист задает структуру функционала классов-потомков через абстрактные классы, а другие программисты пишут реализацию методов абстрактных классов, каждый для своего класса-потомка абстрактного класса. Так обеспечивается контроль целостности функционала уже на стадии компиляции кода, а значит и взаимодействие участников проекта.
 
Очень интересное использование овера в модуле Combination Activate / Deactivate.
Вот changelog.txt
Код:
Prestashop Combination Activate/Deactivate Module

##########################################################################
Change Log : V1.0.0 | COMPATIBLE:: PRESTASHOP V1.6
##########################################################################

## Added Features:

- [+]FO :
   - Customer can purchase only active combination.
   - Seller can also activate/deactivate combination (If marketplace product combination module V2.2.0 is installed)
- [+]BO :
   - Admin can activate/deactivate catalog product combination.

## Note:

We override some prestashop core files in this module в 

Classes Product.php      
Function name getAttributesGroups()

Admin Controller AdminProductsController.php
Function name 
 postProcess()
 renderListAttributes()
 ajaxProcessDefaultProductAttribute()

Задача: в набор комбинаций товара добавляется флаг активности. Вывод только активных комбинаций.

Реализация: В базу добавляется таблица при помощи файла
install.sql
Код:
CREATE TABLE IF NOT EXISTS `PREFIX_wk_combination_status` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `id_ps_product` int(10) unsigned NOT NULL,
  `id_ps_product_attribute` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;

Далее в папке овер модуля добавляется файл Product.php в котором переопределяется функция выборки
Функция просто копируется из оригинала и в нее добавляется несколько строчек, реализующих работу
с новой таблицей.

Код:
class Product extends ProductCore
{
   public function getAttributesGroups($id_lang)
  {
  if (!Combination::isFeatureActive()) {
  return array();
  }
  $sql = 'SELECT ag.`id_attribute_group`, ag.`is_color_group`, agl.`name` AS group_name, agl.`public_name` AS public_group_name,
           a.`id_attribute`, al.`name` AS attribute_name, a.`color` AS attribute_color, product_attribute_shop.`id_product_attribute`,
           IFNULL(stock.quantity, 0) as quantity, product_attribute_shop.`price`, product_attribute_shop.`ecotax`, product_attribute_shop.`weight`,
           product_attribute_shop.`default_on`, pa.`reference`, product_attribute_shop.`unit_price_impact`,
           product_attribute_shop.`minimal_quantity`, product_attribute_shop.`available_date`, ag.`group_type`
         FROM `'._DB_PREFIX_.'product_attribute` pa
         '.Shop::addSqlAssociation('product_attribute', 'pa').'
         '.Product::sqlStock('pa', 'pa').'
         LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
         LEFT JOIN `'._DB_PREFIX_.'attribute` a ON (a.`id_attribute` = pac.`id_attribute`)
         LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON (ag.`id_attribute_group` = a.`id_attribute_group`)
         LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute`)
         LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group`)
         '.Shop::addSqlAssociation('attribute', 'a').'
         WHERE pa.`id_product` = '.(int)$this->id.'
           AND al.`id_lang` = '.(int)$id_lang.'
           AND agl.`id_lang` = '.(int)$id_lang.' ';

  if (Module::isEnabled('wkcombinationcustomize')) {
  $sql .= 'AND pa.`id_product_attribute` NOT IN (SELECT `id_ps_product_attribute` FROM `'._DB_PREFIX_.'wk_combination_status`) ';
  }

  $sql .= 'GROUP BY id_attribute_group, id_product_attribute
         ORDER BY ag.`position` ASC, a.`position` ASC, agl.`name` ASC';

  return Db::getInstance()->executeS($sql);
  }
}

Аналогично добавляется в админку работа с этой базой и изменяется уже функции в Admin Controller AdminProductsController.php

В самом wkcombinationcustomize.php определяются процедуры создания таблицы и удаления.

Код:
  public function deleteTables()
  {
  return Db::getInstance()->execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'wk_combination_status`');
  }

  public function uninstall()
  {
  if (!WkCombinationStatus::makeAllCombinationEnable()
  || !parent::uninstall()
  || !$this->deleteTables()
  ) {
  return false;   
  }

  return true;
  }

  public function disable($force_all = false)
  {
  if (!WkCombinationStatus::makeAllCombinationEnable()
  || !parent::disable()) {
  return false;   
  }

  return true;
  }

А также функционал ON/OFF поля статуса реализуется через новый хук actionObjectCombinationDeleteAfter
Код:
...
if (!parent::install()
  || !$this->registerHook('actionObjectCombinationDeleteAfter')
  ) {
  return false;
  }
 ...

  public function hookActionObjectCombinationDeleteAfter($params)
  {
  if ($params['object']->id) {
  $idProduct = $params['object']->id_product;

  if ($params['object']->default_on) { //if deleting default attribute
  $defaultAttributeId = Product::getDefaultAttribute($idProduct);
  if ($defaultAttributeId) {
  WkCombinationStatus::deleteORActiveSinglePsCombination($defaultAttributeId);
  }
  } else {
  //if admin delete normal combination then delete from module table also
  $idProductAttribute = $params['object']->id;
  WkCombinationStatus::deleteORActiveSinglePsCombination($idProductAttribute);
  }
  }
  }
 
Назад
Сверху