0

I'm trying to store the image URL to the database using a form.

I've got 2 entities:

Product & ProductImages.

Product has OneToMany relation to ProductImages and ProductImages has ManyToOne relation to Product.

Product:

/**
 * @ORM\OneToMany(targetEntity="ProductImages", mappedBy="product")
 */
private $images;

/**
 * @return mixed
 */
public function getImages()
{
    return $this->images;
}

/**
 * @param mixed $images
 * @return $this
 */
public function setImages($images)
{
    $this->images = $images;

    return $this;
}

ProductImages:

/**
 * @ORM\ManyToOne(targetEntity="Product", inversedBy="images")
 * @ORM\JoinColumn(nullable=false)
 */
private $product;

/**
 * @return mixed
 */
public function getProduct()
{
    return $this->product;
}

/**
 * @param mixed $product
 */
public function setProduct(Product $product)
{
    $this->product = $product;
}

I made a form, with a file upload and this controller:

$product = new Product();

$form = $this->createForm(ProductFormType::class, $product);
$form->handleRequest($request);

if($form->isSubmitted() && $form->isValid()) {

    $file = $product->getImages();
    $fileName = $form->get('slug')->getData().'.'.$file->guessExtension();
    $file->move(
        $this->getParameter('product_image_directory'),
        $fileName
    );

    $product->setImages($fileName);

    $em = $this->getDoctrine()->getManager();
    $em->persist($product);
    $em->flush();

    $this->addFlash('success', 'Product aangemaakt!');

    return $this->redirectToRoute('admin_product_list');
}

The error I'm getting is :

Type error: Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, string given, called in C:\git\symfony\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 605

I already tried to save the ProductImages as new ProductImages(); and filling in all fields, but that does not work either.

1
  • It have to be array of product images, you must be passing single object instead of objects array
    – Eimsas
    May 4, 2017 at 10:27

1 Answer 1

1

setImages expects an array of images Entities. Not The filename. So you have to create a new entity with that filename or locate an existing Image entity with that filename.

It would be also useful creating addImage and remove image in your Product entity

public function addImage(Image $image){
$this->images->add($image);
}

public function removeImage(Image $image){
$this->images->removeElement($image);
}
10
  • I get this error when I try to pass an array with productImages Entity: A new entity was found through the relationship 'AppBundle\Entity\Product#images' that was not configured to cascade persist operations for entity: test.jpeg. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).
    – Refilon
    May 4, 2017 at 11:25
  • You need to persist the new created entity. If you are in a controller: $this->getDoctrine()->getManager()->persist($imageEntity); You only need to do this on new created entities. If you are updating an existing entity, you don't need to call the persist method. You can also use annotations to allow cascade persist, but I don't use them so much.
    – Carlos
    May 4, 2017 at 11:34
  • Does not work Carlos.... I did this already, that's why I get the error. When I use merge($product) it works, but it does not save to database.
    – Refilon
    May 4, 2017 at 11:41
  • I' don't use the merge method, buy are you calling flush() after that?? $this->getDoctrine()->getManager()->flush()
    – Carlos
    May 4, 2017 at 11:41
  • Please double check the persist(IMAGE ENTITY), reviewing your code, I saw that you are persisting the $product but not the image entity.
    – Carlos
    May 4, 2017 at 11:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.