【问题标题】:Injecting options into form in Silex在 Silex 中将选项注入表单
【发布时间】:2016-03-30 13:15:08
【问题描述】:

我在 Silex 中遇到了有关表单管理的问题。

我有一个表格 (RegionType),允许我填写和修改我的域(实体)信息(例如,有关 Region 的信息,例如名称和描述)。此表单扩展自 Symfony 的 AbstractType

我正在尝试向其中注入一个选项(validation_groups 为 false),以便能够重用表单来获取数据并使用此数据将搜索表单作为我的数据库。

由于搜索表单和编辑表单将使用相同字段和相同类型的数据,我不想重复我的类。

这是我的RegionType 表单:

<?php

namespace Easytrip2\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RegionType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add ( 'name', 'text', array (
                'label' => 'Region code'
        ) );
        $builder->add ( 'description', 'text', array (
                'label' => 'Region description'
        ) );
    }
    public function getName() {
        return 'region';
    }
    public static function getScriptsIdsArray() {
        return array (
                array ()
        );
    }
}

我可以将它用于我的搜索,只需复制它并添加以下方法:

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults ( array (
            'validation_groups' => false
    ) );
}

我的控制器用于在 Type 版本中编辑表单(标准 Create Update 事物):

public function regionUpdateByIdAction($id, Request $request, Application $app) {
        if (/*check the user rights*/) {
            //find the object being updated
            $obj = $app ['dao.region']->findById ( $id );
            //create form and handle request
            $form = $app ['form.factory']->create ( new RegionType ( $app ), $obj );
            $form->handleRequest ( $request );
            if ($form->isSubmitted () && $form->isValid ()) {
                if ($app ['dao.region']->save ( $obj )) {
                    //warn user and redirect
                    $app ['session']->getFlashBag ()->add ( 'success', 'The region was succesfully updated.' );
                    return $app->redirect ( $app ['url_generator']->generate ( 'region' ) );
                } else {
                    $app ['session']->getFlashBag ()->add ( 'error', 'Something went wrong...' );
                }
            }
            //generate the form view
            return $app ['twig']->render ( 'form.html.twig', array (
                    'form' => $form->createView (),
                    'title' => 'Edit region'
            ) );
        } else {
            $app ['session']->getFlashBag ()->add ( 'error', 'Don\'t have the rights...' );
            return $app->redirect ( $app ['url_generator']->generate ( 'home' ) );
        }
    }

我想做的是使用以下行

form = $app ['form.factory']->create ( new RegionType ( $app ), $obj );

并在其中添加一个选项,允许传递一个选项,例如

$form = $app ['form.factory']->create ( new RegionType ( $app ), $obj, array (
                    'validation_groups' => false
            ) );

调试时,我发现我的选项归结为规范化器,validation_groups 规范化器将其从 false 更改为空的 arrayOptionsResolver.php 的第 962 行,具有以下堆栈跟踪(没有错误发生,只是为了显示调用堆栈)。

