禁用 FOSUserBundle 中定义的默认约束

Disable default constraints defined in FOSUserBundle

我目前正在开发一个使用奏鸣曲的 Symfony2 项目。

以前的开发人员直接在供应商内部进行修改,这显然是一个巨大的错误,所以我正在重构它。我目前坚持对来自 FOSUserBundle 的约束映射进行的一些修改。

文件是:/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/config/validation/orm.xml

他们实际上禁用了基于字段 usernameCanonical 的 class FOS\UserBundle\Model\User 上的 UniqueEntity 约束,如下所示:

<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
        http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

    <class name="FOS\UserBundle\Model\User">
        <!-- <constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
            <option name="fields">usernameCanonical</option>
            <option name="errorPath">username</option>
            <option name="message">fos_user.username.already_used</option>
            <option name="groups">
                <value>Registration</value>
                <value>Profile</value>
            </option>
        </constraint> -->

        <constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
            <option name="fields">emailCanonical</option>
            <option name="errorPath">email</option>
            <option name="message">fos_user.email.already_used</option>
            <option name="groups">
                <value>Registration</value>
                <value>Profile</value>
            </option>
        </constraint>
    </class>

</constraint-mapping>

如何在覆盖的 FOSUserBundle 或覆盖的 SonataUserBundle 中重现此更改?

我有一个解决方案,但不知道它是否符合您的需要。 您可以在 config.yml 中为 fos_user 更改验证组名称。

例如:

fos_user:
    ...
    registration:
        ...
        form:
            validation_groups: [YourBundleNameRegistration, Default] #before it was [Registration, Default]
    profile:
        ...
        form:
            ...
            validation_groups: [YourBundleNameProfile, Default] #before it was [Profile, Default]

那么/vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/config/validation/orm.xml中定义的验证约束将不再适用。

您必须复制原始 orm.xml,并将其粘贴到您的 YourBundle/Resources/config 目录中。在此副本中,您将注册和配置文件替换为 YourBundleNameRegistration 和 YourBundleNameProfile。然后你删除对 usernameCanonical 的唯一约束。

尽管@Nico 的回答为我指明了正确的方向,但这是我必须完成的完整设置,以便将其集成到 SonataUserBundle 中并考虑我的自定义验证组。

事实上,我的自定义 orm.xml 文件似乎没有加载。所以在更改验证组之后,根本就没有再进行任何验证。

1。创建文件 orm.xml

Application\Sonata\UserBundle\Resources\config\validation\中:

<?xml version="1.0" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
        http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

    <class name="FOS\UserBundle\Model\User">
        <!-- <constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
            <option name="fields">usernameCanonical</option>
            <option name="errorPath">username</option>
            <option name="message">fos_user.username.already_used</option>
            <option name="groups">
                <value>Registration</value>
                <value>Profile</value>
            </option>
        </constraint> -->

        <constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
            <option name="fields">emailCanonical</option>
            <option name="errorPath">email</option>
            <option name="message">fos_user.email.already_used</option>
            <option name="groups">
                <value>CustomRegistration</value>
                <value>CustomProfile</value>
            </option>
        </constraint>
    </class>

</constraint-mapping>

2。告诉 FOSUserBundle 和 SonataUserBundle

要使用自定义验证组(我已经删除了不相关的配置行):

app/config/fos/fos_user.yml:

fos_user:

    registration:
        form:
            validation_groups:
                - CustomRegistration

    profile:
        form:
            validation_groups:
                - CustomProfile

app/config/sonata/sonata_user.yml:

sonata_user:
    profile:
        form:
            validation_groups:
                - CustomProfile

3。告诉编译器加载 "overriden" 验证文件

添加Application\Sonata\UserBundle\DependencyInjection\Compiler\ValidationPass.phpclass。这是基于 FOSUserBundle 的原始 class:

class ValidationPass implements CompilerPassInterface
{
    /**
     * {@inheritDoc}
     */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasParameter('fos_user.storage')) {
            return;
        }

        $storage = $container->getParameter('fos_user.storage');

        if ('custom' === $storage) {
            return;
        }

        $validationFile = __DIR__ . '/../../Resources/config/validation/' . $storage . '.xml';

        if ($container->hasDefinition('validator.builder')) {
            // Symfony 2.5+
            $container->getDefinition('validator.builder')
                ->addMethodCall('addXmlMapping', array($validationFile));

            return;
        }
    }
}

编辑Application\Sonata\UserBundle\ApplicationSonataUserBundle:

class ApplicationSonataUserBundle extends Bundle
{
    /**
     * {@inheritdoc}
     */
    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $container->addCompilerPass(new ValidationPass());
    }
}

4。覆盖 Sonata 的 UserAdmin class 中的默认验证组(在超载的 UserAdmin class 中)

/**
 * {@inheritdoc}
 */
public function getFormBuilder()
{
    $this->formOptions['data_class'] = $this->getClass();

    $options = $this->formOptions;
    $options['validation_groups'] =
        (!$this->getSubject() || is_null($this->getSubject()->getId())) ? 'CustomRegistration' : 'CustomProfile';

    $formBuilder = $this->getFormContractor()->getFormBuilder( $this->getUniqid(), $options);

    $this->defineFormBuilder($formBuilder);

    return $formBuilder;
}

我不知道是否有更简单的方法来实现这一点。尽管如此,它对我有用。