我有一个控制器,可以使用变量类名为用户提供正确的表单类型。
有一个名为 EntityForm 的实体,它存储所有可用表单的数据,并提供给出类名和表单类型名称的方法:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="entity_form")
*/
class EntityForm
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var string
*
* @ORM\Column(length=12)
*/
protected $url;
/**
* @var string
*
* @ORM\Column
*/
protected $name;
/**
* @var string
*
* @ORM\Column(name="class_name")
*/
protected $className;
/**
* @var string
*
* @ORM\Column(name="description")
*/
protected $description;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set url
*
* @param string $url
*
* @return Form
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* Get url
*
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Set name
*
* @param string $name
*
* @return Form
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set className
*
* @param string $className
*
* @return Form
*/
public function setClassName($className)
{
$this->className = $className;
return $this;
}
/**
* Get className
*
* @return string
*/
public function getClassName()
{
return $this->className;
}
public function createEntity()
{
$entity = sprintf('%s\%s', __NAMESPACE__, $this->getClassName());
return new $entity;
}
public function createType()
{
return sprintf('AppBundle\Form\%sType', $this->getClassName());
}
/**
* Set description
*
* @param string $description
*
* @return Form
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
}
创建正确表单的操作修改如下:
/**
* @Route("/form/ent/{url}", name="entity_form")
* @Method("GET")
*/
public function formAction(EntityForm $entityForm)
{
$form = $this->createForm($entityForm->createType())
->add('Dodaj!', SubmitType::class, array(
'attr' => array(
'class' => 'btn-info'
)
))
;
return $this->render('default/form.html.twig', [
'form_name' => $entityForm->getName(),
'form_description' => $entityForm->getDescription(),
'form' => $form->createView(),
]);
}
此控制器链接到正确的表单类型,即。对于 cyclicNewsletter
class CyclicNewsletterType extends AbstractType
{
private $doctrine;
public function __construct($doctrine)
{
$this->doctrine = $doctrine;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$currencies = $this->doctrine->getRepository('AppBundle:Currency')->findAll();
$currenciesFormat = array();
foreach($currencies as $currency){
$currenciesFormat += array($currency->getName() .' ('. $currency->getShortName() . ')' => $currency);
}
$cycles = $this->doctrine->getRepository('AppBundle:Cycle')->findAll();
$cyclesFormat = array();
foreach($cycles as $cycle){
$cyclesFormat += array($cycle->getName() => $cycle);
}
$builder
->add('currency', ChoiceType::class, array(
'label' => 'Waluta',
'choices' => $currenciesFormat,
))
->add('cycle', ChoiceType::class, array(
'label' => 'Cykl',
'choices' => $cyclesFormat,
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => CyclicNewsletter::class,
));
}
}
现在通过简单的POST操作,我可以轻松地向数据库添加新值,而无需为所有表单编写单独的操作:
/**
* @Route("/form/ent/{url}", name="form_entity_post")
* @Method("POST")
*
*/
public function formPostAction(EntityForm $entityForm, Request $request)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm($entityForm->createType())
->add('Dodaj!', SubmitType::class)
;
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$formData = $form->getData();
$formData->setUser($this->container->get('security.token_storage')->getToken()->getUser());
$em->persist($formData);
$em->flush();
return $this->redirectToRoute('form_complete', ['url' => $entityForm->getUrl(), 'entityId' => $formData->getId()]);
}
var_dump('problem ' . $form->getErrors());
exit;
}
我似乎无法使用该方法将已创建的对象注入表单构建器进行编辑。
我的意思是用一个变量类名来创建一个表单创建,它也会存储一个实体实例,这些值已经在表单中设置了。
symfony可以这样吗?
答案 0 :(得分:1)
您需要将正在编辑的实体的ID添加到您的网址中,并将其设为可选。
* @Route("/form/ent/{url}/{id}", name="form_entity_post", defaults={"id" = null})
在您的控制器中,在构建表单时,您需要从数据库中获取该对象,并将其作为第二个参数传递给createForm方法。
/**
* @Route("/form/ent/{url}/{id}", name="form_entity_post", defaults={"id" = null})
* @Method("POST")
*
*/
public function formPostAction(EntityForm $entityForm, Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = null;
if ($id) {
$entity = $em->getRepository($entityForm->getClassName)->find($id);
}
$form = $this->createForm($entityForm->createType(), $entity)
->add('Dodaj!', SubmitType::class)
;