2016-08-18 7 views
0

私は購入のアイデアを基に作成したフォームを持っています。購入アイテム、支払金額、支払いタイプ(VISA、Mastercard、Cash)があります。私は2つの購入アイテムがプリロードされたフォームを持っていますが、ユーザーがカード決済タイプ(VISAまたはマスターカード)タイプを選択した場合、追加の購入アイテムを追加しようとしています。 この追加購入アイテム私はコントローラ経由で追加しようとしています。ページ提出後にSymfony2フォームコレクションタイプに追加項目を追加する

Rendered Form view

質問は、どこ私はコントローラのアクションでこの機能を実装するのです本当にある...それとも、より良いフォームタイプのイベントリスナーとしてのですか?フォームが追加のカード手数料購買アイテムで提出される

私は次のエラーを取得する...

Catchable Fatal Error: Argument 1 passed to Aazp\BookingBundle\Entity\PurchaseItem::__construct() must be an instance of Aazp\BookingBundle\Entity\Product, none given, called in /project/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/FormType.php on line 141 and defined in /project/src/Aazp/BookingBundle/Entity/PurchaseItem.php line 20

BookingController

namespace Aazp\BookingBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Aazp\BookingBundle\Entity\Booking; 
use Aazp\BookingBundle\Entity\Passenger; 
use Aazp\BookingBundle\Entity\Payment; 
use Aazp\BookingBundle\Entity\Purchase; 
use Aazp\BookingBundle\Entity\PurchaseItem; 

use Aazp\BookingBundle\Form\PurchaseItemType; 
use Aazp\BookingBundle\Form\PurchaseType; 

use Doctrine\Common\Collections\ArrayCollection; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 

class BookingController extends Controller 
{ 

    public function passengerPaymentAction($passenger_id) 
    { 
     $request = Request::createFromGlobals(); 
     $purchaseBalance = 0.0; 

     //Query the selected Passenger 
     $em = $this->getDoctrine()->getManager(); 
     $passenger = $request->attributes->get('passenger', $em->getRepository('AazpBookingBundle:Passenger')->find($passenger_id)); 
     if (!$passenger) { 
      throw $this->createNotFoundException('Unable to find Passenger entity.'); 
     } 

     $purchase = $passenger->getPurchase(); 
     //Has this Passenger made a Payment. If yes then Purchase exists. 
     if($purchase === NULL) //If Purchase does not exist then preload the form with default products. 
     { 
      $purchase = new Purchase(); 

      $product_category_photo = $em->getRepository('AazpBookingBundle:ProductCategory')->findOneByName('FLIGHT-PHOTO'); 

      $product_photo_option = $em->getRepository('AazpBookingBundle:Product')->findOneByProductCategory($product_category_photo); 
      if (!$product_photo_option) { 
       throw $this->createNotFoundException('Unable to find Flight Photo Product entity.'); 
      } 

      $purchase_item_flight = new PurchaseItem($passenger->getFlight()); 
      $purchase_item_photo_option = new PurchaseItem($product_photo_option); 

      //Add Purchase Items to the Purchase 
      $purchase->addPurchaseItem($purchase_item_flight); 
      $purchase->addPurchaseItem($purchase_item_photo_option); 

      //Set the Purchase on the Passenger 
      $passenger->setPurchase($purchase); 
     } 
     //Ajax call triggered by onChange event on PaymentType radio button in form 
     //Add additional Purchase Item for Card Type Payment 
     if($form->get('paymentType')->getData()->getId() > 1) 
     { 
      //PaymentType selected/modified then calculate Payment Fee 
      $product_category_card_fee = $em->getRepository('AazpBookingBundle:ProductCategory')->findOneByName('CARD-FEE'); 
      $product_card_fee = $em->getRepository('AazpBookingBundle:Product')->findOneByProductCategory($product_category_card_fee); 
      if (!$productcard_fee) { 
      throw $this->createNotFoundException('Unable to find Card Fee Product entity.'); 
      } 

      $purchase_item_card_fee = new PurchaseItem($product_card_fee); 

      //Add Purchase Items to the Purchase 
      $purchase->addPurchaseItem($purchase_item_card_fee); 

      $passenger->setPurchase($purchase); 

      return $this->render('AazpBookingBundle:Purchase:summary.html.twig', array(
       'passenger' => $passenger, 
       'form' => $form->createView(), 
      )); 
     } 

     $form = $this->createForm(new PurchaseType($em), $purchase); 

     $form->handleRequest($request); 

     //If form is Valid create Payment and persist. 
     if ($form->isValid()) 
     { 
      $payment = new Payment(); 
      $payment->setAmount($form->get('paymentAmount')->getData()); 
      $payment->setPaymentType($form->get('paymentType')->getData()); 
      $payment->setDescription($form->get('description')->getData()); 

      $passenger->getPurchase()->addPayment($payment); 
      $passenger->getBooking()->setStatus(Booking::STATUS_CONFIRMED); 

      $em->persist($passenger->getPurchase()); 
      $em->flush(); 
      $this->get('session')->getFlashBag()->add('message', 'Payment '.$payment->getAmount().' CHF has been successful!'); 

      return $this->redirect($this->generateUrl('booking_show', array ('id'=> $passenger->getBooking()->getId()))); 
     } 

     return $this->render('AazpBookingBundle:Purchase:summary.html.twig', array(
      'passenger' => $passenger, 
      'form' => $form->createView(), 
     )); 
    } 
} 

