Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 具有额外字段的N:M关系的表单版本不起作用_Php_Symfony_Doctrine Orm_Symfony Forms_Symfony 2.5 - Fatal编程技术网

Php 具有额外字段的N:M关系的表单版本不起作用

Php 具有额外字段的N:M关系的表单版本不起作用,php,symfony,doctrine-orm,symfony-forms,symfony-2.5,Php,Symfony,Doctrine Orm,Symfony Forms,Symfony 2.5,我正在处理一个表单,该表单使用一个额外的参数(额外的字段/列)处理N:m关系。这就是我到目前为止所做的: 在ordersype.php表单中: class OrdersType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { // $builder fields // $builder fields

我正在处理一个表单,该表单使用一个额外的参数(额外的字段/列)处理N:m关系。这就是我到目前为止所做的:

ordersype.php
表单中:

class OrdersType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // $builder fields

        // $builder fields only need on edit form not in create
        if ($options['curr_action'] !== NULL)
        {
            $builder
                    // other $builder fields
                    ->add("orderProducts", "collection", array(
                        'type' => new OrdersHasProductType(),
                        'allow_add' => true,
                        'allow_delete' => true,
                        'by_reference' => false
            ));
        }
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Tanane\FrontendBundle\Entity\Orders',
            'render_fieldset' => FALSE,
            'show_legend' => FALSE,
            'intention' => 'orders_form',
            'curr_action' => NULL
        ));
    }

    public function getName()
    {
        return 'orders';
    }

}
OrderHasProductType.php
中:

class OrdersHasProductType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
                ->add('product', 'text', array(
                    'required' => FALSE,
                    'label' => FALSE
                ))
                ->add('amount', 'text', array(
                    'required' => TRUE,
                    'label' => FALSE
        ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Tanane\FrontendBundle\Entity\OrderHasProduct',
            'intention' => 'order_has_product'
        ));
    }

    public function getName()
    {
        return 'order_has_product';
    }

}
最后是
Orders.php
OrdersHasProduct.php
实体:

class Orders {
    use IdentifiedAutogeneratedEntityTrait;
    // rest of fields for the entity 

    /**
     * @ORM\OneToMany(targetEntity="OrderHasProduct", mappedBy="order", cascade={"all"}) 
     */
    protected $orderProducts;

    protected $products;

    /**
     * @ORM\Column(name="deletedAt", type="datetime", nullable=true)
     */
    protected $deletedAt;

    public function __construct()
    {
        $this->orderProducts = new ArrayCollection();
        $this->products = new ArrayCollection();
    }

    public function getOrderProducts()
    {
        return $this->orderProducts;
    }

    public function getDeletedAt()
    {
        return $this->deletedAt;
    }

    public function setDeletedAt($deletedAt)
    {
        $this->deletedAt = $deletedAt;
    }

    public function getProduct()
    {
        $products = new ArrayCollection();

        foreach ($this->orderProducts as $op)
        {
            $products[] = $op->getProduct();
        }

        return $products;
    }

    public function setProduct($products)
    {
        foreach ($products as $p)
        {
            $ohp = new OrderHasProduct();
            $ohp->setOrder($this);
            $ohp->setProduct($p);

            $this->addPo($ohp);
        }
    }

    public function getOrder()
    {
        return $this;
    }

    public function addPo($ProductOrder)
    {
        $this->orderProducts[] = $ProductOrder;
    }

    public function removePo($ProductOrder)
    {
        return $this->orderProducts->removeElement($ProductOrder);
    }

}

/**
 * @ORM\Entity
 * @ORM\Table(name="order_has_product")
 * @Gedmo\SoftDeleteable(fieldName="deletedAt")
 * @UniqueEntity(fields={"order", "product"})
 */
class OrderHasProduct {
    use IdentifiedAutogeneratedEntityTrait;

    /**
     * Hook timestampable behavior
     * updates createdAt, updatedAt fields
     */
    use TimestampableEntity;