C:/path/to/app/Easytrip2/vendor/symfony/options-resolver/OptionsResolver.php.Symfony\Component\OptionsResolver\OptionsResolver->offsetGet(): lineno 944 
C:/path/to/app/Easytrip2/vendor/symfony/options-resolver/OptionsResolver.php.Symfony\Component\OptionsResolver\OptionsResolver->resolve(): lineno 791   
C:/path/to/app/Easytrip2/vendor/symfony/form/ResolvedFormType.php.Symfony\Component\Form\ResolvedFormType->createBuilder(): lineno 104  
C:/path/to/app/Easytrip2/vendor/symfony/form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php.Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->createBuilder(): lineno 83   
C:/path/to/app/Easytrip2/vendor/symfony/form/FormFactory.php.Symfony\Component\Form\FormFactory->createNamedBuilder(): lineno 87    
C:/path/to/app/Easytrip2/vendor/symfony/form/FormFactory.php.Symfony\Component\Form\FormFactory->createBuilder(): lineno 67 
C:/path/to/app/Easytrip2/vendor/symfony/form/FormFactory.php.Symfony\Component\Form\FormFactory->create(): lineno 39    
C:/path/to/app/Easytrip2/src/Controller/RegionController.php.Easytrip2\Controller\RegionController->regionSearchAction(): lineno 39 
C:/path/to/app/Easytrip2/vendor/symfony/http-kernel/HttpKernel.php.call_user_func_array:{D:\users\F001780\Desktop\soft\wamp\www\Easytrip2\vendor\symfony\http-kernel\HttpKernel.php:139}(): lineno 139  
C:/path/to/app/Easytrip2/vendor/symfony/http-kernel/HttpKernel.php.Symfony\Component\HttpKernel\HttpKernel->handleRaw(): lineno 139 
C:/path/to/app/Easytrip2/vendor/symfony/http-kernel/HttpKernel.php.Symfony\Component\HttpKernel\HttpKernel->handle(): lineno 62 
C:/path/to/app/Easytrip2/vendor/silex/silex/src/Silex/Application.php.Silex\Application->handle(): lineno 586   
C:/path/to/app/Easytrip2/vendor/silex/silex/src/Silex/Application.php.Silex\Application->run(): lineno 563  
C:/path/to/app/Easytrip2/web/index.php.{main}(): lineno 10  

谁能解释这种行为?我在这里有点迷失在机械学中......

我忘记了我的 composer.json 设置:

{
    "require": {
        "silex/silex": "~1.3",
        "doctrine/dbal": "2.5.*",
        "symfony/security": "2.7.*",
        "twig/twig": "1.21.*",
        "symfony/twig-bridge": "2.7.*",
        "symfony/form": "2.7.*",
        "symfony/translation": "2.7.*",
        "symfony/config": "2.7.*",
        "jasongrimes/silex-simpleuser": "*",
        "twig/extensions": "1.3.*",
        "symfony/validator": "2.*",
        "phpoffice/phpexcel": "1.*",
        "symfony/monolog-bridge": "*",
        "box/spout": "*"
    },
    "require-dev": {
        "phpunit/phpunit": "*",
        "symfony/browser-kit": "*",
        "symfony/css-selector": "*",
        "silex/web-profiler": "*"
    },
    "autoload":{
        "psr-4":{"Easytrip2\\": "src"}
    },
    "autoload-dev":{
        "psr-4":{"Easytrip2\\": "tests"}
    }
}

【问题讨论】:

  • validation_groups 的标准化程序将 false 更改为空数组。您可以在 Symfony\Component\Form\Extension\Validator\Type\BaseValidatorExtension 中查看它是如何工作的
  • 可以设置validation_groups为null,默认值
  • 你们俩都是对的,我花了一些时间才意识到空数组的计算结果为假。但后来我无法理解这种行为的变化以及验证发生的原因......
  • 实际上,我只是意识到验证不在服务器中进行,而仅在浏览器中进行。我错配了这两个。所以我想我只需要找到一种方法来删除浏览器“验证”(在我的情况下只是一个required 标签。我想我可以使用现有的选项之一。我会留着你通知。
  • 尝试将novalidate 属性添加到表单。 w3schools.com/tags/att_form_novalidate.asp

标签: forms symfony silex


【解决方案1】:

好吧,我在这里犯了一个错误... 感谢 Max P.,我找到了它。

实际上使用此配置,服务器不会进行任何验证。除了将validation_groups 设置为false(禁用服务器验证)之外,我还必须将require 选项设置为false,以确保不会向浏览器发送所需的标签。

所以替换:

$form = $app ['form.factory']->create ( new RegionType ( $app ), $obj, array (
                'validation_groups' => false
        ) );

作者:

$form = $app ['form.factory']->create ( new RegionType ( $app ), $obj, array (
                'validation_groups' => false,
                'required' => false
        ) );

在浏览器和服务器端都有效。

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    相关资源
    最近更新 更多