Основные понятия
В документации и коде PrestaShop постоянно встречаются одни и те же слова: витрина, панель, хук, контекст. Этот урок — словарь. Каждое понятие дальше разобрано подробно, здесь важно понять, что чем является.
Витрина и панель управления
| Часть | Кто пользуется | Английское название |
|---|---|---|
| Витрина | Покупатель: каталог, корзина, заказ | Front office, FO |
| Панель управления | Владелец магазина: товары, заказы, настройки | Back office, BO |
Это две отдельные части с разными адресами, шаблонами и контроллерами. Модуль обычно работает в обеих: выводит блок на витрине и даёт страницу настроек в панели.
Модуль, хук, тема
| Понятие | Что это |
|---|---|
| Модуль | Папка в modules с главным классом. Его можно установить, выключить и удалить из панели |
| Хук | Именованная точка в коде или шаблоне, в которой движок спрашивает модули: «кто хочет что-то добавить?» |
| Тема | Шаблоны, стили и скрипты витрины |
Связь между ними такая: тема в нужном месте страницы вызывает хук, например displayHome, а модуль, подписанный на этот хук, возвращает HTML. Тема не знает, какие модули установлены, а модуль не знает, как устроена тема.
Два ядра
PrestaShop постепенно переезжает на фреймворк Symfony, и в коде живут два мира.
| Старое ядро | Новое ядро | |
|---|---|---|
| Папки | classes, controllers | src |
| Шаблоны | Smarty, файлы .tpl | Twig, файлы .html.twig |
| Где работает | Вся витрина и часть панели | Большинство страниц панели |
| Как выглядит код | Классы без пространств имён: Product, Db | Службы, маршруты, контроллеры Symfony |
Модулю приходится иметь дело с обоими: блок на витрине пишут по-старому, страницу в панели — по-новому. В курсе всегда сказано, к какому миру относится пример.
Контекст
Контекст — объект класса Context, в котором собрано всё о текущем запросе: какой магазин, язык, валюта, кто покупатель, какая у него корзина.
$context = Context::getContext();
$languageId = (int) $context->language->id;
$currencyCode = $context->currency->iso_code;
$customerName = $context->customer->firstname;Первая строка получает контекст, остальные читают из него номер языка, код валюты и имя покупателя. Внутри модуля и контроллера вызывать getContext() не нужно: контекст уже лежит в $this->context.
Что есть в контексте
| Свойство | Что в нём |
|---|---|
language | Текущий язык |
currency | Текущая валюта |
shop | Текущий магазин |
customer | Покупатель на витрине |
cart | Его корзина |
employee | Сотрудник в панели управления |
link | Построитель адресов страниц |
smarty | Шаблонизатор |
controller | Контроллер текущей страницы |
Несколько магазинов и языков
Одна установка может обслуживать несколько магазинов и языков. Поэтому у товара нет одного названия: оно своё для каждого языка. Поэтому же многие методы ядра принимают номер языка и номер магазина, а берут их обычно из контекста.
Частая ошибка
В панели управления обращаются к $this->context->customer или $this->context->cart и получают пустой объект: покупателя и корзины там нет, есть сотрудник в $this->context->employee. На витрине наоборот. Прежде чем читать свойство контекста, подумайте, на какой стороне выполняется код.