    /**
     * @ORM\ManyToOne(targetEntity="\Tanane\FrontendBundle\Entity\Orders", inversedBy="orderProducts")
     * @ORM\JoinColumn(name="general_orders_id", referencedColumnName="id")
     */
    protected $order;

    /**
     * @ORM\ManyToOne(targetEntity="\Tanane\ProductBundle\Entity\Product", inversedBy="orderProducts")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     */
    protected $product;

    /**
     * @ORM\Column(type="integer", nullable=false)
     */
    protected $amount;

    /**
     * @ORM\Column(name="deletedAt", type="datetime", nullable=true)
     */
    protected $deletedAt;

    public function setOrder(\Tanane\FrontendBundle\Entity\Orders $order)
    {
        $this->order = $order;
    }

    public function getOrder()
    {
        return $this->order;
    }

    public function setProduct(\Tanane\ProductBundle\Entity\Product $product)
    {
        $this->product = $product;
    }

    public function getProduct()
    {
        return $this->product;
    }

    public function setAmount($amount)
    {
        $this->amount = $amount;
    }

    public function getAmount()
    {
        return $this->amount;
    }

    public function getDeletedAt()
    {
        return $this->deletedAt;
    }

    public function setDeletedAt($deletedAt)
    {
        $this->deletedAt = $deletedAt;
    }

}
但当我尝试在控制器中使用以下代码编辑订单时:

public function editAction(Request $request, $id)
{
    $em = $this->getDoctrine()->getManager();
    $order = $em->getRepository('FrontendBundle:Orders')->find($id);
    $type = $order->getPerson()->getPersonType() === 1 ? "natural" : "legal";

    $params = explode('::', $request->attributes->get('_controller'));
    $actionName = substr($params[1], 0, -6);

    $orderForm = $this->createForm(new OrdersType(), $order, array('action' => '#', 'method' => 'POST', 'register_type' => $type, 'curr_action' => $actionName));

    return array(
        "form" => $orderForm->createView(),
        'id' => $id,
        'entity' => $order
    );
}
我得到这个错误:

表单的视图数据应为标量、数组或 \ArrayAccess的实例,但是类的实例 代理\uuuu CG\uuuu\Tanane\ProductBundle\Entity\Product。你可以避免这种情况 将“data_class”选项设置为时出错 “代理\uuuu CG\uuuu\Tanane\ProductBundle\Entity\Product”或通过添加 视图转换器,用于转换类的实例 代理\uuuu CG\uuuu\Tanane\ProductBundle\Entity\Product到标量、数组或 \ArrayAccess的实例


我找不到或不知道如何修复它,有人能给我一些帮助吗?

我想这是因为代码

class OrdersHasProductType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
                ->add('product', 'text', array(
                    'required' => FALSE,
                    'label' => FALSE
                ))
        ));
    }
    //...
}
这意味着Symfony希望“product”是“text”类型的字段,但当它在OrderHasProduct上调用
getProduct()
时,它会得到一个产品对象(或一个产品的原则代理,因为此时尚未加载)。Symfony字段继承自Form/AbstractType,因此它们本质上是表单本身,只有一个字段,因此会出现错误消息


解决方案是将该字段设置为“entity”类型,或者创建一个只给出产品名称的不同方法,例如OrderHasProduct上的
getProductName()
,然后将其用作字段后面的数据。

Hi@frumious,感谢您在这里留下的所有回复(这一个和您回答的另外两个)。我之所以使用
text
而不是
entity
是因为我使用的是Select2组件,它通过AJAX调用从DB获取产品,如果我使用
entity
类型,我不希望Symfony呈现典型的select组件,如果你知道这方面的任何解决方案,那么是的,我可以使用
实体
,没有问题。你能用它来获得你想要的输出吗?嗯,我不确定
属性是否有帮助,你对此有什么想法吗?可能没有。。。您需要传递给Select2的具体内容是什么?你能给出一个呈现HTML的例子吗?它是在线的,看看这个字符串“Ofertas realizadas a facturar”,在那里你会看到我在说什么(很抱歉是西班牙语翻译),如果你有任何疑问,请再次告诉我我在这里