8

を拡張しているため、ユーザー エンティティBaseUserにプロパティがありません。$name検証を追加するにはどうすればよいですか? $usernameこのエンティティにプロパティを追加することはできますか? ユーザークラスにネイティブに提供されている特定の機能や検証などを台無しにしたり、オーバーライドしたりしますか?

私はこの質問に答えました:FOSUserBundle - Validation for username, password or email fields
しかし、私は一連の注釈検証を使用しているため、それはうまくいきません。

フォローアップの質問fosUSerBundle-XMLファイルで、取得したユーザー名を使用するためのチェッカーがネイティブにあることをユーザーを検証するために見ています。その機能が得られません。既存のユーザーと同じ名前のユーザーを追加しようとすると、SQL エラー メッセージが表示されます。これは、XML 検証ファイルをすべてオーバーライドする注釈を使用しているためでしょうか?

<?php
namespace BizTV\UserBundle\Entity;

use BizTV\UserBundle\Validator\Constraints as BizTVAssert;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;


use FOS\UserBundle\Model\User as BaseUser;

use Doctrine\ORM\Mapping as ORM;

use BizTV\BackendBundle\Entity\company as company;


class User extends BaseUser implements AdvancedUserInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;  

//TODO: Add regex on $name for a-z, A-Z, 0-9 and _ (underscore) 
//TODO: Add constraint on $name    * @BizTVAssert\NameExists    (and finish coding this constraint)

    /**
    * @var object BizTV\BackendBundle\Entity\company
    *  
    * @ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
    * @ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
    */
    protected $company; 

    /**
    * @var object BizTV\UserBundle\Entity\UserGroup
    * @ORM\ManyToOne(targetEntity="BizTV\UserBundle\Entity\UserGroup")
    * @ORM\JoinColumn(name="userGroup", referencedColumnName="id", nullable=true)
    */
    protected $userGroup;   

だから私はここ(フォームで検証グループを使用するsymfony2)を見て、フォームを構築するときにコントローラーにこれを追加してその解決策を試しました。何も起こりません (まだ INSERT INTO SQL エラーに直接ジャンプします)

    $entity  = new User();
    $request = $this->getRequest();
    $form    = $this->createForm(new newUserType($tempCompany), $entity, array('validation_groups'=>'registration'));
    $form->bind($request);

また、この検証グループ「登録グループ」(一意のユーザーと電子メールの検証を「無料」で提供することになっています)をフォームクラスで次のように設定しようとしました:

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
    'validation_groups' => array('registration'),
));
}

それでも何も起こりません。保存時にSQLエラーにまっすぐ。

4

5 に答える 5

3

早々にお詫び申し上げます。$nameプロパティまたはプロパティを検証するかどうかは完全にはわかりません$usernameが、これが正しい方向に向けられることを願っています.

正規表現検証を使用してプロパティを追加するには、$name次のようになります。テストされていませんが、ここから始めます。

<?php

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     * @Assert\NotBlank(groups={"Registration","Profile"})
     * @Assert\Regex(pattern="/^[a-zA-Z0-9_]+$/", groups={"Registration","Profile"})
     */
    protected $name;

    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    public function getName()
    {
        return $this->name;
    }
}

一意の usernameCanonical および emailCanonical 検証は継承されますが、検証グループ内にあります。検証グループの詳細については、こちらこちらをご覧ください。

これまでのところ、FOSUserBundle は一種のリポジトリのようにユーザー マネージャーを使用しているように思われるので、それを使用してストレージ レイヤーとできるだけやり取りする必要があります。これは、コントローラーでどのように見えるかを示しています (これもテストされていません)。

// setting values manually
$userManager = $this->container->get('fos_user.user_manager');
$user = $userManager->createUser();
$user->setName('Joe');
$user->setUsername('joeuser');
$user->setEmail('joe@gmail.com');
$user->setPlainPassword('secret');
$user->addRole('ROLE_EDITOR');

// persist to database
$userManager->updateUser($user);

// inherited validations that check for username and email uniqueness
// using validation group names 'Registration' and 'Profile'
$uniqueEmail = $user->getEmailCanonical();
$uniqueUsername = $user->getUsernameCanonical();

フォーム ビルダーを使用している場合、またはバンドルで提供されていないフォーム タイプを使用している場合は、次のようになります。

// setting values from a form
$userManager = $this->container->get('fos_user.user_manager');
$user = $userManager->createUser();

$form = $this->container->get('form.factory')
    ->createBuilder('form', $user, array('validation_groups' => 'Registration'))
    ->add('username', 'text')
    ->add('email', 'email')
    ->add('name', 'text')
    ->add('plainPassword', 'repeated', array(
        'type' => 'password'
    ))
    ->getForm();

if ($request->isMethod('POST')) {
    $form->handleRequest($request);
    if ($form->isValid()) {
        $userManager->updateUser($user);

        // redirect response
    }
}

return $this->container->get('templating')->renderResponse($templateName, array(
    'form' => $form->createView()
));

これが役立つことを願っています。詳細を提供できる場合はお知らせください。ここにコードの一部を投稿しますが、実装は少し異なります。

于 2013-11-13T06:13:40.520 に答える
2

これは質問に対する正確な回答ではありませんが、これまでのところ私にとっての解決策です。バリデーターをフォーム (UserType) に追加しました。

    $validatorUsername = function(FormEvent $event){
        $form = $event->getForm();
        $myExtraField = $form->get('username')->getData();
        if ( preg_match('/^[a-zA-Z0-9_]+$/',$myExtraField) == false ) {
          $form['username']->addError(new FormError("Du får inte använda andra specialtecken än understreck (_)"));
        }

    };
于 2013-10-31T19:54:37.993 に答える
1

Symfony クックブックに記載されているコールバック検証制約を実装します: http://symfony.com/doc/current/reference/constraints/Callback.html

例:

use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use BizTV\BackendBundle\Entity\company;

/**
 * @Assert\Callback(methods={"validateName"})
 */
class User extends BaseUser implements AdvancedUserInterface
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;  

/**
* @var object BizTV\BackendBundle\Entity\company
*  
* @ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* @ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company; 

/**
* @var object BizTV\UserBundle\Entity\UserGroup
* @ORM\ManyToOne(targetEntity="BizTV\UserBundle\Entity\UserGroup")
* @ORM\JoinColumn(name="userGroup", referencedColumnName="id", nullable=true)
*/
protected $userGroup;   

/**
 * @param ExecutionContextInterface $context
 */
public function validateName(ExecutionContextInterface $context)
{
    // do some validation

    // or add violation
        $context->addViolationAt(
            'name',
            'Name "%name% is not valid',
            array('%name%' => $this->getName()),
            null
        );
}
于 2013-11-13T13:04:38.403 に答える