S.Tominoff

Frontend / Backend developer

Разработка в Opencart: обзор основных отличий между второй и третьей версиями движка для разработчиков

Обновление мажорной версии Opencart принесло разработчикам много новшеств, в этой статье рассмотрим с чем вам придётся столкнуться при разработке модулей для Opencart 3.

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

 

Сегодня мы кратко пробежимся по основным отличиям между Opencart 2 и 3, с которыми вам придётся столкнуться при разработке своих решений для этого движка.

 

Отличие №1 

Шаблонизатор TWIG

Ранее, Opencart не использовал никаких шаблонизаторов и мы писали в файлах .tpl обычный PHP код. Третья версия CMS принесла нам долгожданную поддержку шаблонов.

 

Хотя многие, возможно, и не согласятся, но я считаю внедрение шаблонизатора шагом вперёд для этого движка.

 

Шаблонизатор TWIG предоставляет необходимый минимум доступных функций для форматирования и управления отображением содержимого, теги для организации циклов и условий.

 

Нет таких задач для слоя представления, с которыми бы не справился TWIG.

 

Не стоит волноваться!

Вы сможете легко перевести большинство своих .tpl файлов в .twig если они семантически корректны и не используют какую либо бизнес-логику.

 

А зачем этот твиг? PHP ведь раньше отлично справлялся в шаблонах! 😏

 

PHP тоже своего рода шаблонизатор

 

PHP тоже сам себе шаблонизатор, но поскольку это ещё и язык программирования — он подпитывает условия для написания новичками "плохих" шаблонов, путём добавления в них нежелательной логики и проломом семантики паттерна MVC (например, кто–то может добавить запросы к БД, внешним ресурсам, выполнять какие–то функции внутри шаблонов или добавлять другие операции не связанные напрямую с отображением)

 

 

Набитые бизнес логикой шаблоны обязательно вызовут в будущем кучу проблем. Чтобы не стрелять себе в ногу — максимально следуйте MVC паттерну, оставляйте всю или хотя бы большую часть бизнес логики в моделях!

 

Никогда не добавляйте бизнес–логику в представления!

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

Никогда не пишите там бизнес–логику — это не только ломает семантику MVC (что ведёт к усложнению поддержки), но и серьёзно ухудшает переносимость, а в некоторых случаях и производительность!

 

 

Совсем кратко об отличиях .tpl и .twig шаблонов в Opencart

Вот наглядная картинка для понимания разницы базового синтаксиса — на картинке слева шаблон .tpl с PHP кодом, справа — twig шаблон:

 

 

Как видите, шаблон Twig выглядит короче и аккуратнее своего PHP собрата.

Обзору основных возможностей шаблонизатора Twig я отведу отдельную статью, тут же мы просто примем как данность — шаблонизация Opencart 3 теперь основана на Twig, а не PHP файлах.

 

 

Отличие №2

Расположение загруженных файлов

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

 

Это нужно учитывать, если вы собираетесь разрабатывать модуль для Opencart 3, который должен будет предоставлять пользователю ссылку на скачивание/просмотр файла, поскольку в большинстве случаев расположение storage будет недоступно извне.

 

Если речь идёт об изображениях, то тут поможет старый добрый image->resize. Этот метод делает копию оригинального изображения с изменёнными размерами и помещает её в image/cache, доступную извне.

 

Отличие №3

Автоматическая подгрузка переменных из language

До Opencart 3, при подгрузке файлов перевода мы должны были самостоятельно назначать значения из языковых файлов в переменные шаблонов:

 

<?php
/*
  урезанный пример из Opencart 2.3 
  catalog/controller/common/cart.php
*/

$this->load->language('common/cart');

// назначаем переменные для шаблона
$data['text_empty'] = $this->language->get('text_empty');
$data['text_cart'] = $this->language->get('text_cart');
$data['text_checkout'] = $this->language->get('text_checkout');
$data['text_recurring'] = $this->language->get('text_recurring');
$data['text_items'] = sprintf($this->language->get('text_items'), 

 

В модулях для Opencart 2 можно часто видеть подобные простыни кода, поскольку нет другого способа (без ломания семантики шаблонов) передать переведённые надписи в шаблон.

 

Начиная с Opencart 3.0 при загрузке языковых переменных они сразу же становятся доступны в параметрах шаблона. Однако, будьте аккуратны — каждый language->load перезаписывает одинаковые ключи, загруженные ранее.

Обратите внимание

За маппинг переменных отвечает встроенный обработчик события (event/language). Перед тем как начнёт выполняться код вашего действия (action), Opencart сохраняет все загруженные до начала выполнения контроллера переводы в переменную backup.

Таким образом, если вы хотите получить список языковых переменных назначенных до выполнения вашего экшна, можно воспользоваться такой конструкцией:

<?php
class ControllerExtensionModuleTest extends Controller {
  public function index () {
    // например, подгрузили свои переводы
    $this->language->load('extension/module/test');

    // получаем хэш-таблицу всех переводов загруженных ранее
    $preloaded_language_data = $this->language->get('backup');
    $data['heading_title'] = $preloaded_language_data['heading_title'];

    // ...
  }
}

 

Отличие №4

Изменено название GET переменной токена авторизации

Система авторизации в административной части Opencart устроена довольно интересно и местами не очень удобно, на мой взгляд.

Помимо использования традиционных PHP сессий, движок также использует GET переменную для дополнительного контроля доступа. Эта переменная называлась token что в первой, что во второй версиях Opencart, однако в третьей версии разработчики изменили имя этой переменной на user_token.

 

 

Отличие №5

Изменения в работе seo url

Вообще, SEO это известная проблема в Opencart. Изначально встроенная поддержка синонимизации URL в зачаточном виде появилась в Opencart 2. К третьей версии её немного доработали.

 

В первую очередь стоит отметить изменения связанные с хранением встроенных seo url.

 

Ранее для хранения красивых урлов использовалась таблица url_alias, в которой просто хранились key-value данные, в виде query (запрос) и keyword (сео представление). Для каждого query существовал только один синоним.

 

В Opencart 3 эта схема изменилась

Таблица теперь называется seo_url, а к знакомым уже query и keyword добавились также данные о магазине и языке — store_id и language_id. Это позволяет создавать разные url синонимы для разных магазинов и версий языка пользователя.

 

Отличие №6

Отличаются некоторые пути и названия

В третьей версии есть небольшие отличия в расположении некоторых контроллеров. Так, контроллеры установщика, списка модулей, события и OCMod установщик переехали из раздела extension в marketplace. Теперь в extension хранятся только сами модули.

Вкупе с изменением названия переменной токена, теперь для перенаправления пользователя обратно к списку модулей нужно писать так:

 

<?php
// было
$this->response->redirect($this->url->link('extension/extension', 'token=' . $this->session->data['token'] . '&type=module', true));

// стало
$this->response->redirect($this->url->link('marketplace/extension', 'user_token=' . $this->session->data['user_token'] . '&type=module', true));

 

 

В заключение

 

Разумеется, приведённый список изменений далеко не полный — есть ещё тысяча и одна мелочь, отличающая Opencart 3 от прошлых версий, однако я постарался перечислить самые важные изменения, которые вам нужно учитывать при переходе от разработки для Opencart 2 в третью ветку.

 


Спасибо что дочитали! 👍

Как и всегда, приглашаю к дискусиям в комментариях 👇