Разработка в Opencart: обзор основных отличий между второй и третьей версиями движка для разработчиков
Обновление мажорной версии Opencart принесло разработчикам много новшеств, в этой статье рассмотрим с чем вам придётся столкнуться при разработке модулей для Opencart 3.
В прошлой статье я подробно рассказывал об общем устройстве модулей в Opencart, а также показал на примере как создать элементарный модуль для Opencart 2.
Сегодня мы кратко пробежимся по основным отличиям между Opencart 2 и 3, с которыми вам придётся столкнуться при разработке своих решений для этого движка.
Отличие №1
Шаблонизатор TWIG
Ранее, Opencart не использовал никаких шаблонизаторов и мы писали в файлах .tpl обычный PHP код. Третья версия CMS принесла нам долгожданную поддержку шаблонов.
Хотя многие, возможно, и не согласятся, но я считаю внедрение шаблонизатора шагом вперёд для этого движка.
Шаблонизатор TWIG предоставляет необходимый минимум доступных функций для форматирования и управления отображением содержимого, теги для организации циклов и условий.
Нет таких задач для слоя представления, с которыми бы не справился TWIG.
Не стоит волноваться!
Вы сможете легко перевести большинство своих .tpl файлов в .twig если они семантически корректны и не используют какую либо бизнес-логику.
А зачем этот твиг? 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 в третью ветку.
Спасибо что дочитали! 👍
Как и всегда, приглашаю к дискусиям в комментариях 👇