Skip to content

Commit

Permalink
Merge pull request #158 from thomasnares/demosymfonyformsimple
Browse files Browse the repository at this point in the history
Add complete example module for a (simple) configuration page for a module
  • Loading branch information
kpodemski authored Jul 25, 2023
2 parents 2e54e12 + ffa4ab6 commit 438d65f
Show file tree
Hide file tree
Showing 10 changed files with 319 additions and 0 deletions.
28 changes: 28 additions & 0 deletions demosymfonyformsimple/README.md
Original file line number Diff line number Diff line change
@@ -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.
23 changes: 23 additions & 0 deletions demosymfonyformsimple/composer.json
Original file line number Diff line number Diff line change
@@ -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"
}
8 changes: 8 additions & 0 deletions demosymfonyformsimple/config/routes.yml
Original file line number Diff line number Diff line change
@@ -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
29 changes: 29 additions & 0 deletions demosymfonyformsimple/config/services.yml
Original file line number Diff line number Diff line change
@@ -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'
34 changes: 34 additions & 0 deletions demosymfonyformsimple/demosymfonyformsimple.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?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('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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?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()) {
/** 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(),
]);
}
}
21 changes: 21 additions & 0 deletions demosymfonyformsimple/src/Form/DemoConfigurationFormType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?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('Configuration text', 'Modules.DemoSymfonyFormSimple.Admin'),
'help' => $this->trans('Maximum 32 characters', 'Modules.DemoSymfonyFormSimple.Admin'),
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @author PrestaShop SA <[email protected]>
* @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']);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace PrestaShop\Module\DemoSymfonyFormSimple\Form;

use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface;
use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface;

/**
* Provider is responsible for providing form data, in this case, it is returned from the configuration component.
*
* 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);
}
}
23 changes: 23 additions & 0 deletions demosymfonyformsimple/views/templates/admin/form.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends '@PrestaShop/Admin/layout.html.twig' %}

{% block content %}
{{ form_start(demoConfigurationForm) }}
<div class="card">
<h3 class="card-header">
<i class="material-icons">settings</i> {{ 'Text form types'|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">
{{ 'Save'|trans({}, 'Admin.Actions') }}
</button>
</div>
</div>
</div>
{{ form_end(demoConfigurationForm) }}
{% endblock %}

0 comments on commit 438d65f

Please sign in to comment.