Reputation: 11
Please help me with my project for a shopping cart. I am trying to add products to the basket and get this error while adding a new product: Type error: Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, object given, called in C:\Users\Angel's\Desktop\untitled2\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 605.
Here is my CartController:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Entity\Product;
use AppBundle\Entity\Cart;
use AppBundle\Entity\Shipping;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class CartController extends Controller
{
/**
* @Route("/", name="homepage")
*/
/*public function indexAction(Request $request)
{
// replace this example code with whatever you need
return $this->render('default/index.html.twig', array(
'base_dir' => realpath($this->container->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
));
}*/
/**
* @Route("/cart", name="view_cart")
*/
public function showAction()
{
# Get object from doctrine manager
$em = $this->getDoctrine()->getManager();
# Get logged user then get his ['id']
$user = $this->container->get('security.token_storage')->getToken()->getUser();
/** Check IF user have exist cart **/
# select cart from database where user id equal to cureent logged user using [ findByUser() ]
$user_cart = $this->getDoctrine()
->getRepository('AppBundle:Cart')
->findBy(['user' => $user]);
if ( $user_cart )
{
# Then select all user cart products to display it to user
$user_products = $this->getDoctrine()
->getRepository('AppBundle:Shipping')
->findBy( array('cart' => $user_cart[0]->getId()) );
# pass selected products to the twig page to show them
return $this->render('cart/show.html.twig', array(
'products' => $user_products,
'cart_data' => $user_cart[0],
));
}
//return new Response(''. $user_products[0]->getProduct()->getPrice() );
# pass selected products to the twig page to show them
return $this->render('cart/show.html.twig');
}
/**
* @Route("/cart/addTo/{productId}", name="add_to_cart")
* @param $productId
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function addAction($productId)
{
# First of all check if user logged in or not by using FOSUSERBUNDLE
# authorization_checker
# if user logged in so add the selected product to his cart and redirect user to products page
# else redirect user to login page to login first or create a new account
$securityContext = $this->container->get('security.authorization_checker');
# If user logged in
if ( $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED') )
{
# Get object from doctrine manager
$em = $this->getDoctrine()->getManager();
# Get logged user then get his ['id']
$user = $this->container->get('security.token_storage')->getToken()->getUser();
# for any case wewill need to select product so select it first
# select specific product which have passed id using ['find(passedID)']
$product = $this->getDoctrine()
->getRepository('AppBundle:Product')
->find($productId);
/** Check IF user have exist cart **/
# select cart from database where user id equal to cureent logged user using [ findByUser() ]
$exsit_cart = $this->getDoctrine()
->getRepository('AppBundle:Cart')
->findBy(['user' => $user]);
# if there's no cart to this user create a new one
if ( !$exsit_cart )
{
# defince cart object
$cart = new Cart();
# set user whose own this cart
$cart->setUser($user);
# set initail total price for cart which equal to product price
$cart->setTotalPrice($product->getPrice());
$cart->setQuantity(1);
# persist all cart data to can use it in create shipping object
$em->persist($cart);
# flush it
$em->flush();
# create shipping object
$ship = new Shipping();
# set all its data quantity initail equal to 1 and passed product and cart created
$ship->setQuantity(1);
$ship->setProduct($product);
$ship->setCart($cart);
# persist it and flush doctrine to save it
$em->persist($ship);
$em->flush();
}
# if user have one so just add new item price to cart price and add it to shipping
else
{
# Get cart from retrived object
$cart = $exsit_cart[0];
# set initail total price for cart which equal to product price
$cart->setTotalPrice($cart->getTotalPrice() + $product->getPrice());
# persist all cart data to can use it in create shipping object
$em->persist($cart);
# flush it
$em->flush();
# create shipping object
$ship = new Shipping();
# set all its data quantity initail equal to 1 and passed product and cart created
$ship->setQuantity(1);
$ship->setProduct($product);
$ship->setCart($cart);
# persist it and flush doctrine to save it
$em->persist($ship);
$em->flush();
}
//return new Response('user id '.$product->getId());
return $this->redirect($this->generateUrl('products_index'));
}
# if user not logged in yet
else
{
# go to adding product form
return $this->redirect($this->generateUrl('login'));
}
}
/**
* @Route("/cart/remove/{itemProduct}/{itemCart}", name="remove_item")
*/
public function removeActione($itemProduct, $itemCart)
{
# get an object from doctrine db and get Shipping Entity to work on it
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('AppBundle:Shipping');
# select wanted item from shipping table to delete it
$ship = $repository->findOneBy(array('product' => $itemProduct, 'cart' => $itemCart));
# Calculate the new total price for cart by subtract deleted item price from total one
$final_price = $ship->getCart()->getTotalPrice() - ($ship->getProduct()->getPrice() * $ship->getQuantity());
# update the total price of cart
$ship->getCart()->setTotalPrice($final_price);
# Remove item from db
$em->remove($ship);
$em->flush();
return $this->redirect($this->generateUrl('view_cart'));
}
/**
* @Route("/cart/edit/{itemProduct}/{itemCart}", name="edit item")
*/
public function editActione(Request $request, $itemProduct, $itemCart)
{
# in the start check if user edit field and click on button
if ( $request->getMethod() === 'POST' )
{
# read data from quantity field
$new_quantity =$request->request->get('quantity');
# get oject from doctrine manager to mange operation
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('AppBundle:Shipping');
# select wanted item from shipping table to edit it
$ship = $repository->findOneBy(array('product' => $itemProduct, 'cart' => $itemCart));
# check if new quantity less than old one so subtract total price
# otherwise, add to it
if( $ship->getQuantity() < $new_quantity )
{
# edit selected item quantity
$ship->setQuantity($new_quantity);
# Calculate the new total price for cart by sum added item price to total one
$final_price = $ship->getCart()->getTotalPrice() + $ship->getProduct()->getPrice();
# update the total price of cart
$ship->getCart()->setTotalPrice($final_price);
}
elseif( $ship->getQuantity() > $new_quantity )
{
# edit selected item quantity
$ship->setQuantity($new_quantity);
# Calculate the new total price for cart by sum added item price to total one
$final_price = $ship->getCart()->getTotalPrice() - $ship->getProduct()->getPrice();
# update the total price of cart
$ship->getCart()->setTotalPrice($final_price);
}
# flush operations to update database
$em->flush();
}
//return new Response(''. $new_quantity );
return $this->redirect($this->generateUrl('view_cart'));
}
/**
* @Route("/cart/clear/{cart}", name="clear_cart")
*/
public function clearActione($cart)
{
# get an object from doctrine db and get Shipping Entity to work on it
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('AppBundle:Shipping');
# select wanted item from shipping table to delete it
$ship = $repository->findBy(array('cart' => $cart));
# Fetch all them using foeach loop and delete them
foreach ($ship as $one_prod)
{
# Remove item from db
$em->remove($one_prod);
$em->flush();
}
$cart_repository = $em->getRepository('AppBundle:Cart');
$one_cart = $cart_repository->findOne(['id' => $cart]);
$em->remove($one_cart);
$em->flush();
return $this->redirect($this->generateUrl('view_cart'));
}
}
This is my Cart Entity code:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Shipping;
#use AppBundle\Entity\User;
#use AppBundle\Entity\Product;
/**
* @ORM\Entity
* @ORM\Table(name="cart")
*/
class Cart
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="decimal", scale=2)
*/
private $total_price;
/**
* @ORM\Column(type="integer")
*/
private $quantity;
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="cart")
*/
private $user;
/** @ORM\OneToMany(targetEntity="Shipping", mappedBy="cart") */
protected $cartProducts;
/**
* Constructor
*/
public function __construct()
{
$this->cartProducts = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set total_price
*
* @param string $totalPrice
* @return Cart
*/
public function setTotalPrice($totalPrice)
{
$this->total_price = $totalPrice;
return $this;
}
/**
* Get total_price
*
* @return string
*/
public function getTotalPrice()
{
return $this->total_price;
}
/**
* Set quantity
*
* @param integer $quantity
* @return Cart
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* @return integer
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* Set user
*
* @param \AppBundle\Entity\User $user
* @return Cart
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Add cartProducts
*
* @param Shipping $cartProducts
* @return Collection
*/
public function addCartProduct(array $cartProducts)
{
$this->cartProducts[] = $cartProducts;
return $this;
}
/**
* Remove cartProducts
*
* @param Shipping $cartProducts
*/
public function removeCartProduct(array $cartProducts)
{
$this->cartProducts->removeElement($cartProducts);
}
/**
* Get cartProducts
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCartProducts()
{
return $this->cartProducts;
}
}
And my Shipping Entity:
<?php
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
#use AppBundle\Entity\User;
#use AppBundle\Entity\Product;
/**
* @ORM\Entity
* @ORM\Table(name="shipping")
*/
class Shipping
{
/**
* @ORM\Column(type="integer")
*/
private $quantity;
/**
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="Product", inversedBy="cartProducts")
*/
protected $product;
/**
* @ORM\Id()
* @ORM\ManyToOne(targetEntity="Cart", inversedBy="cartProducts")
*/
protected $cart;
/**
* Set product
*
* @param \AppBundle\Entity\Product $product
* @return Shipping
*/
public function setProduct(\AppBundle\Entity\Product $product)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* @return \AppBundle\Entity\Product
*/
public function getProduct()
{
return $this->product;
}
/**
* Set cart
*
* @param \AppBundle\Entity\Cart $cart
* @return Shipping
*/
public function setCart(\AppBundle\Entity\Cart $cart)
{
$this->cart = $cart;
return $this;
}
/**
* Get cart
*
* @return \AppBundle\Entity\Cart
*/
public function getCart()
{
return $this->cart;
}
/**
* Set quantity
*
* @param integer $quantity
* @return Shipping
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* @return integer
*/
public function getQuantity()
{
return $this->quantity;
}
}
Upvotes: 1
Views: 887
Reputation: 330
Try using doctrine query builder with ->select('your join entity', 'alias') by using ->select() method you retrieve array not object from query
Upvotes: 0