2016-09-16 3 views
0

symfonydoctrine으로 간단한 웹 쇼핑몰을 만들려고합니다. 문제는 : 각 제품의 수량을 선택/설정해야하는 주문 양식을 작성하는 방법을 모르겠습니다. 3 Entities Product, Order 및 OrderPosition이 필요하다고 생각합니다.배열 컬렉션에서 개체를 기반으로 양식 만들기

여기서 제품 가격과 제목이 있습니다. Order는 어떤 사용자가 Order를 만들었는지 알고 있으며,이 경우 관련이있는 Order는 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 입력 필드를 만들 수있는 주문 양식을받을 수 있나요?

답변

2

는이 같은 유형을 정의 :

OrderPositionType :

class OrderPositionType extends AbstractType { 

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

OrderType :

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); 
+1

+1 내 오랜 질문을 읽었기 때문에 +1 .. 감사합니다. 지금 당장 시도 할 것입니다. – caramba

+0

OrderPositionType에 대해 별도의 위젯이 필요할 것입니다. 지금은 수량을 설정하고 위치를 삭제하는 것이 가능하기 때문에 제품에 대한 정보 만 표시하면됩니다. 이 문제에 도움이 필요하면 –

+0

Dmitry에게 감사하십시오! 문제는 마지막 줄'..buildForm..'입니다. 왜냐하면 buildForm은 정의되지 않은 메소드입니다.'..createFormBuilder ..'로 변경하면 "catch 가능한 치명적 오류가 발생합니다 : 인수 2가 createFormBuilder()에 전달되었지만 배열이어야하지만 객체가 있어야합니다.".. 도울 수 있습니까? – caramba