0

連絡先(名前、電子メール)エンティティごとにPhoneNumberエンティティのコレクションがあります。PhoneNumberは、市外局番、交換、サフィックス、内線番号、そしてタイプセレクター(職場、自宅、携帯電話)に分類されます。DataTransformerを使用して、4つの異なるテキストボックスではなく、単一のフォームフィールドに数値を表示できるようにします。電話番号はデータベース内で一意ではありません。

更新:文字列バージョンからエンティティに変換するときに、エンティティ全体にアクセスするにはどうすればよいですか?私は以前にこの問題に遭遇し、テキストフィールド内の角かっこ内にエンティティのIDを入れてから、エンティティを取得するためのクエリを実行できるように、変換でそれらを再実行しました。

phonenumber_combinedは、私のPhoneNumberCombinedTypeクラスを参照するカスタムフォームタイプのサービスです。

Contact内の電話を収集するための私の追加方法:

->add('phones', 'collection', array(
            'label'     => 'Phones',
            'type'      => new PhoneNumberType(),
            'allow_add' => true,
            'allow_delete' => true
            ))
        ; 

PhoneNumberType buildForm関数:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('phone', 'phonenumber_combined')
        ->add('type', 'entity',
            array('class'   => 'Test\Bundle\SystemBundle\Entity\Type',
            'property'      => 'name',
            'query_builder' => function(EntityRepository $er){
                return $er->createQueryBuilder('type')
                ->where('type.type = :t')
                ->orderBy('type.name', 'ASC')
                ->setParameter('t', 'PhoneNumber');
            }))
        ;           
}

PhoneNumberCombinedTypeサービス:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new PhoneNumberToStringTransformer($this->om);

    $builder->addViewTransformer($transformer);
}

PhoneNumberToStringTransformer:

public function transform($phonenumber)
{
    if (null === $phonenumber) {
        return null;
    }

    return $phonenumber->__toString();       
}

public function reverseTransform($phonenumber)
{
    if (!$phonenumber) {
        return null;
    } 

    // PHONE NUMBER IS JUST A STRING AT THIS POINT, HOW DO I GET THE ENTITY?
}
4

2 に答える 2

3

コンストラクターインジェクションを介してオブジェクトマネージャーを渡し、通常どおりに操作する必要があります。

class PhoneNumberTransformer implements DataTransformerInterface
{
    /**
     * @var ObjectManager
     */
    private $om;

    /**
     * @param ObjectManager $om
     */
    public function __construct(ObjectManager $om)
    {
        $this->om = $om;
    }

    public function transform($phonenumber)
    {
        if ($phonenumber === null) {
            return null;
        }

        return $phonenumber->__toString();
    }

    public function reverseTransform($phonenumber)
    {
        if (!$this->phonenumber) {
            return null;
        }

        $phoneEntity = $this->om
            ->getRepository('{REFERENCE_TO_THE_ENTITY}')
            ->findOneBy(array('phonenumber' => $phonenumber));

        if ($phoneEntity === null) {
            throw new TransformationFailedException();
        }

        return $phoneEntity;
    }
}
于 2013-03-14T23:06:38.330 に答える
0

更新がなくて申し訳ありませんが、この問題に対する適切な解決策を見つけました。逆変換後に自動的に呼び出されると思われる PhoneNumber エンティティに setPhone メソッドを追加しました。トランスフォーマーに正規表現を追加して、電話番号をそれぞれのセクションに分割し、各セクションを配列に追加しました。この配列はトランスフォーマーによって返され、setPhone によって使用されて PhoneNumber オブジェクトが更新されます。

PhoneNumber エンティティの setPhone メソッド:

/**
 * Used by PhoneNumberToStringTransformer to set Entity data
 * @param array $phone_data
 */
public function setPhone($phone_data)
{
    if($phone_data == null) {
        $this->setAreaCode(null);
        $this->setExchange(null);
        $this->setSuffix(null);
        $this->setExtension(null);
        return $this;
    }

    $this->setAreaCode($phone_data['AreaCode']);
    $this->setExchange($phone_data['Exchange']);
    $this->setSuffix($phone_data['Suffix']);
    $this->setExtension($phone_data['Extension']);

    return $this;
}

私の PhoneNumberToStringTransformer の reverseTransform:

/**
 * Transforms a phonenumber string to an array that will be passed to setPhone
 * which will handle setting each entity field.
 *
 * @param  string $string Phone number string
 * @return (array) areaCode, exchange, suffix and extension
 */
public function reverseTransform($string)
{
    if (!$string || strlen($string) == 0) {
        return null;
    }

    // Split phone number into array for areaCode, exchange, suffix, and extension
    $pattern = '/(\d{3})?-?(\d{3})?-?(\d{4})?( x(\d+))?/';
    preg_match_all($pattern, $string, $matches, PREG_PATTERN_ORDER);

    $phone_data = array('AreaCode'=>null, 'Exchange'=>null, 'Suffix'=>null, 'Extension'=>null);

    $counter = 1;
    foreach($phone_data as $key => $value) {
        if($counter == 4)
            $counter = 5;

        if(isset($matches[$counter][0]) && $matches[$counter][0] !== '') {
            $phone_data[$key] = $matches[$counter][0];
        } else {
            $phone_data[$key] = null;
        }
        $counter++;
    }

    return $phone_data;
}
于 2013-01-09T15:00:05.917 に答える