2012-10-25 67 views
0

我爲每個聯繫人(姓名,電子郵件)實體收集了PhoneNumber實體。 PhoneNumber被分解成區號,交換,後綴,擴展名,然後是一個類型選擇器(Work,Home,Mobile)。我想使用DataTransformer,以便數字可以顯示在單個表單字段中,而不是4個不同的文本框。電話號碼在數據庫中不是唯一的。Symfony2 DataTransformers - 如何在沒有ID或唯一值的情況下轉換回來?

已更新:如何在從字符串版本轉換回實體時訪問完整實體?我以前遇到過這個問題,並最終將實體的ID放在文本字段中的括號內,然後將它們在變換中重新排列,以便我可以執行查詢來獲取實體。

phonenumber_combined是引用我的PhoneNumberCombinedType類的自定義表單類型服務。

我對手機的聯繫人中集合添加方法:

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

回答

0

對不起,沒有更新,但我已經找到一個體面的解決這一問題。我在PhoneNumber實體中添加了一個setPhone方法,該方法似乎在反向變換後自動調用。在我的變壓器中,我添加了一個正則表達式來將我的電話號碼分成相應的部分,然後將每個部分添加到一個數組中。該數組由變換器返回,然後由setPhone用於更新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; 
} 
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; 
    } 
} 
相關問題