mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°8771 - Add Symfony form component to iTop core (#760)
- Add Symfony Form Component - Add Symfony CSRF security component - Add iTop default form template - Add Twig debug extension to Twig Environment - Add iTop abstract controller facility to get form builder - Add Twig filter to make trans an alias of dict_s filter
This commit is contained in:
@@ -19,25 +19,38 @@
|
||||
|
||||
namespace Combodo\iTop\Application\TwigBase\Controller;
|
||||
|
||||
use Combodo\iTop\Application\WebPage\AjaxPage;
|
||||
use ApplicationMenu;
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\WebPage\AjaxPage;
|
||||
use Combodo\iTop\Application\WebPage\ErrorPage;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\Controller\AbstractController;
|
||||
use Dict;
|
||||
use Combodo\iTop\Application\WebPage\ErrorPage;
|
||||
use Exception;
|
||||
use ExecutionKPI;
|
||||
use IssueLog;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use LoginWebPage;
|
||||
use MetaModel;
|
||||
use ReflectionClass;
|
||||
use SetupPage;
|
||||
use SetupUtils;
|
||||
use Symfony\Bridge\Twig\Extension\FormExtension;
|
||||
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
|
||||
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormFactoryBuilderInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormRenderer;
|
||||
use Symfony\Component\Form\Forms;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Security\Csrf\CsrfTokenManager;
|
||||
use Twig\Error\Error;
|
||||
use Twig\Error\SyntaxError;
|
||||
use Twig\RuntimeLoader\FactoryRuntimeLoader;
|
||||
use utils;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use ZipArchive;
|
||||
|
||||
abstract class Controller extends AbstractController
|
||||
@@ -81,6 +94,15 @@ abstract class Controller extends AbstractController
|
||||
/** @var array contains same parameters as {@see iTopWebPage::SetBreadCrumbEntry()} */
|
||||
private $m_aBreadCrumbEntry = [];
|
||||
|
||||
/** @var Request Request (from Symfony http_foundation component @link https://symfony.com/doc/current/components/http_foundation.html) */
|
||||
private Request $oRequest;
|
||||
|
||||
/** @var FormFactoryBuilderInterface Factory form builder (from Symfony form component @link https://symfony.com/doc/current/components/form.html) */
|
||||
private FormFactoryBuilderInterface $oFormFactoryBuilder;
|
||||
|
||||
/** @var CsrfTokenManager Csrf manager (from Symfony form component @link https://symfony.com/doc/current/security/csrf.html) */
|
||||
private CsrfTokenManager $oCsrfTokenManager;
|
||||
|
||||
/**
|
||||
* Controller constructor.
|
||||
*
|
||||
@@ -96,6 +118,24 @@ abstract class Controller extends AbstractController
|
||||
$this->m_aDefaultParams = [];
|
||||
$this->m_aBlockParams = [];
|
||||
$this->SetModuleName($sModuleName);
|
||||
|
||||
// Initialize Symfony components
|
||||
$this->InitSymfonyComponents($sViewPath, $sModuleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Symfony components.
|
||||
*
|
||||
* @param string $sViewPath
|
||||
* @param string $sModuleName
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function InitSymfonyComponents(string $sViewPath, string $sModuleName): void
|
||||
{
|
||||
// Twig environment
|
||||
$aAdditionalPaths[] = APPROOT.'lib/symfony/twig-bridge/Resources/views/Form';
|
||||
$aAdditionalPaths[] = APPROOT.'templates';
|
||||
if (strlen($sViewPath) > 0) {
|
||||
$this->SetViewPath($sViewPath, $aAdditionalPaths);
|
||||
if ($sModuleName != 'core') {
|
||||
@@ -107,6 +147,17 @@ abstract class Controller extends AbstractController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PHP Request object representation from PHP request globals
|
||||
$this->oRequest = Request::createFromGlobals();
|
||||
|
||||
// Initialize the CSRF token manager
|
||||
$this->oCsrfTokenManager = new CsrfTokenManager();
|
||||
|
||||
// Initialize the form factory builder to handle Request objects
|
||||
$this->oFormFactoryBuilder = Forms::createFormFactoryBuilder()
|
||||
->addExtension(new HttpFoundationExtension())
|
||||
->addExtension(new CsrfExtension($this->oCsrfTokenManager));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,6 +186,14 @@ abstract class Controller extends AbstractController
|
||||
public function SetViewPath($sViewPath, $aAdditionalPaths = [])
|
||||
{
|
||||
$oTwig = TwigHelper::GetTwigEnvironment($sViewPath, $aAdditionalPaths);
|
||||
/** @link https://github.com/symfony/twig-bridge/blob/6.4/CHANGELOG.md#320 */
|
||||
$formEngine = new TwigRendererEngine(['application/forms/itop_console_layout.html.twig'], $oTwig);
|
||||
$oTwig->addRuntimeLoader(new FactoryRuntimeLoader([
|
||||
FormRenderer::class => function () use ($formEngine): FormRenderer {
|
||||
return new FormRenderer($formEngine, $this->oCsrfTokenManager);
|
||||
},
|
||||
]));
|
||||
$oTwig->addExtension(new FormExtension());
|
||||
$this->m_oTwig = $oTwig;
|
||||
}
|
||||
|
||||
@@ -659,6 +718,44 @@ abstract class Controller extends AbstractController
|
||||
$this->m_aBreadCrumbEntry = [$sId, $sLabel, $sDescription, $sUrl, $sIcon];
|
||||
}
|
||||
|
||||
public function GetRequest(): Request
|
||||
{
|
||||
return $this->oRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a form builder.
|
||||
* This form builder can be used to create a form or to add fields to an existing form.
|
||||
*
|
||||
* @param string $type
|
||||
* @param mixed|null $data
|
||||
* @param array $options
|
||||
*
|
||||
* @return FormBuilderInterface
|
||||
*/
|
||||
public function GetFormBuilder(string $type = FormType::class, mixed $data = null, array $options = []): FormBuilderInterface
|
||||
{
|
||||
return $this->oFormFactoryBuilder->getFormFactory()->createBuilder($type, $data,$options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a form.
|
||||
* This form can be directly used in a twig template.
|
||||
*
|
||||
* @param string $type
|
||||
* @param mixed|null $data
|
||||
* @param array $options
|
||||
*
|
||||
* @return FormInterface
|
||||
*/
|
||||
public function GetForm(string $type = FormType::class, mixed $data = null, array $options = []): FormInterface
|
||||
{
|
||||
if (is_null($data)) {
|
||||
$data = $type::GetDefaultData();
|
||||
}
|
||||
return $this->GetFormBuilder($type, $data,$options)->getForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aParams
|
||||
* @param $sName
|
||||
|
||||
@@ -11,12 +11,14 @@ use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\Forms\Twig\Extension\FormCompatibilityExtension;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use CoreTemplateException;
|
||||
use ExecutionKPI;
|
||||
use IssueLog;
|
||||
use Twig\Environment;
|
||||
use Twig\Error\Error;
|
||||
use Twig\Extension\DebugExtension;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
use utils;
|
||||
|
||||
@@ -80,7 +82,10 @@ class TwigHelper
|
||||
$oLoader->addPath($sAdditionalPath);
|
||||
}
|
||||
|
||||
$oTwig = new Environment($oLoader);
|
||||
// Create Twig environment
|
||||
$oTwig = new Environment($oLoader, [
|
||||
'debug' => utils::IsDevelopmentEnvironment(),
|
||||
]);
|
||||
Extension::RegisterTwigExtensions($oTwig);
|
||||
if (!utils::IsDevelopmentEnvironment()) {
|
||||
// Disable the cache in development environment
|
||||
@@ -90,7 +95,9 @@ class TwigHelper
|
||||
$oTwig->setCache($sCachePath);
|
||||
}
|
||||
|
||||
$oTwig->addExtension(new DebugExtension());
|
||||
$oTwig->addExtension(new UIBlockExtension());
|
||||
$oTwig->addExtension(new FormCompatibilityExtension());
|
||||
|
||||
return $oTwig;
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ class iTopComposer extends AbstractFolderAnalyzer
|
||||
'symfony/event-dispatcher/Tests',
|
||||
'symfony/filesystem/Tests',
|
||||
'symfony/finder/Tests',
|
||||
'symfony/form/Test',
|
||||
'symfony/http-client-contracts/Test',
|
||||
'symfony/http-foundation/Test',
|
||||
'symfony/http-kernel/Tests',
|
||||
@@ -91,6 +92,7 @@ class iTopComposer extends AbstractFolderAnalyzer
|
||||
'symfony/mailer/Test',
|
||||
'symfony/mime/Test',
|
||||
'symfony/routing/Tests',
|
||||
'symfony/security-core/Test',
|
||||
'symfony/stopwatch/Tests',
|
||||
'symfony/translation-contracts/Test',
|
||||
'symfony/twig-bridge/Test',
|
||||
|
||||
47
sources/Forms/Twig/Extension/FormCompatibilityExtension.php
Normal file
47
sources/Forms/Twig/Extension/FormCompatibilityExtension.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Twig\Extension;
|
||||
|
||||
use Dict;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
/**
|
||||
* Extension to provide compatibility with Symfony/Twig standard functions
|
||||
*
|
||||
* @package Combodo\iTop\Forms\Twig\Extension
|
||||
*/
|
||||
class FormCompatibilityExtension extends AbstractExtension
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function getFilters(): array
|
||||
{
|
||||
return [
|
||||
|
||||
// Alias of dict_s, to be compatible with Symfony/Twig standard
|
||||
new TwigFilter('trans', function ($sStringCode, $aData = null, $sTransDomain = false) {
|
||||
return Dict::S($sStringCode);
|
||||
})
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user