digivia / form-handler
为Symfony表单类型提供表单处理器
Requires
- php: >=8.0
- symfony/config: ^5.4 || ^6.0
- symfony/dependency-injection: ^5.4 || ^6.0
- symfony/form: ^5.4 || ^6.0
- symfony/http-foundation: ^5.4 || ^6.0
- symfony/http-kernel: ^5.4 || ^6.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- symfony/phpunit-bridge: ^6.0
- symfony/validator: ^5.4 || ^6.0
Suggests
- ext-intl: *
README
如果您想将表单提交期间执行的逻辑与控制器中执行的处理请求分离,这个包就是为您准备的 :)
因此,控制器只需完成其工作:接收请求并发送响应。
需求
需要使用php8和Symfony 5.4 / 6
安装
使用Symfony Flex的应用程序
打开命令行,进入您的项目目录,然后执行
$ composer require digivia/form-handler
不使用Symfony Flex的应用程序
步骤 1: 下载包
打开命令行,进入您的项目目录,并执行以下命令以下载此包的最新稳定版本
$ composer require digivia/form-handler
此命令要求您全局安装Composer,如Composer文档中的安装章节所述。
步骤 2: 启用包
然后,通过将其添加到项目中app/AppKernel.php
文件中注册的包列表中,启用此包
<?php // app/AppKernel.php // ... class AppKernel extends Kernel { public function registerBundles() { $bundles = [ // ... new Digivia\FormHandler\DigiviaFormHandlerBundle() ]; // ... } // ... }
配置
🆕
感谢Symfony自动配置,无需配置标签或其他内容
使用
创建您的表单,它必须实现接口Digivia\FormHandler\Contract\Form\FormWithHandlerInterface
然后,您可以在静态方法getHandlerClassName中提供您的处理器类名
use Digivia\FormHandler\Contract\Form\FormWithHandlerInterface; use App\FormHandler\TestFormHandler; /** * Class FormTestType * @package Digivia\Tests\HandlerFactory\TestSet\Form */ class FormTestType extends AbstractType implements FormWithHandlerInterface { public static function getHandlerClassName(): string { // Here add your form handler return TestFormHandler::class; } /** * @inheritdoc */ public function buildForm(FormBuilderInterface $builder, array $options) { // here add your form field - see Symfony doc } /** * @inheritdoc */ public function configureOptions(OptionsResolver $resolver) { // Form configuration - see Symfony doc } }
创建您的表单处理器
<?php namespace App\FormHandler\TestFormHandler; use App\Form\MyFormType; use Digivia\FormHandler\Handler\AbstractHandler; class TestFormHandler extends AbstractHandler { protected function process($data, array $options): void { // your business logic in case of successful form submitting // ie : Doctrine persisting, messenger, mail... } }
在控制器中,调用表单处理器工厂
public function edit(HandlerFactoryInterface $factory, Request $request, Post $post) : Response { // Instanciate form handler and gives him your form type class name $handler = $factory->createFormWithHandler(FormTestType::class); // Give data to work with and options to form / handler $handler->setData($post); // Optionally, set entity to work with to the form // Return Response after treatment return $handler->handle( $request, // Callable used in case of form submitted with success function (Post $post) use ($request) { return $this->redirectToRoute('post_show', ['id' => $post->getId()]); }, // Callable used in case of non-submitted form, or submitted but not valid function (FormView $formView, $data) { return $this->render('conference/edit.html.twig', [ 'form' => $formView, 'post' => $data ]); } ); }
如你所见,这个控制器只获取请求并发送响应...
您可以为表单提供一些选项,并为处理器“process”方法提供额外的参数
// Instanciate form handler $handler = $factory->createFormWithHandler(FormTestType::class); // Give data to work with and options to form / handler $handler->setFormOptions(['validation_groups' => false]); // Optionally, add form type options if you need // will be sent to $options in FormType : FormFactory::create(string $type = 'Symfony\Component\Form\Extension\Core\Type\FormType', $data = null, array $options = []) // Process extra parameters is fourth parameter $handler = $factory->createFormWithHandler(FormTestType::class); // Give data to work with and options to form / handler $handler->setExtraParams(['form_creation' => true]); // Optionally, add form type options if you need // will be sent to $options in this Form Handler method : protected function process($data, array $options): void
注意
两个可调用函数,$onSuccess 和 $render,必须返回一个响应(Symfony\Component\HttpFoundation\Response)。如果响应是Symfony\Component\HttpFoundation\RedirectResponse的实例,则表单处理器将提供HTTP 303状态码。
如果表单已提交但无效,则处理器将为响应提供HTTP 422状态码。
因此,您可以使用此包与Turbo一起使用,例如 - 查看:https://github.com/symfony/ux/blob/0a6ebad4bc67f74ba3bbb52f6586085ddcd28ab1/src/Turbo/README.md#forms
public function edit(HandlerFactoryInterface $factory, Request $request, Post $post) : Response { // Instanciate form handler $handler = $factory->createFormWithHandler(FormTestType::class); // Give data to work with and options to form / handler $handler->setData($post); // Optionally, set entity to work with to the form // Return Response after treatment return $handler->handle( $request, // Callable used in case of form submitted with success function (Post $post) use ($request) { // 🔥 If you uses Turbo 🔥 if (TurboStreamResponse::STREAM_FORMAT === $request->getPreferredFormat()) { // If the request comes from Turbo, only send the HTML to update using a TurboStreamResponse return $this->render( 'post/success.stream.html.twig', ['post' => $post], new TurboStreamResponse() ); } return $this->redirectToRoute('post_show', ['id' => $post->getId()]); }, // Callable used in case of non-submitted form, or submitted but not valid function (FormView $formView, $data) { return $this->render('conference/edit.html.twig', [ 'form' => $formView, 'post' => $data ]); } ); }
事件
当表单提交时,会触发多个事件
FormHandlerEvents::EVENT_FORM_PROCESS
在调用process方法之前触发的事件。它允许您修改从表单接收到的数据。因此,您可以通过此事件对处理器process方法发送的数据采取行动。
FormHandlerEvents::EVENT_FORM_SUCCESS
在表单成功提交以及process方法执行的处理之后触发的事件。
FormHandlerEvents::EVENT_FORM_FAIL
在表单提交失败后触发的事件。
如果您有任何问题或开发想法,请随时联系我。祝您玩得开心!
Eric BATARSON - Digivia