Эти классы доступны из фронт-офиса и добавляют функции для клиентов.
Создание фронтального контроллера
Чтобы фронтальный контроллер был прочитан PrestaShop, необходимо соблюсти три правила:
- Он хранится в подпапке
controllers/front/модуля. - Имя класса следует формату в CamelCase:
<ModuleClassName><FileName>ModuleFrontController. - Он расширяет класс
ModuleFrontController.
Пример минимального контроллера
Допустим, мы хотим создать контроллер, ответственный за проверку платежей в нашем модуле cheque. Мы создаем файл /modules/cheque/controllers/front/validation.php и его класс:
<?php
/**
* <ModuleClassName> => Cheque
* <FileName> => validation.php
* Формат ожидался: <ModuleClassName><FileName>ModuleFrontController
*/
class ChequeValidationModuleFrontController extends ModuleFrontController
{
}
Это все, методы, добавленные в класс, будут автоматически учитываться PrestaShop.
Доступные свойства
Контроллеры, добавленные в модуль, расширяют ModuleFrontController, который в свою очередь расширяет FrontController и Controller. Они предоставляют доступ к окружению, в котором они выполняются.
$this->module- экземпляр модуля, ответственного за контроллер.$this->context- результат вызоваContext::getContext().
Добавление методов в контроллер
Существуют два основных типа HTTP-запросов для контроллера:
- GET-запросы, используемые для получения данных;
- POST-запросы, используемые для изменения данных на сайте.
Для расширенного использования также могут быть вызваны другие HTTP-методы (такие как PUT, PATCH, DELETE).
Отображение содержимого
Обработка запросов может быть выполнена путем реализации метода initContent() во фронтальном контроллере. Обратите внимание, что родительский класс также реализует его, не забудьте вызвать его.
Назначение переменных для Smarty
Шаблонизатор Smarty доступен в свойстве context контроллера. Назначение переменных можно выполнить с помощью метода assign(array $vars).
<?php
public function initContent()
{
// В шаблоне нам нужны переменные paymentId и paymentStatus
$this->context->smarty->assign(
array(
'paymentId' => Tools::getValue('id'), // Получено из GET переменных
'paymentStatus' => [...],
));
}
Отображение HTML-содержимого
Это вторая часть, которую мы ожидаем в методе initContent(). HTML-содержимое должно храниться в шаблоне Smarty, доступном в подпапке модуля views/templates/front/. Метод setTemplate(...) ожидает в качестве параметра имя файла шаблона. Не нужно указывать полный путь, так как PrestaShop ожидает найти его в папке views/templates/front/ того же модуля.
<?php
public function initContent()
{
// В шаблоне нам нужны переменные paymentId и paymentStatus
$this->context->smarty->assign(
array(
'paymentId' => Tools::getValue('id'), // Получено из GET переменных
'paymentStatus' => [...],
));
// Будет использовать файл modules/cheque/views/templates/front/validation.tpl
$this->setTemplate('module:cheque/views/templates/front/validation.tpl');
}
Обработка действий (POST)
POST-запросы будут обрабатываться методом postProcess(). Он не получает параметров и не ожидает возвращаемых значений, но ввод пользователя можно проверить с помощью Tools::getIsset(...) и получить с помощью Tools::getValue(...). По завершении контроллеры обычно перенаправляют на другой маршрут, используя Tools::redirect(<url>).
Доступ к фронтальному контроллеру модуля
Адреса к вашему контроллеру можно легко сгенерировать с помощью класса Link:
<?php
public function Link::getModuleLink($module, $controller, array $params = array());
$module - это техническое название модуля, $controller - это имя файла контроллера (без '.php'), а $params - массив переменных для добавления в настраиваемый маршрут или просто в качестве GET-параметров. Сгенерированный адрес автоматически обрабатывает среды HTTP или HTTPS, с или без URL-переписывания.
Пример вызовов метода
<?php
Context::getContext()->link->getModuleLink('cheque', 'validation', array('idPayment' => 1337));
Без переписывания URL: http://<shop_domain>/index.php?idPayment=1337&fc=module&module=cheque&controller=validation&id_lang=1
С переписыванием URL: http://<shop_domain>/en/module/cheque/validation?idPayment=1337
Ajax-запрос
При вызове контроллера через AJAX, необходимо добавить параметр ajax в URL.
Context::getContext()->link->getModuleLink('cheque', 'validation', array('idPayment' => 1337, 'ajax'=>true));
Без переписывания URL: http://<shop_domain>/index.php?idPayment=1337&fc=module&module=cheque&controller=validation&id_lang=1&ajax=true
С переписыванием URL: http://<shop_domain>/en/module/cheque/validation?idPayment=1337&ajax=true
Ограничение доступа
Только для авторизованных клиентов
Установите свойство $auth в true, если хотите, чтобы гости автоматически перенаправлялись на страницу входа.
<?php
public $auth = true;
public $guestAllowed = false;
Для всех, временно
Вы можете заставить страницу технического обслуживания отображаться, когда клиент обращается к контроллеру.
<?php
protected $maintenance = true;
Не-SSL запросы
Когда SSL включен в магазине, вы можете заставить вызов к контроллеру быть защищенным, перенаправив его на HTTPS.
<?php
public $ssl = true;
Порядок выполнения функций контроллера
- __construct(): Устанавливает все переменные-члены контроллера.
- init(): Инициализирует контроллер.
- setMedia() или setMobileMedia(): Добавляет все JavaScript и CSS специфики на страницу, чтобы их можно было объединить, сжать и кэшировать.
- postProcess(): Обрабатывает ввод (например, обрабатывает ajaxProcess).
- initHeader(): Вызывается перед initContent().
- initContent(): Инициализирует содержимое.
- initFooter(): Вызывается после initContent().
- display() или displayAjax(): Отображает содержимое.
Использование фронтального контроллера в качестве задачи cron
Благодаря Symfony, модули могут реализовывать Консольные команды для задач cron. Для модулей, совместимых с ранними версиями PrestaShop 1.7 и предыдущими основными версиями, нет специального обработчика для вызовов CLI. Доступен обходной путь с фронтальными контроллерами, содержащими специфические проверки для вызовов CLI.
Реализация контроллера вместо простого PHP-скрипта позволит избежать некоторых проблем, таких как неинициализированный Context или Symfony Kernel, особенно в последних версиях PrestaShop (например, отображение цен с версии PS 1.7.6). Поэтому, даже для вызовов CLI, запускаемых заданиями cron, мы рекомендуем иметь контроллер. Хитрость заключается в том, чтобы определить его как Ajax-вызов, чтобы предотвратить отображение шаблона страницы.
Следующий код предоставляет основу для задачи cron в модуле examplemodule.
<?php
class ExampleModuleCronModuleFrontController extends ModuleFrontController
{
/** @var bool Если установлено в true, будет перенаправлен на страницу аутентификации */
public $auth = false;
/** @var bool */
public $ajax;
public function display()
{
$this->ajax = 1;
if (!Tools::isPHPCLI()) {
$this->ajaxRender('Forbidden call.');
}
// Дополнительные проверки токенов
// ...
$this->ajaxRender("hello\n");
}
}
Этот контроллер теперь можно запускать, создавая PHP-файл, который инициирует маршрут к контроллеру, затем включает файл index.php в корне PrestaShop, чтобы инициализировать диспетчер и ваш контроллер.
Этот вид скрипта также полезен, если автономный PHP-скрипт, взаимодействующий с PrestaShop, был перенесен в ModuleFrontController. URL-адреса для вызова изменятся при переходе в контроллер, но старый будет все еще доступен с этим обходным путем.
<?php
$_GET['fc'] = 'module';
$_GET['module'] = 'examplemodule';
$_GET['controller'] = 'cron';
require_once dirname(__FILE__) . '/../../index.php';
Код теперь можно вызвать через команду php в терминале:
$ php modules/examplemodule/cron.php
hello
