Блог Статьи

Решение проблемы вызова метода расчета скидок getTotal в версиях OpenCart 2.1 и 2.2+

Периодически, при релизе OpenCart происходит так, что некоторые ядровые механизмы меняются. И это могут быть вполне логичные и понятные корректировки, но, к сожалению, порождающие проблемы поддержки нескольких версий. Так и произошло при выходе версии 2.2.0.0, а именно изменился подход к передачe данных в стандартный метод getTotal в модели каталога при расчете скидок.

Если раньше данные передавались в виде трех разных параметров (в 2.0 и 2.1), то начиная с версии 2.2 (включая 2.3) передача осуществляется через один параметр, представляющий собой массив. И это весьма неплохой ход, так как в PHP отсутствует перегрузка методов, а количество данных может расти от версии к версии.

Наглядно это выглядит так:

// Версия 2.0 - 2.1
public function getTotal(&$total_data, &$total, &$taxes)

// Версия 2.2 +
public function getTotal($total_data)

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

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

// Этот класс реализует саму функциональность скидки
// И в ядре OpenCart он не будет вызываться напрямую
class ModelTotalMyModule_Engine extends Model {
  ....
  // Этот метод реализует весь расчет скидки
  protected function _getTotal(&$total_data = null, &$total = null, &$taxes = null) 
  ....
}

// А вот тут решаем проблему параметров
// При помощи обычного механизма наследования
if (version_compare('2.2', VERSION) <= 0) {
  class ModelTotalMyModule extends ModelTotalMyModule_Engine {
    public function getTotal($total_data)
    {
      $this->_getTotal($total_data['totals'], $total_data['total'], $total_data['taxes']);
    }
  }
} else {
  class ModelTotalMyModule extends ModelTotalMyModule_Engine {
    public function getTotal(&$total_data = null, &$total = null, &$taxes = null)
    {
      $this->_getTotal($total_data, $total, $taxes);
    }
  }
}

Суть его заключается в том, что создается класс наследник Model, который называете произвольным именем. В рамках примера — это ModelTotalMyModule_Engine. В нем реализуете всю необходимую логику в стиле 2.1.

А затем в зависимости от версии определяете требуемый класс модуля (в примере, ModelTotalMyModule), но наследуете его не от Model, а от дочернего ModelTotalMyModule_Engine. При этом созданный класс вашего модуля будет содержать в себе всего один метод, который и решает задачу парсинга параметров без лишних проблем.

Так что, если вам понадобится сделать так, чтобы код расчета скидки для OpenCart 2.1 запускался без проблем в 2.2 (или с корректировками в 2.3), то это сделать можно простым и легким методом.

Примечание: Нетрудно заметить, что так же легко сделать и обратную поддержку стиля из 2.2 в 2.1.