从数组集

时间:2016-09-16 12:19:51

标签: php symfony oop doctrine-orm symfony-forms

尝试使用symfonydoctrine创建一个简单的网上商店。问题是:我不知道如何创建订单表单,该表单应该能够选择/设置每个产品的数量。我想我需要3个实体产品,订单和OrderPosition。

产品有价格和标题。订单知道哪个用户订单以及何时但在这种情况下相关的订单具有OrderPositions且OrderPositions具有属性数量。因此,OrderPosition知道已经订购了多少次产品。

我不确定这些实体的映射/关系是否正确所以我会在这里显示:

产品:

class Product
{
    private $id;
    private $price;
    private $title;
    private $orderPositions;

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

    public function getId()
    {
        return $this->id;
    }

    public function setPrice($price)
    {
        $this->price = $price;

        return $this;
    }

    public function getPrice()
    {
        return $this->price;
    }

    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

    public function getTitle()
    {
        return $this->title;
    }

    public function getOrderPositions()
    {
        return $this->orderPositions;
    }

    public function addOrderPosition(OrderPosition $orderPosition)
    {
        $this->orderPositions[] = $orderPosition;
        if ($orderPosition->getProduct() !== $this) {
            $orderPosition->setProduct($this);
        }
        return $this;
    }
}

订单:

class Order
{
    private $id;
    private $orderPositions;

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

    public function getId()
    {
        return $this->id;
    }

    public function getOrderPositions()
    {
        return $this->orderPositions;
    }

    public function addOrderPosition(OrderPosition $orderPosition)
    {
        $this->orderPositions[] = $orderPosition;
        if ($orderPosition->getOrder() !== $this) {
            $orderPosition->setOrder($this);
        }
        return $this;
    }
}

OderPosition:

class OrderPosition
{
    private $id;
    private $quantity;
    private $order;
    private $product;

    public function getId()
    {
        return $this->id;
    }

    public function getQuantity()
    {
        return $this->quantity;
    }

    public function setQuantity($quantity)
    {
        $this->quantity = $quantity;
    }

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

    public function setOrder(Order $order)
    {
        $this->order = $order;
        if ($order->getOrderPositions() !== $this) {
            $order->addOrderPosition($this);
        }
        return $this;
    }

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

    public function setProduct(Product $product)
    {
        $this->product = $product;
        if ($product->getOrderPositions() !== $this) {
            $product->addOrderPosition($this);
        }
        return $this;
    }
}

映射文件:

产品:

MyBundle\Entity\Product:
    type: entity
    table: product
    repositoryClass: MyBundle\Repository\ProductRepository
    oneToMany:
        orderPositions:
            targetEntity: OrderPosition
            mappedBy: product
            cascade: [ "persist" ]
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        price:
            type: float
        title:
            type: string
            length: 255
            column: title

    lifecycleCallbacks: {  }

订单:

MyBundle\Entity\Order:
    repositoryClass: MyBundle\Repository\OrderRepository
    type: entity
    table: order
    oneToMany:
        orderPositions:
            targetEntity: OrderPosition
            mappedBy: order
            cascade: [ "persist" ]
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO

    lifecycleCallbacks: {  }

OrderPosition:

MyBundle\Entity\OrderPosition:
    repositoryClass: MyBundle\Repository\OrderPositionRepository
    type: entity
    table: order_position
    manyToOne:
        order:
            targetEntity: Order
            inversedBy: orderPositions
            joinColumn:
                name: order_id
                referencedColumnName: id
        product:
            targetEntity: Product
            inversedBy: orderPositions
            joinColumn:
                name: product_id
                referencedColumnName: id
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        quantity:
            type: integer
    lifecycleCallbacks: {  }

应该创建表单的控制器如下所示:

$order = new Order();

$form = $this->createFormBuilder($order)
        ->add('quantity', OrderPositionType::class)
        ->add('save', SubmitType::class, array('label' => 'Order'))
        ->getForm();

并持续使用OrderPositionType

class OrderPositionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('quantity', IntegerType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MyBundle\Entity\OrderPosition'
        ));
    }
}

现在,问题是:如何获取订单表单为每个产品创建quantity输入字段?

1 个答案:

答案 0 :(得分:2)

您可以定义如下类型:

<强> OrderPositionType:

class OrderPositionType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('quantity');
    }
}

<强>订单类型

class OrderType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('orderPositions', CollectionType::class, [
            'entry_type' => OrderPositionType::class,
            'allow_add' => false,
        ]);

        // Other fields then...
    }
}

和您的控制人员:

    // $products = list of products user has selected. You already have it
    $order = new Order();

    foreach ($products as $product) {
        $orderPosition = new OrderPosition($order);
        $orderPosition->setProduct($product);
        $orderPosition->setQuantity(1); // default quantity, just my guess
    }

    $form = $this->createForm(OrderType::class, $order);