0

我为每个联系人(姓名、电子邮件)实体收集了电话号码实体。PhoneNumber 分为区号、交换机、后缀、分机,然后是类型选择器(工作、家庭、移动)。我想使用 DataTransformer 以便数字可以显示在单个表单字段中,而不是 4 个不同的文本框中。电话号码在数据库中不是唯一的。

更新:从字符串版本转换回实体时,如何访问完整实体?我之前遇到过这个问题,最终将实体的 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);
}

电话号码转字符串转换器:

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 回答