PurchaseItemType

namespace Aazp\BookingBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Aazp\BookingBundle\Entity\ProductRepository; 

class PurchaseItemType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('product', 'entity', array('label' => 'Flight', 'class' => 'AazpBookingBundle:Product','property' => 'name', 'empty_value' => 'Please Select', 'required' => false,)); 
     $builder->add('amount', 'number', array('precision' => 2)); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array('data_class' => 'Aazp\BookingBundle\Entity\PurchaseItem',)); 
    } 

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

購入タイプ

namespace Aazp\BookingBundle\Form; 

use Doctrine\ORM\EntityManager; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 

use Aazp\BookingBundle\Entity\PurchaseItem; 

class PurchaseType extends AbstractType 
{ 
    protected $em; 

    function __construct(EntityManager $em) 
    { 
     $this->em = $em; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('purchaseItems', 'collection', array('type' => new PurchaseItemType(), 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false)); 
     $builder->add('paymentType', 'entity', array('label' => 'Payment Type', 'class' => 'AazpBookingBundle:PaymentType','property' => 'name', 'mapped' => false, 'expanded' => true)); 
     $builder->add('paymentAmount', 'number', array('precision' => 2, 'data' => 0.0, 'mapped' => false)); 
     $builder->add('description', 'text', array('mapped' => false, 'required' => false)); 
     $builder->add('cancel', 'submit', array('attr' => array('formnovalidate' => true, 'data-toggle' => 'modal', 'data-target' => '#cancelWarning',))); 
    $builder->add('pay', 'submit'); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array('data_class' => 'Aazp\BookingBundle\Entity\Purchase',)); 
    } 

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

購入エンティティ

<?php 
namespace Aazp\BookingBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Gedmo\Mapping\Annotation as Gedmo; 
use Symfony\Component\Validator\Constraints as Assert; 

use Aazp\MainBundle\Entity\BaseEntity; 

