Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Расширение таблиц и форм панели

Страницы панели на Symfony собраны из двух кирпичей: таблица со списком (grid) и форма. Модуль может дополнить чужую таблицу или форму — добавить колонку в список покупателей, поле в форму покупателя. Для этого у каждой таблицы и формы есть набор хуков действия, имена которых строятся по шаблону.

Хуки таблицы

ХукЧто позволяет изменить
action<Имя>GridDefinitionModifierНабор колонок, фильтров и действий
action<Имя>GridQueryBuilderModifierЗапрос SQL, которым выбираются строки
action<Имя>GridDataModifierУже выбранные строки

<Имя> — идентификатор таблицы: Customer, Order, Category, Address. Для списка покупателей хуки называются actionCustomerGridDefinitionModifier и actionCustomerGridQueryBuilderModifier.

Колонка в списке покупателей

Добавим в список покупателей колонку «Отзывов». Сначала описание колонки:

// modules/acmehello/acmehello.php
use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn;
 
public function hookActionCustomerGridDefinitionModifier(array $params): void
{
    $column = new DataColumn('reviews_count');
    $column->setName($this->trans('Отзывов', [], 'Modules.Acmehello.Admin'));
    $column->setOptions(['field' => 'reviews_count']);
 
    $params['definition']->getColumns()->addAfter('email', $column);
}

Строку use ставят в начало файла, до объявления класса. В $params['definition'] приходит описание таблицы. addAfter('email', ...) вставляет колонку после колонки с почтой, а опция field говорит, из какого поля строки брать значение.

Значение для колонки

Поля reviews_count в запросе пока нет. Его добавляет второй хук:

// modules/acmehello/acmehello.php
public function hookActionCustomerGridQueryBuilderModifier(array $params): void
{
    $params['search_query_builder']->addSelect(
        '(SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'acmehello_review` r
          WHERE r.id_customer = c.id_customer) AS reviews_count'
    );
}

search_query_builder — построитель запроса Doctrine, которым таблица выбирает покупателей; таблица покупателей в нём имеет псевдоним c. Подзапрос считает отзывы каждого покупателя по колонке id_customer, добавленной в уроке о таблицах.

Как увидеть результат

Зарегистрируйте оба хука в install() и сбросьте модуль:

&& $this->registerHook('actionCustomerGridDefinitionModifier')
&& $this->registerHook('actionCustomerGridQueryBuilderModifier')
php bin/console prestashop:module reset acmehello

Откройте «Клиенты → Клиенты»: после колонки с почтой появилась колонка «Отзывов» с числом у каждого покупателя.

Хуки формы

ХукКогда срабатывает
action<Имя>FormBuilderModifierФорма строится — можно добавить поле
actionAfterCreate<Имя>FormHandlerНовая запись сохранена
actionAfterUpdate<Имя>FormHandlerСуществующая запись сохранена

Поле в форме покупателя

// modules/acmehello/acmehello.php
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 
public function hookActionCustomerFormBuilderModifier(array $params): void
{
    $params['form_builder']->add('acme_trusted', CheckboxType::class, [
        'label' => $this->trans('Проверенный автор отзывов', [], 'Modules.Acmehello.Admin'),
        'required' => false,
    ]);
 
    $params['data']['acme_trusted'] = (bool) Configuration::get('ACMEHELLO_TRUSTED_' . (int) $params['id']);
    $params['form_builder']->setData($params['data']);
}

form_builder — построитель формы Symfony. Метод add() добавляет флажок, а setData() подставляет его текущее значение. В $params['id'] лежит номер покупателя; при создании нового покупателя он пуст.

Сохранение поля

// modules/acmehello/acmehello.php
public function hookActionAfterUpdateCustomerFormHandler(array $params): void
{
    Configuration::updateValue(
        'ACMEHELLO_TRUSTED_' . (int) $params['id'],
        (int) !empty($params['form_data']['acme_trusted'])
    );
}

В form_data приходят значения всех полей формы, включая добавленное. Здесь флажок для простоты хранится в Configuration; в настоящем модуле для этого заводят колонку в своей таблице. После регистрации трёх хуков и сброса модуля в форме покупателя появится флажок, и его состояние будет сохраняться.

Частая ошибка

Колонку добавили в описание таблицы, а запрос не изменили. Страница списка падает с ошибкой о неизвестном поле или показывает пустую колонку. Хуки GridDefinitionModifier и GridQueryBuilderModifier почти всегда идут парой: первый объявляет колонку, второй даёт для неё данные.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.