diff --git a/demosymfonyformsimple/README.md b/demosymfonyformsimple/README.md new file mode 100644 index 0000000..016bfd0 --- /dev/null +++ b/demosymfonyformsimple/README.md @@ -0,0 +1,28 @@ +# Demonstration of how to use Symfony form types for Module configuration pages + +## About + +In this module, you will learn how to utilize Symfony form types to create configuration pages for your module. + +[This module has been created by following a guide from the developer documentation](https://devdocs.prestashop-project.org/8/modules/creation/adding-configuration-page-modern/). + +It provides a simple configuration page for a module with a Text Field. This text field value is stored [using the Configuration component](https://devdocs.prestashop-project.org/8/development/components/configuration/). + +## Supported PrestaShop versions + +This module has been tested with PrestaShop 8. + +## Requirements + +Composer + +## How to install + +Download or clone the module into the modules directory of your PrestaShop installation. +Rename the directory to make sure that the module directory is named `demosymfonyformsimple`. + +`cd` into module's directory and run following commands: + +`composer install` - to download dependencies into vendor folder + +Install the module from Back Office or via CLI. \ No newline at end of file diff --git a/demosymfonyformsimple/composer.json b/demosymfonyformsimple/composer.json new file mode 100644 index 0000000..817eb03 --- /dev/null +++ b/demosymfonyformsimple/composer.json @@ -0,0 +1,23 @@ +{ + "name": "prestashop/demosymfonyformsimple", + "description": "PrestaShop - Settings Form Examples", + "license": "AFL-3.0", + "authors": [ + { + "name": "PrestaShop Core Team" + } + ], + "autoload": { + "psr-4": { + "PrestaShop\\Module\\DemoSymfonyFormSimple\\": "src/" + } + }, + "require": { + "php": ">=7.2.5" + }, + "config": { + "preferred-install": "dist", + "prepend-autoloader": false + }, + "type": "prestashop-module" + } \ No newline at end of file diff --git a/demosymfonyformsimple/config/routes.yml b/demosymfonyformsimple/config/routes.yml new file mode 100644 index 0000000..4682af8 --- /dev/null +++ b/demosymfonyformsimple/config/routes.yml @@ -0,0 +1,8 @@ +demo_configuration_form_simple: + path: /demosymfonyformsimple/configuration + methods: [GET, POST] + defaults: + _controller: 'PrestaShop\Module\DemoSymfonyFormSimple\Controller\DemoConfigurationController::index' + # Needed to work with tab system + _legacy_controller: AdminDemoSymfonyFormSimple + _legacy_link: AdminDemoSymfonyFormSimple \ No newline at end of file diff --git a/demosymfonyformsimple/config/services.yml b/demosymfonyformsimple/config/services.yml new file mode 100644 index 0000000..96ecba7 --- /dev/null +++ b/demosymfonyformsimple/config/services.yml @@ -0,0 +1,29 @@ +services: + _defaults: + public: true + + # Demo configuration text form + 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 } + + prestashop.module.demosymfonyformsimple.form.demo_configuration_text_data_configuration: + class: PrestaShop\Module\DemoSymfonyFormSimple\Form\DemoConfigurationTextDataConfiguration + arguments: ['@prestashop.adapter.legacy.configuration'] + + 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.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' \ No newline at end of file diff --git a/demosymfonyformsimple/demosymfonyformsimple.php b/demosymfonyformsimple/demosymfonyformsimple.php new file mode 100644 index 0000000..dc146dd --- /dev/null +++ b/demosymfonyformsimple/demosymfonyformsimple.php @@ -0,0 +1,34 @@ +name = 'demosymfonyformsimple'; + $this->author = 'PrestaShop'; + $this->version = '1.0.0'; + $this->need_instance = 0; + + $this->bootstrap = true; + parent::__construct(); + + $this->displayName = $this->trans('Demo of the Symfony-based configuration form', [], 'Modules.DemoSymfonyFormSimple.Admin'); + $this->description = $this->trans( + 'Module demonstrates a simple module\'s configuration page made with Symfony.', + [], + 'Modules.DemoSymfonyFormSimple.Admin' + ); + + $this->ps_versions_compliancy = ['min' => '8.0.0', 'max' => '8.99.99']; + } + + public function getContent() + { + $route = $this->get('router')->generate('demo_configuration_form_simple'); + Tools::redirectAdmin($route); + } +} diff --git a/demosymfonyformsimple/src/Controller/DemoConfigurationController.php b/demosymfonyformsimple/src/Controller/DemoConfigurationController.php new file mode 100644 index 0000000..457e55c --- /dev/null +++ b/demosymfonyformsimple/src/Controller/DemoConfigurationController.php @@ -0,0 +1,37 @@ +get('prestashop.module.demosymfonyformsimple.form.demo_configuration_text_form_data_handler'); + + $textForm = $textFormDataHandler->getForm(); + $textForm->handleRequest($request); + + if ($textForm->isSubmitted() && $textForm->isValid()) { + /** You can return array of errors in form handler and they can be displayed to user with flashErrors */ + $errors = $textFormDataHandler->save($textForm->getData()); + + if (empty($errors)) { + $this->addFlash('success', $this->trans('Successful update.', '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(), + ]); + } +} diff --git a/demosymfonyformsimple/src/Form/DemoConfigurationFormType.php b/demosymfonyformsimple/src/Form/DemoConfigurationFormType.php new file mode 100644 index 0000000..0c71965 --- /dev/null +++ b/demosymfonyformsimple/src/Form/DemoConfigurationFormType.php @@ -0,0 +1,21 @@ +add('config_text', TextType::class, [ + 'label' => $this->trans('Configuration text', 'Modules.DemoSymfonyFormSimple.Admin'), + 'help' => $this->trans('Maximum 32 characters', 'Modules.DemoSymfonyFormSimple.Admin'), + ]); + } +} diff --git a/demosymfonyformsimple/src/Form/DemoConfigurationTextDataConfiguration.php b/demosymfonyformsimple/src/Form/DemoConfigurationTextDataConfiguration.php new file mode 100644 index 0000000..7c393c2 --- /dev/null +++ b/demosymfonyformsimple/src/Form/DemoConfigurationTextDataConfiguration.php @@ -0,0 +1,80 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ + +declare(strict_types=1); + +namespace PrestaShop\Module\DemoSymfonyFormSimple\Form; + +use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; +use PrestaShop\PrestaShop\Core\ConfigurationInterface; + +/** + * Configuration is used to save data to configuration table and retrieve from it. + */ +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 value is too long'; + } + } + + /* Errors are returned here. */ + return $errors; + } + + /** + * Ensure the parameters passed are valid. + * + * @return bool Returns true if no exception are thrown + */ + public function validateConfiguration(array $configuration): bool + { + return isset($configuration['config_text']); + } +} diff --git a/demosymfonyformsimple/src/Form/DemoConfigurationTextFormDataProvider.php b/demosymfonyformsimple/src/Form/DemoConfigurationTextFormDataProvider.php new file mode 100644 index 0000000..aed56a9 --- /dev/null +++ b/demosymfonyformsimple/src/Form/DemoConfigurationTextFormDataProvider.php @@ -0,0 +1,36 @@ +demoConfigurationTextDataConfiguration = $demoConfigurationTextDataConfiguration; + } + + public function getData(): array + { + return $this->demoConfigurationTextDataConfiguration->getConfiguration(); + } + + public function setData(array $data): array + { + return $this->demoConfigurationTextDataConfiguration->updateConfiguration($data); + } +} diff --git a/demosymfonyformsimple/views/templates/admin/form.html.twig b/demosymfonyformsimple/views/templates/admin/form.html.twig new file mode 100644 index 0000000..11af283 --- /dev/null +++ b/demosymfonyformsimple/views/templates/admin/form.html.twig @@ -0,0 +1,23 @@ +{% extends '@PrestaShop/Admin/layout.html.twig' %} + +{% block content %} + {{ form_start(demoConfigurationForm) }} +
+

+ settings {{ 'Text form types'|trans({}, 'Modules.DemoSymfonyFormSimple.Admin') }} +

+
+
+ {{ form_widget(demoConfigurationForm) }} +
+
+ +
+ {{ form_end(demoConfigurationForm) }} +{% endblock %}