/** 
* @ORM\Entity(repositoryClass="Aazp\BookingBundle\Entity\PurchaseRepository") 
* @ORM\Table(name="purchase") 
* @Gedmo\SoftDeleteable(fieldName="deleted") 
*/ 
class Purchase extends BaseEntity 
{ 
    /** 
    * Constructor 
    */ 
    public function __construct() 
    { 
     $this->purchaseItems = new \Doctrine\Common\Collections\ArrayCollection(); 
     $this->payments = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\ManyToMany(targetEntity="PurchaseItem", cascade={"all"}) 
    * @ORM\JoinTable(name="purchase_purchase_items", 
    *  joinColumns={@ORM\JoinColumn(name="purchase_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="purchase_item_id", referencedColumnName="id", unique=true)} 
    *  ) 
    **/ 
    protected $purchaseItems; 

    /** 
    * @ORM\ManyToMany(targetEntity="Payment", inversedBy="purchases", cascade={"all"}) 
    * @ORM\JoinTable(name="purchases_payments", 
    *  joinColumns={@ORM\JoinColumn(name="purchase_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="payment_id", referencedColumnName="id")} 
    *  ) 
    **/ 
    protected $payments; 

    /** 
    * @ORM\OneToOne(targetEntity="Passenger", mappedBy="purchase") 
    **/ 
    protected $passenger; 


    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Add purchaseItems 
    * 
    * @param \Aazp\BookingBundle\Entity\PurchaseItem $purchaseItems 
    * @return Purchase 
    */ 
    public function addPurchaseItem(\Aazp\BookingBundle\Entity\PurchaseItem $purchaseItems) 
    { 
     $this->purchaseItems[] = $purchaseItems; 

     return $this; 
    } 

    /** 
    * Remove purchaseItems 
    * 
    * @param \Aazp\BookingBundle\Entity\PurchaseItem $purchaseItems 
    */ 
    public function removePurchaseItem(\Aazp\BookingBundle\Entity\PurchaseItem $purchaseItems) 
    { 
     $this->purchaseItems->removeElement($purchaseItems); 
    } 

    /** 
    * Get purchaseItems 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getPurchaseItems() 
    { 
     return $this->purchaseItems; 
    } 

    /** 
    * Add payments 
    * 
    * @param \Aazp\BookingBundle\Entity\Payment $payments 
    * @return Purchase 
    */ 
    public function addPayment(\Aazp\BookingBundle\Entity\Payment $payments) 
    { 
     $this->payments[] = $payments; 

     return $this; 
    } 

    /** 
    * Remove payments 
    * 
    * @param \Aazp\BookingBundle\Entity\Payment $payments 
    */ 
    public function removePayment(\Aazp\BookingBundle\Entity\Payment $payments) 
    { 
     $this->payments->removeElement($payments); 
    } 

    /** 
    * Get payments 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getPayments() 
    { 
     return $this->payments; 
    } 

    /** 
    * Set passenger 
    * 
    * @param \Aazp\BookingBundle\Entity\Passenger $passenger 
    * @return Purchase 
    */ 
    public function setPassenger(\Aazp\BookingBundle\Entity\Passenger $passenger = null) 
    { 
     $this->passenger = $passenger; 

     return $this; 
    } 

    /** 
    * Get passenger 
    * 
    * @return \Aazp\BookingBundle\Entity\Passenger 
    */ 
    public function getPassenger() 
    { 
     return $this->passenger; 
    } 
} 
+0

PurchaseItem.phpが表示されませんか? – Fiemhong

答えて

0

デフォルトdata_classオプションは引数なしでそのコンストラクタを呼び出すため、これが起こりました。あなたのクラスAazp\Booking Bundle\Entity\PurchaseItemは、コンストラクタのパラメータを持っている、あなたはインスタンス化するempty_dataオプションを使用する必要がある場合:

// Aazp\BookingBundle\Form\PurchaseItemType.php 

$resolver->setDefaults([ 
    'empty_data' => function (FormInterface $form) { 
     return new PurchaseItem($form->get('product')->getData()); 
    }, 
]); 

このオプションhereについてもっと傾くことができます。

+0

このような多くの感謝を見ていないYonel。 例外は、フォームの最初のプリロードの後に​​作成された購入アイテムプロキシエンティティまたは新しいエンティティを指していたと考えました。私は、彼らが例外に応じて関連商品を持っていなかったと信じていました。 これで私の問題の最初の部分が修正され、残りの部分を修正することができました。今私は実装するだけのシンプルなロジックだと思っています。 再び多くの感謝Yonelあなたは私をもう一度前進させました。 (y) – tmschneider

関連する問題