仅在自定义验证程序字段上需要Symfony表单

时间:2017-08-10 14:31:59

标签: php symfony symfony-forms

我正在努力找到一种方法来使required只有那些附有我自己的自定义验证器的字段。有没有办法实现这个目标?

/**
 * @var string
 * @ORM\Column(type="string", length=255)
 * @AdminAssert\CustomNotBlank(          // <--- this is my custom validator
 *     groups={
 *         //...
 *     }
 * )
 */
protected $name;

/**
 * @var string
 * @ORM\Column(type="string", length=255)
 * @Assert\Email(
 *     groups={
 *         //...
 *     }
 * )
 */
private $email;

因此,在上面的示例中,只有$name必须有'required' => true,因为它是由我自己的验证程序CustomNotBlank验证的。并且没有任何具有此验证器的字段,无论它们具有什么其他验证设置。

FormType并不重要,因为我有许多表单类型的字段(这只是两个文本类型字段的简单示例)

1 个答案:

答案 0 :(得分:2)

默认情况下Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser如果属性具有以下约束之一,则应执行此作业:

'Symfony\Component\Validator\Constraints\NotNull'
'Symfony\Component\Validator\Constraints\NotBlank'
'Symfony\Component\Validator\Constraints\IsTrue'

因此,您可能需要一个新的TypeGuesser来将自定义约束添加到列表中。一个简单的解决方案可能是装饰form.type_guesser.validator服务并覆盖包含此列表的公共方法guessRequiredForConstraint()

public function guessRequiredForConstraint(Constraint $constraint)
{
    switch (get_class($constraint)) {
        case 'Symfony\Component\Validator\Constraints\NotNull':
        case 'Symfony\Component\Validator\Constraints\NotBlank':
        case 'Symfony\Component\Validator\Constraints\IsTrue':
        case 'AppBundle\Validator\Constraints\CustomNotBlank': // <-- adds here
            return new ValueGuess(true, Guess::HIGH_CONFIDENCE);
    }
}

,如果required属性具有自定义约束,那么AppBundle\Validator\ValidatorTypeGuesser属性应该在表单字段中。

加:How to decorate the service

创建一个从原始类型guesser扩展的新类services: form.type_guesser.validator: class: AppBundle\Validator\ValidatorTypeGuesser arguments: ['@validator.mapping.class_metadata_factory'] tags: ['form.type_guesser'] ,然后添加重写方法并使用原始服务ID注册它,包括其标记和必需参数:

    <menuitem id="menu_picking_listing" name="Picking List" parent="purchase.menu_procurement_management" sequence="20" action="action_picking_listing"/>

    <record model="ir.actions.act_window" id="action_picking_listing">
        <field name="name">JobApplication Application</field>
        <field name="type">ir.actions.act_window</field>
        <field name="view_type">form</field>
        <field name="view_mode">tree,form</field>
        <field name="help" type="html"> 
            <p class="oe_view_nocontent_create"> Click here to create a Job.</p>
        </field>
        <field name="res_model">stock.picking</field>
    </record>

    <record model="ir.actions.act_window.view" id="action_picking_listing_tree">
        <field name="sequence" eval="1"/>
        <field name="view_mode">tree</field>
        <field name="view_id" ref="stock.vpicktree"/>
        <field name="act_window_id" ref="action_picking_listing"/>
    </record>

    <record model="ir.actions.act_window.view" id="action_picking_listing_form">
        <field name="sequence" eval="2"/>
        <!--<field name="model">stock.picking</field>-->
        <field name="view_mode">form</field>
        <field name="view_id" ref="stock.view_picking_form"/>
        <field name="act_window_id" ref="action_picking_listing"/>
        <field name="arch" type="xml">
            <notebook position="after">
                <page string="Landed Costs">
                    <field name="landed_costs" colspan="4" nolabel="1" />
                </page>
            </notebook>
        </field>
    </record>