1

私のシステムには 2 つのエンティティがあります:PersonPhone次のコードです。

class Person
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $lastName;

    /**
     * @ORM\OneToOne(targetEntity="Phone", cascade={"persist"})
     */
    private $phone;
};

class Phone
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="PhoneType")
     */
    private $type;

    /**
     * @ORM\Column(type="integer")
     */
    private $countryCode;

    /**
     * @ORM\Column(type="integer")
     */
    private $regionCode;

    /**
     * @ORM\Column(type="integer")
     */
    private $number;
};

個人 (電話を使用) を作成および更新するフォームもあるためPersonType、電話 ( ) を表すフォームが埋め込まれていPhoneTypeます。

私の問題は、人がオプションで電話を持つことができるということですが、人が電話を持っている場合は、すべての電話フィールドが必要です。したがって、ユーザーがすべての電話フィールドに何も書き込まない場合、これは電話のない人を表し、このケースは有効です。ただし、ユーザーが少なくとも 1 つのフォーム フィールドに入力する場合、他のすべてのフィールドは必須です。

すべての電話フィールドが入力されていない場合、電話を null に設定するアプローチを試みます。これはエンティティに実装さsetPhoneれています。Personしかし、電話番号が null の場合、Symfony はすべての電話番号フィールドが必須であるが、入力されていないことを教えてくれます。Symfony は検証を person エンティティに直接適用すると思われるため、Symfony は電話を検証しないと思います。ヌルの電話を持っているのに、なぜすべての電話フィールドが入力されていないと教えてくれるのですか?

私が望むことを行う方法はありますか (できれば、すべてのコントローラーとフォームの種類を変更せずに、つまり、エンティティまたは検証コンポーネント レベルで) 方法はありますか?

編集:申し訳ありませんが、言及されていないことがあります。ユーザーが電話番号フィールドに入力した場合、すべての電話番号フィールドを異なるバリデーターで個別に検証する必要があります (フィールドが整形式の数値であるかどうかを確認するため、正しい長さを確認するためなど)。ただし、ユーザーがすべての電話フィールドを空のままにした場合、フィールドごとの検証は無視されます。

ありがとう!

4

5 に答える 5

3

私はこの方法を試してみます:

すべてのフィールドがnullであるか、すべてのフィールドがnullでないかを検証する追加のメソッドをPhoneエンティティに作成します(これらの2つのケースは正しいです)。その後、trueを返します。一部のフィールドがnullで、一部がfalseを返さない場合。新しいメソッドにassertアノテーションを追加します-これが新しい制約になります。

/**
 * @Assert\True(message = "Fill all fields or leave all them blank")
 */

そして、これはうまくいくはずです。

詳細については、こちらをご覧ください: http ://symfony.com/doc/master/book/validation.html#getters

編集:

これを試してください:

カスタム検証メソッド(電話フィールドのいずれかが入力されているかどうかをチェックするメソッド)をコールバック(クラスの最上位)として定義します。

 * @Assert\Callback(methods={"checkPhoneFields"})
 */
 class Phone {

次に、検証グループで検証する必要があるフィールドにマークを付けます。

/**
 * @ORM\Column(type="string", length=16, groups={"phone_validation"})
 */
private $number;

最後に、カスタム制約メソッドで、フィールドのいずれかが空でない場合は「phone_validation」グループをオンにする必要があります。

public function checkPhoneFields(ExecutionContext $context) {
    if (/* fields are not empty */) {
        $context->getGraphWalker()->walkReference($this, 'phone_validation', $context->getPropertyPath(), true);
    }

そして、それはうまくいくはずです。

于 2012-08-17T13:59:06.810 に答える
2

通りすがりの人のために、新しいバージョンの Symfony でできること:

/**
 *
 * @Assert\Callback()
 */
public function validatePhone(ExecutionContextInterface $context)
{
    if (/* Fields are not empty */)
    {
        $context->validate($this->getPhone(), 'phone', array("phone_validation"));
    }
}
于 2015-09-24T13:15:51.180 に答える
0

これを行う:

最初に phone エンティティで、次のようにフィールドを「nullable」として宣言します。

/**
 * @ORM\Column(type="integer", nullable=true)
 */
private $countryCode;

これにより、これらのフィールドに null 値を設定できます。

次に、フィールドのいずれも入力されていないか、すべてが入力されているかをチェックするバリデーターを宣言する必要があります。

class Phone {

...
/**
 * @Assert\True(message = "Phone must be empty of fill all fields")
 */
public function isPhoneOK()
{
    // check if no field is null or all of them are
    // return false if these conditions are not met
}
于 2012-08-17T14:14:48.253 に答える
0

この問題を解決するために、非常に単純なデータ トランスフォーマーを使用することもできます。

  1. Phone データ トランスフォーマーを作成します。

    class PhoneTransformer implements DataTransformerInterface
    {
        public function transform($phone)
        {
            if (is_null($phone))
                return new Phone();
    
            return $phone;
        }
    
        public function reverseTransform($phone)
        {
            if (is_null($phone))
                return null;
    
            if (!$phone->getType() && !$phone->getCountryCode() /* ... Test if phone is not valid here */)
                return null;
    
            return $phone;
    }
    
  2. 次に、このトランスフォーマーを PhoneType フォームの先頭に追加します。

    class PhoneType extends AbstractType
    {
        public function buildForm(FormBuilder $builder, array $options)
        {
            $builder
                /* Add fields here :
                ->add( ... )
                */
                ->prependNormTransformer(new PhoneTransformer())
            ;
        }
    }
    

データ トランスフォーマーの実装方法の詳細については、http://symfony.com/doc/2.0/cookbook/form/data_transformers.htmlを参照してください。

于 2012-12-19T18:21:01.733 に答える