Страница панели на Symfony
Новые страницы панели управления пишут так же, как в обычном проекте на Symfony: маршрут связывает адрес с методом контроллера, контроллер готовит данные, шаблон Twig рисует страницу. Сделаем так страницу статистики отзывов. Для этого урока нужны автозагрузка и служба из предыдущего.
Что создаём
modules/acmehello/
├── config/
│ ├── routes.yml
│ └── services.yml
├── src/
│ ├── Controller/
│ │ └── Admin/
│ │ └── StatsController.php
│ └── Repository/
│ └── ReviewRepository.php
└── views/
└── templates/
└── admin/
└── stats.html.twigВсе три файла создают вручную.
Маршрут
# modules/acmehello/config/routes.yml
acmehello_stats:
path: /acmehello/stats
methods: [GET]
defaults:
_controller: 'Acme\Hello\Controller\Admin\StatsController::indexAction'
_legacy_controller: AdminAcmehelloStats
_legacy_link: AdminAcmehelloStatsacmehello_stats — имя маршрута, path — адрес, _controller — класс и метод, который отвечает. _legacy_controller связывает маршрут с вкладкой и правами доступа, а _legacy_link позволяет строить ссылку привычным getAdminLink('AdminAcmehelloStats').
К адресам модулей движок добавляет приставку /modules, поэтому страница откроется по адресу вида /admin437xyz/index.php/modules/acmehello/stats.
Контроллер
<?php
// modules/acmehello/src/Controller/Admin/StatsController.php
namespace Acme\Hello\Controller\Admin;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\Response;
class StatsController extends FrameworkBundleAdminController
{
public function indexAction(): Response
{
return $this->render('@Modules/acmehello/views/templates/admin/stats.html.twig', [
'layoutTitle' => 'Статистика отзывов',
]);
}
}Метод возвращает объект ответа. render() собирает его из шаблона; путь начинается с @Modules и имени модуля.
Шаблон
{# modules/acmehello/views/templates/admin/stats.html.twig #}
{% extends '@PrestaShop/Admin/layout.html.twig' %}
{% block content %}
<div class="card">
<h3 class="card-header">Отзывы</h3>
<div class="card-body">
<p>Здесь будет статистика.</p>
</div>
</div>
{% endblock %}Шаблон наследует общий макет панели: меню, шапка и заголовок страницы подставляются сами. Содержимое пишут в блоке content.
Вкладка
Добавьте страницу в свойство tabs главного класса и укажите имя маршрута:
// modules/acmehello/acmehello.php
[
'name' => 'Статистика отзывов',
'class_name' => 'AdminAcmehelloStats',
'route_name' => 'acmehello_stats',
'parent_class_name' => 'AdminCatalog',
'visible' => true,
],Сбросьте модуль и очистите кеш:
php bin/console prestashop:module reset acmehello
php bin/console cache:clearВ разделе «Каталог» появится пункт «Статистика отзывов», по нажатию откроется страница с карточкой.
Данные из службы
// modules/acmehello/src/Controller/Admin/StatsController.php
public function indexAction(): Response
{
$repository = $this->get('acme.hello.review_repository');
return $this->render('@Modules/acmehello/views/templates/admin/stats.html.twig', [
'layoutTitle' => 'Статистика отзывов',
'total' => $repository->countAll(),
'latest' => $repository->findLatest(5),
]);
}{% block content %}
<div class="card">
<h3 class="card-header">Всего отзывов: {{ total }}</h3>
<div class="card-body">
<ul>
{% for review in latest %}
<li>{{ review.author }} — {{ review.rating }}/5</li>
{% else %}
<li>Отзывов пока нет.</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}На странице появится общее число отзывов и пять последних. Twig экранирует переменные сам.
Ссылки и сообщения
| Вызов в контроллере | Что делает |
|---|---|
$this->generateUrl('acmehello_stats') | Адрес маршрута с токеном |
$this->redirectToRoute('acmehello_stats') | Перенаправление на маршрут |
$this->addFlash('success', 'Готово') | Зелёное сообщение на следующей странице |
$this->trans('Текст', 'Modules.Acmehello.Admin') | Перевод строки |
В шаблоне ссылку строит функция {{ path('acmehello_stats') }}.
Права доступа
Перед методом контроллера ставят аннотацию @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") из пространства имён PrestaShopBundle\Security\Annotation. Она проверяет, что у профиля сотрудника есть право просмотра вкладки.
Отличия PrestaShop 9
В версии 9 базовый класс называется PrestaShopAdminController, службы передают в аргументы метода или конструктор, а не получают через $this->get(), а вместо аннотаций используют атрибуты PHP. Маршруты и шаблоны остаются теми же.
Частая ошибка
Маршрут добавили, а страница отдаёт «No route found». Маршруты кешируются вместе с контейнером, и модуль должен быть установлен и включён, иначе его routes.yml не читается. Очистите кеш и проверьте список командой php bin/console debug:router, найдя в выводе acmehello_stats.