禁用FOSUserBundle中定义的默认约束

时间:2015-07-16 16:22:34

标签: symfony fosuserbundle symfony-sonata sonata-user-bundle

我目前正在开发一个使用Sonata的Symfony2项目。

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

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

他们实际上已根据字段FOS\UserBundle\Model\User禁用了类usernameCanonical上的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中重现此更改?

2 个答案:

答案 0 :(得分:3)

我有一个解决方案,但不知道它是否符合您的需求。 您可以在config.yml中为fos_user更改de validation groups name。

例如:

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上的唯一约束。

答案 1 :(得分:2)

尽管@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

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

应用程序/配置/ FOS / fos_user.yml:

fos_user:

    registration:
        form:
            validation_groups:
                - CustomRegistration

    profile:
        form:
            validation_groups:
                - CustomProfile

应用程序/配置/奏/ sonata_user.yml:

sonata_user:
    profile:
        form:
            validation_groups:
                - CustomProfile

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

添加Application \ Sonata \ UserBundle \ DependencyInjection \ Compiler \ ValidationPass.php类。这是基于FOSU​​serBundle的原始类:

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类中的默认验证组(在重载的UserAdmin类中)

/**
 * {@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;
}

我不知道是否有更简单的方法来实现这一目标。不过,它对我有用。