如何在表单类型中更改实体类?

时间:2016-09-12 09:17:30

标签: php symfony symfony-forms

我有几乎相同的树实体类:A,B,C(它们都通过Doctrine类表继承扩展了一个超类)。

我有一个表单允许通过ChoiceType选择合适的实体类。事实上,我需要在实体创建时通过表单更改实体类(当它没有被持久化时)

我无法弄清楚如何创建将要处理的控制器操作:

  • 创建新的A / B / C实体
  • 更改实体类(当我更改类字段时 - 表单将提交)
  • 坚持实体

更新 我更新了描述并找到了解决方案(见下)

3 个答案:

答案 0 :(得分:1)

我认为你可以轻松使用DataTransformer来做到这一点。

请参阅http://symfony.com/doc/current/form/data_transformers.html了解如何对其进行记录。

您可以使用选择内容来选择您需要创建的课程。

答案 1 :(得分:1)

多种方式去。因为我的信息很少,所以有一些选择:

在表单级别:

为您的所有实体添加表单类型。添加一个选项以配置data_class的{​​{1}}:

ChoiceType

现在在生成表单字段时使用它:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setRequired(['entity_class']);
}

在数据库级别:

查看Doctrine处理Single Map Inheritance的方式。它使您能够创建$form->add( 'entity', ChoiceType.class, ['data_class' => $options['entity_class']] ) 并从中扩展实体BaseEntityAB。现在,您只需添加C(或ChoiceType即可)并选择EntityType作为实体。

然后,表单将显示一个字段中的所有实体。

答案 2 :(得分:0)

所以,解决方案就是这样。也许有人会发现它很有用

<强> MySuperClassType.php

   $domain='stackoverflow.com';  
   $protocol='http://';  
   $orgin=$protocol.$domain.'/';
   $url='http://stackoverflow.com';

   $param=array('action'=>'like','app_id'=>'','channel'=>'http://staticxx.facebook.com/connect/xd_arbiter/r/lUqP5iIjiw6.js?version=42#cb=f178d9075b06a6a',
   'domain'=>$domain,'orgin'=>$orgin,'relation'=>'parent.parent','container_width'=>0,'href'=>$url,'layout'=>'button_count','locale'=>'en_GB','sdk'=>'joey',
   'share'=>false,'show_faces'=>true,'size'=>'large');

   $fb_url='https://www.facebook.com/v2.6/plugins/like.php?';

   $ch= curl_init();
   $options=array( 
   CURLOPT_URL => $fb_url.http_build_query($param),
   CURLOPT_FRESH_CONNECT => 1,
   CURLOPT_RETURNTRANSFER => 1, 
   CURLOPT_FORBID_REUSE =>1,
   CURLOPT_USERAGENT => "Mozilla/4.0 (compatible; MSIE 5.01;Windows NT 5.0)",
   CURLOPT_SSL_VERIFYHOST=> 0,
   CURLOPT_SSL_VERIFYPEER=> 0, 
   CURLOPT_REFERER=>$orgin,
   CURLOPT_CONNECTTIMEOUT=> 10,
   CURLOPT_TIMEOUT=>40
  );

  curl_setopt_array($ch,$options);
  $fb_html=curl_exec($ch);

  if(curl_errno($ch)>0){ #checks any curl error
   $fbc='';
  }else{ 
   $fb_html=preg_replace('/\s+/', '',$fb_html);
   preg_match('/<span[^>]*id="u_0_3">(.*?)<\/span>/sm',$fb_html,$count);
   $fbc=$count[1];  
  }

  curl_close($ch);
  echo "Like count:$fbc";

<强> MySuperClassController.php

protected function getAvailableEntityTypes()
{
    $availableTypes = array();

    // here i get all subclasses of MySuperClass to fill em in choice form

    foreach ($this->em->getMetadataFactory()->getAllMetadata() as $classMetadata) {
        if (is_subclass_of($classMetadata->getName(), MySuperClass::class)) {
            $availableTypes[$classMetadata->getName()] = EntityLabelBuilder::getEntityLabelTranslationKey(
                $classMetadata->getName()
            );
        }
    }

    return $availableTypes;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // here i add choice field with all available entity classes

    $builder
        ->add(
            'entityClass',
            ChoiceType::class,
            [
                'mapped' => false,
                'choices' => $this->getAvailableEntityTypes(),
            ]
        );

}