Отключить ограничения по умолчанию, определенные в FOSUserBundle

В настоящее время я работаю над проектом Symfony2, который использует Sonata.

Предыдущие разработчики вносили изменения непосредственно внутри поставщиков, что, очевидно, является огромной ошибкой, поэтому я нахожусь в процессе рефакторинга. В настоящее время я застрял с некоторыми изменениями, которые были внесены в сопоставление ограничений из FOSUserBundle.

Это файл: /vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/config/validation/orm.xml

Они фактически отключили ограничение UniqueEntity для класса FOS\UserBundle\Model\User на основе поля usernameCanonical, например:

<?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?


person Didier Ghys    schedule 16.07.2015    source источник


Ответы (2)


У меня есть решение, но я не знаю, подойдет ли оно вам. Вы можете изменить имя группы проверки в файле 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. И в этой копии вы заменяете Registration и Profile на YourBundleNameRegistration и YourBundleNameProfile. Затем вы снимаете уникальное ограничение для usernameCanonical.

person Nico    schedule 17.07.2015
comment
Я попробую и буду держать вас в курсе. - person Didier Ghys; 17.07.2015

Поскольку ответ от @Nico указал мне правильное направление, вот полная настройка, которую мне пришлось сделать, чтобы интегрировать ее в SonataUserBundle и принять во внимание мои пользовательские группы проверки.

На самом деле казалось, что мой пользовательский orm.xml файл не загружен. Таким образом, после изменения групп валидации валидация больше не проводилась.

1. Создайте файл orm.xml

In 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

Чтобы использовать настраиваемые группы проверки (я убрал нерелевантные строки конфигурации):

приложение / config / fos / fos_user.yml:

fos_user:

    registration:
        form:
            validation_groups:
                - CustomRegistration

    profile:
        form:
            validation_groups:
                - CustomProfile

приложение / config / sonata / sonata_user.yml:

sonata_user:
    profile:
        form:
            validation_groups:
                - CustomProfile

3. Скажите компилятору загрузить "переопределенный" файл проверки.

Добавьте класс Application \ Sonata \ UserBundle \ DependencyInjection \ Compiler \ ValidationPass.php. Это основано на исходном классе из FOSUserBundle:

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;
        }
    }
}

Отредактируйте приложение \ Sonata \ UserBundle \ ApplicationSonataUserBundle:

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

4. Переопределите группы проверки по умолчанию в классе UserAdmin Sonata (в перегруженном классе 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;
}

Я не знаю, есть ли более простой способ добиться этого. Тем не менее, у меня это работает.

person Didier Ghys    schedule 20.07.2015
comment
Большое вам спасибо, это стоило мне буквально недель ... - person metafa; 07.07.2021