开始使用symfony2。我喜欢它,到目前为止。如果表单构建器可用于我的需要,我尝试在多实体表单上找出答案。 首先,我的实体:
客户实体
namespace CustomerBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Mapping as ORM;
use UserBundle\Entity\Users;
/**
* @ORM\Table(name="customers")
* @ORM\HasLifecycleCallbacks
* @ORM\Entity(repositoryClass="CustomerBundle\Entity\CustomerRepository")
*/
class Customer
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $Id;
/**
* @ORM\Column(name="nickname", type="string", length=50, unique=true)
*/
protected $NickName;
/**
* @ORM\OneToMany(targetEntity="\CustomerBundle\Entity\Address", mappedBy="Customer")
**/
protected $Addresses;
/**
* @ORM\OneToMany(targetEntity="\CustomerBundle\Entity\Mail", mappedBy="Customer")
**/
protected $Emails;
/**
* @ORM\ManyToMany(targetEntity="\UserBundle\Entity\Users")
* @ORM\JoinTable(name="customers_mapping_users",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="customer_id", referencedColumnName="id")}
* )
**/
protected $Users;
/**
* @ORM\Column(name="lead_type", type="string", length=50, nullable=true)
*/
protected $LeadType;
/**
* @ORM\ManyToOne(targetEntity="\UserBundle\Entity\Users", fetch="EXTRA_LAZY")
* @ORM\JoinColumn(name="lead__owner_user_id", referencedColumnName="id")
*/
protected $LeadOwner;
/**
* @ORM\OneToMany(targetEntity="\CustomerBundle\Entity\Note", mappedBy="Customer")
**/
protected $Notes;
protected $Reminders;
protected $SupportTickets;
protected $Invoices;
protected $Documents;
/**
* @ORM\OneToMany(targetEntity="\CustomerBundle\Entity\Todo", mappedBy="Customer")
**/
protected $Todos;
/**
* @return Todo[]
*/
public function getTodos()
{
return $this->Todos;
}
/**
* @param Todo $todo
*/
public function addTodo(Todo $todo)
{
$this->Todos->add($todo);
}
/**
* @param Todo $todo
*
* @return bool
*/
public function hasTodo(Todo $todo=null)
{
return $this->Todos->contains($todo);
}
/**
* @param Todo $todo
*
* @return $this
*/
public function removeTodo(Todo $todo)
{
$this->Todos->removeElement($todo);
return $this;
}
}
我的地址实体
<?php
namespace CustomerBundle\Entity;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="customers_address")
* @ORM\HasLifecycleCallbacks
* @ORM\Entity(repositoryClass="CustomerBundle\Entity\AddressRepository")
*/
class Address
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $Id;
/**
* @ORM\ManyToOne(targetEntity="CustomerBundle\Entity\Customer", inversedBy="Addresses")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
**/
protected $Customer;
/**
* @ORM\Column(name="first_name", type="string", length=50, nullable=true)
*/
protected $FirstName;
/**
* @ORM\Column(name="last_name", type="string", length=50, nullable=true)
*/
protected $LastName;
/**
* @ORM\Column(name="company_name", type="string", length=50, nullable=true)
*/
protected $CompanyName;
/**
* @ORM\Column(name="street1", type="string", length=250, nullable=true)
*/
protected $Street1;
/**
* @ORM\Column(name="street2", type="string", length=250, nullable=true)
*/
protected $Street2;
/**
* @ORM\Column(name="street3", type="string", length=250, nullable=true)
*/
protected $Street3;
/**
* @ORM\Column(name="zipcode", type="string", length=10, nullable=true)
*/
protected $Zipcode;
/**
* @ORM\Column(name="city", type="string", length=50, nullable=true)
*/
protected $City;
/**
* @ORM\Column(name="country", type="string", length=50, nullable=true)
*/
protected $Country;
/**
* @ORM\Column(name="phone", type="string", length=50, nullable=true)
*/
protected $Phone;
/**
* @ORM\Column(name="fax", type="string", length=50, nullable=true)
*/
protected $Fax;
/**
* @ORM\Column(name="tax_id", type="string", length=50, nullable=true)
*/
protected $TaxId;
}
最后但并非最不重要
namespace CustomerBundle\Entity;
use HomeBundle\Traits\CreateTrait;
use HomeBundle\Traits\serializeTrait;
use HomeBundle\Traits\UpdateTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="customer_mail")
* @ORM\HasLifecycleCallbacks
* @ORM\Entity(repositoryClass="CustomerBundle\Entity\MailRepository")
*/
class Mail
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $Id;
/**
* @ORM\Column(name="email", type="string", length=255, unique=true)
*/
protected $Email;
/**
* @ORM\ManyToOne(targetEntity="CustomerBundle\Entity\Customer", inversedBy="Emails")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
**/
protected $Customer;
}
根据http://symfony.com/doc/current/cookbook/form/form_collections.html我添加了三种表单类型:
地址:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('FirstName','text',array('label'=>'firstname'))
->add('LastName','text',array('label'=>'lastname'))
->add('CompanyName','text',array('label'=>'company name'))
->add('Street1','text',array('label'=>'street 1'))
->add('Street2','text',array('label'=>'street 2'))
->add('Street3','text',array('label'=>'street 3'))
->add('Zipcode','text',array('label'=>'zip code'))
->add('City','text',array('label'=>'city'))
->add('Country','text',array('label'=>'country'))
->add('Phone','text',array('label'=>'phone'))
->add('Fax','text',array('label'=>'fax'))
->add('TaxId','text',array('label'=>'taxid'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomerBundle\Entity\Address',
)
);
}
public function getName()
{
return 'address';
}
}
邮件:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MailType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Email','email',array('label'=>'email'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomerBundle\Entity\Mail',
)
);
}
public function getName()
{
return 'mail';
}
}
和客户作为顶级实例:
<?php
namespace CustomerBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CustomerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('NickName','text',array('label'=>'customers nickname'))
->add('address','collection',array('type'=>new AddressType()))
->add('mail','collection',array('type'=>new MailType()));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomerBundle\Entity\Customer',
)
);
}
public function getName()
{
return 'customer';
}
}
在我的控制器的创建操作中,我添加了这个:
/**
* @Route("/Customers/Create", name="crm_customers_create")
* @Template()
*/
public function createAction()
{
$customer = new Customer();
$address = new Address();
$mail = new Mail();
$customer->addAddress($address);
$customer->addEmail($mail);
$form = $this->createForm(new CustomerType(),$customer);
return array(
'form'=>$form->createView(),
);
}
我的Twig模板包含:
{%extends“HomeBundle:Core:base.html.twig”%}
{% block title %}CustomerBundle:Customers:create{% endblock %}
{% block body %}
<div class="col-xs-10 col-xs-offset-1">
<fieldset>
<legend>{% trans %}create a new Customer{% endtrans %}</legend>
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</fieldset>
</div>
{% endblock %}
所以只要我填饱了一页,我就得到这个输出:
类型为“array or(\ Traversable and \ ArrayAccess)”的预期参数,“boolean”给出 500内部服务器错误 - UnexpectedTypeException 堆栈跟踪
in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php at line 84 -
}
if (!is_array($data) && !($data instanceof \Traversable && $data instanceof \ArrayAccess)) {
throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
}
// First remove all rows
at ResizeFormListener ->preSetData (object(FormEvent), 'form.pre_set_data', object(EventDispatcher))
at call_user_func (array(object(ResizeFormListener), 'preSetData'), object(FormEvent), 'form.pre_set_data', object(EventDispatcher))
in app/cache/dev/classes.php at line 1826 +
at EventDispatcher ->doDispatch (array(array(object(ResizeFormListener), 'preSetData')), 'form.pre_set_data', object(FormEvent))
in app/cache/dev/classes.php at line 1759 +
at EventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
in vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php at line 43 +
at ImmutableEventDispatcher ->dispatch ('form.pre_set_data', object(FormEvent))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 342 +
at Form ->setData (false)
in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php at line 57 +
at PropertyPathMapper ->mapDataToForms (object(Customer), object(RecursiveIteratorIterator))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 396 +
at Form ->setData (object(Customer))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 488 +
at Form ->initialize ()
in vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php at line 226 +
at FormBuilder ->getForm ()
in vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php at line 39 +
at FormFactory ->create (object(CustomerType), object(Customer), array())
in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php at line 250 +
at Controller ->createForm (object(CustomerType), object(Customer))
in src/CustomerBundle/Controller/CustomersController.php at line 47 +
at CustomersController ->createAction ()
at call_user_func_array (array(object(CustomersController), 'createAction'), array())
in app/bootstrap.php.cache at line 3109 +
at HttpKernel ->handleRaw (object(Request), '1')
in app/bootstrap.php.cache at line 3071 +
at HttpKernel ->handle (object(Request), '1', true)
in app/bootstrap.php.cache at line 3222 +
at ContainerAwareHttpKernel ->handle (object(Request), '1', true)
in app/bootstrap.php.cache at line 2444 +
at Kernel ->handle (object(Request))
in web/app_dev.php at line 29 +
我不知道问题来自于我无法看到哪些实体导致故障。 到目前为止,一切看起来都很好 我也试图只访问其中一个表单字段,但是它导致了同样的异常。 我解决了这个问题的任何帮助。