С новой архитектурой Symfony, [существует гораздо более современный способ интеграции форм настройки]({{Configure
действие) для ваших модулей.
В первой части этого руководства мы объясним, как реализовать такой механизм в модуле. Мы создадим модуль с выделенной страницей настройки, состоящей из простого поля конфигурации.
Содержание:
{{< toc >}}
Создание базового модуля
[Следуя этому руководству]({{
<?php
declare(strict_types=1);
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
class DemoSymfonyFormSimple extends Module
{
public function __construct()
{
$this->name = 'demosymfonyformsimple';
$this->author = 'PrestaShop';
$this->version = '1.0.0';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->trans('Демонстрация формы настройки на основе Symfony', [], 'Modules.Demosymfonyformsimple.Admin');
$this->description = $this->trans(
'Модуль демонстрирует простую страницу настройки модуля, созданную с использованием Symfony.',
[],
'Modules.Demosymfonyformsimple.Admin'
);
$this->ps_versions_compliancy = ['min' => '8.0.0', 'max' => '8.99.99'];
}
}
Затем создайте файл composer.json
в вашем модуле и зарегистрируйте ваш namespace:
{
"name": "prestashop/demosymfonyformsimple",
"description": "PrestaShop - Примеры форм настроек",
"license": "AFL-3.0",
"authors": [
{
"name": "PrestaShop Core Team"
}
],
"autoload": {
"psr-4": {
"PrestaShop\\Module\\DemoSymfonyFormSimple\\": "src/"
}
},
"require": {
"php": ">=7.1.0"
},
"config": {
"preferred-install": "dist",
"prepend-autoloader": false
},
"type": "prestashop-module"
}
Затем выполните команду composer dump-autoload
из каталога модуля для генерации файла autoload.php
. Смотрите [Настройка composer в модуле]({{
Создание типа формы настройки
Первое, что нужно создать, это тип формы для нашей формы настройки.
Создайте файл DemoConfigurationFormType.php
в каталоге src/Form
.
<?php
declare(strict_types=1);
namespace PrestaShop\Module\DemoSymfonyFormSimple\Form;
use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class DemoConfigurationFormType extends TranslatorAwareType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('config_text', TextType::class, [
'label' => $this->trans('Текст настройки', 'Modules.Demosymfonyformsimple.Admin'),
'help' => $this->trans('Максимум 32 символа', 'Modules.Demosymfonyformsimple.Admin'),
]);
}
}
Эта форма имеет только одну настройку: config_test
, типа Symfony\Component\Form\Extension\Core\Type\TextType
.
Регистрация вашего вновь созданного типа формы
Создайте файл services.yml
в каталоге config/
.
services:
_defaults:
public: true
# Форма текста настройки демо
prestashop.module.demosymfonyformsimple.form.type.demo_configuration_text:
class: 'PrestaShop\Module\DemoSymfonyFormSimple\Form\DemoConfigurationFormType'
parent: 'form.type.translatable.aware'
public: true
tags:
- { name: form.type }
Этот файл services.yml
регистрирует ваш класс PrestaShop\Module\DemoSymfonyFormSimple\Form\DemoConfigurationFormType
как prestashop.module.demosymfonyformsimple.form.type.demo_configuration_text
. Он также добавляет тег name: form.type
и объявляет его как public
.
{{% notice note %}} Вы можете узнать больше о сервисах в официальной документации Symfony. {{% /notice %}}
Создание настройки данных
Создайте файл DemoConfigurationTextDataConfiguration.php
в каталоге src/Form
.
<?php
declare(strict_types=1);
namespace PrestaShop\Module\DemoSymfonyFormSimple\Form;
use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface;
use PrestaShop\PrestaShop\Core\ConfigurationInterface;
/**
* Конфигурация используется для сохранения данных в таблице конфигурации и извлечения из нее.
*/
final class DemoConfigurationTextDataConfiguration implements DataConfigurationInterface
{
public const DEMO_SYMFONY_FORM_SIMPLE_TEXT_TYPE = 'DEMO_SYMFONY_FORM_SIMPLE_TEXT_TYPE';
public const CONFIG_MAXLENGTH = 32;
/**
* @var ConfigurationInterface
*/
private $configuration;
public function __construct(ConfigurationInterface $configuration)
{
$this->configuration = $configuration;
}
public function getConfiguration(): array
{
$return = [];
$return['config_text'] = $this->configuration->get(static::DEMO_SYMFONY_FORM_SIMPLE_TEXT_TYPE);
return $return;
}
public function updateConfiguration(array $configuration): array
{
$errors = [];
if ($this->validateConfiguration($configuration)) {
if (strlen($configuration['config_text']) <= static::CONFIG_MAXLENGTH) {
$this->configuration->set(static::DEMO_SYMFONY_FORM_SIMPLE_TEXT_TYPE, $configuration['config_text']);
} else {
$errors[] = 'Значение DEMO_SYMFONY_FORM_SIMPLE_TEXT_TYPE слишком длинное';
}
}
/* Ошибки возвращаются здесь. */
return $errors;
}
/**
* Убедитесь, что переданные параметры действительны.
*
* @return bool Возвращает true, если исключения не выброшены
*/
public function validateConfiguration(array $configuration): bool
{
return isset($configuration['config_text']);
}
}
DemoConfigurationTextDataConfiguration
связывает config_text
из типа формы с ключом данных конфигурации DEMO_SYMFONY_FORM_SIMPLE_TEXT_TYPE
.
Регистрация настройки данных
В config/services.yml
зарегистрируйте вашу вновь созданную DemoConfigurationTextDataConfiguration
:
prestashop.module.demosymfonyformsimple.form.demo_configuration_text_data_configuration:
class: PrestaShop\Module\DemoSymfonyFormSimple\Form\DemoConfigurationTextDataConfiguration
arguments: ['@prestashop.adapter.legacy.configuration']
Создание поставщика данных формы
Создайте файл DemoConfigurationTextFormDataProvider.php
в каталоге src/Form
.
<?php
declare(strict_types=1);
namespace PrestaShop\Module\DemoSymfonyFormSimple\Form;
use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface;
use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface;
/**
* Поставщик отвечает за предоставление данных формы, в данном случае они возвращаются из компонента конфигурации.
*
* Class DemoConfigurationTextFormDataProvider
*/
class DemoConfigurationTextFormDataProvider implements FormDataProviderInterface
{
/**
* @var DataConfigurationInterface
*/
private $demoConfigurationTextDataConfiguration;
public function __construct(DataConfigurationInterface $demoConfigurationTextDataConfiguration)
{
$this->demoConfigurationTextDataConfiguration = $demoConfigurationTextDataConfiguration;
}
public function getData(): array
{
return $this->demoConfigurationTextDataConfiguration->getConfiguration();
}
public function setData(array $data): array
{
return $this->demoConfigurationTextDataConfiguration->updateConfiguration($data);
}
}
Регистрация поставщика данных формы
В config/services.yml
зарегистрируйте вашего вновь созданного DemoConfigurationTextFormDataProvider
:
prestashop.module.demosymfonyformsimple.form.demo_configuration_text_form_data_provider:
class: 'PrestaShop\Module\DemoSymfonyFormSimple\Form\DemoConfigurationTextFormDataProvider'
arguments:
- '@prestashop.module.demosymfonyformsimple.form.demo_configuration_text_data_configuration'
Создание и регистрация обработчика формы
Для этого обработчика формы нам не нужно создавать новый класс, мы можем использовать встроенный обработчик форм PrestaShop.
Получив экземпляр DemoConfigurationTextFormDataProvider
и DemoConfigurationFormType
, встроенный обработчик форм PrestaShop сможет обработать полученные данные.
Просто зарегистрируйте его в config/services.yml
:
prestashop.module.demosymfonyformsimple.form.demo_configuration_text_form_data_handler:
class: 'PrestaShop\PrestaShop\Core\Form\Handler'
arguments:
- '@form.factory'
- '@prestashop.core.hook.dispatcher'
- '@prestashop.module.demosymfonyformsimple.form.demo_configuration_text_form_data_provider'
- 'PrestaShop\Module\DemoSymfonyFormSimple\Form\DemoConfigurationFormType'
- 'DemoConfiguration'
Создание шаблонов формы
Создайте файл form.html.twig
в каталоге views/templates/admin
.
{% extends '@PrestaShop/Admin/layout.html.twig' %}
{% block content %}
{{ form_start(demoConfigurationForm) }}
<div class="card">
<h3 class="card-header">
<i class="material-icons">settings</i> {{ 'Типы форм текста'|trans({}, 'Modules.Demosymfonyformsimple.Admin') }}
</h3>
<div class="card-body">
<div class="form-wrapper">
{{ form_widget(demoConfigurationForm) }}
</div>
</div>
<div class="card-footer">
<div class="d-flex justify-content-end">
<button class="btn btn-primary float-right" id="save-button">
{{ 'Сохранить'|trans({}, 'Admin.Actions') }}
</button>
</div>
</div>
</div>
{{ form_end(demoConfigurationForm) }}
{% endblock %}
Создание контроллера настроек
Вам нужно создать контроллер для обработки ваших запросов на форму настройки.
Создайте файл DemoConfigurationController.php
в каталоге src/Controller
.
<?php
declare(strict_types=1);
namespace PrestaShop\Module\DemoSymfonyFormSimple\Controller;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class DemoConfigurationController extends FrameworkBundleAdminController
{
public function index(Request $request): Response
{
$textFormDataHandler = $this->get('prestashop.module.demosymfonyformsimple.form.demo_configuration_text_form_data_handler');
$textForm = $textFormDataHandler->getForm();
$textForm->handleRequest($request);
if ($textForm->isSubmitted() && $textForm->isValid()) {
/** Вы можете вернуть массив ошибок в обработчике формы, и они могут быть отображены пользователю с помощью flashErrors */
$errors = $textFormDataHandler->save($textForm->getData());
if (empty($errors)) {
$this->addFlash('success', $this->trans('Успешное обновление.', 'Admin.Notifications.Success'));
return $this->redirectToRoute('demo_configuration_form_simple');
}
$this->flashErrors($errors);
}
return $this->render('@Modules/demosymfonyformsimple/views/templates/admin/form.html.twig', [
'demoConfigurationForm' => $textForm->createView()
]);
}
}
{{% notice note %}}
Вы можете узнать больше о контроллерах в [разделе контроллеров и маршрутизации]({{
Создание маршрута для контроллера настроек
Создайте файл routes.yml
в каталоге config/
.
demo_configuration_form_simple:
path: /demosymfonyformsimple/configuration
methods: [GET, POST]
defaults:
_controller: 'PrestaShop\Module\DemoSymfonyFormSimple\Controller\DemoConfigurationController::index'
# Необходимо для работы с системой вкладок
_legacy_controller: AdminDemoSymfonyFormSimple
_legacy_link: AdminDemoSymfonyFormSimple
Добавление этого маршрута в метод getContent() модуля
Метод getContent()
модуля вызывается при доступе к странице настройки модуля.
Добавьте этот метод в ваш модуль с перенаправлением на ранее зарегистрированный маршрут.
public function getContent()
{
$route = $this->get('router')->generate('demo_configuration_form_simple');
Tools::redirectAdmin($route);
}
Установка и включение вашего модуля
Перейдите в административную панель и в менеджере модулей найдите ваш модуль и установите его.
{{% notice note %}} Вы также можете установить его через CLI:
php bin/console prestashop:module install demosymfonyformsimple
php bin/console prestashop:module enable demosymfonyformsimple
{{% /notice %}}
Навигация / тестирование формы настройки
Откройте ваш браузер и перейдите в Административная панель > Модули
.
Затем найдите ваш модуль (Демонстрация формы конфигурации Symfony
) и нажмите на кнопку Настроить
.
Полный пример модуля
Модуль, созданный в этом руководстве, доступен здесь.
Другие типы форм
Вы можете использовать все встроенные типы форм Symfony и специфичные для PrestaShop: [см. справочник типов форм]({{
{{% notice note %}} Пожалуйста, ознакомьтесь с этим примером модуля для полной реализации этих полей: DemoSymfonyForm {{% /notice %}}
Необходимый JavaScript для некоторых типов
Некоторые типы требуют инициализации компонента JavaScript для корректной работы.
Добавьте JS файл в шаблон twig вашей формы:
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('../modules/demosymfonyform/views/js/form.js') }}"></script>
{% endblock %}
И добавьте следующий JavaScript код в этот файл:
$(document).ready(function () {
// Узнайте больше о компонентах в документации
// https://devdocs.prestashop.com/8/development/components/global-components/
window.prestashop.component.initComponents(
[
'TranslatableField',
'TinyMCEEditor',
'TranslatableInput',
'GeneratableInput',
'TextWithLengthCounter',
],
);
window.prestashop.instance.generatableInput.attachOn('.js-generator-btn');
new window.prestashop.component.ChoiceTree('#form_category_choice_tree_type');
});
{{% notice note %}}
Зависимости JavaScript для специфичных типов [описаны в справочнике типов форм]({{
{{% notice note %}} Вы можете ознакомиться с этим модулем, чтобы увидеть пример использования JavaScript компонентов: DemoSymfonyForm {{% /notice %}}