A
A
Andrey Shakhtarin2016-10-10 13:45:17
symfony
Andrey Shakhtarin, 2016-10-10 13:45:17

How to save pictures in symphony using Array Collection?

Good day to all! I came across a situation in symfony 2, such as the correct saving of pictures to the database through the ArrayCollection facilities.
What I have:
There is a Product entity (product data),

App\EducationBundle\Entity\Product:
    type: entity
    table: product
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        name:
            type: string
            length: 255
       ......................................
    oneToMany:
        image:
            targetEntity: Image
            cascade:  [persist]
            mappedBy: product

and the Image entity (pictures> for this product):
App\EducationBundle\Entity\Image:
    type: entity
    table: image_product
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        image:
            type: string
            length: 255
        .................................................
    manyToOne:
        product:
            targetEntity: Product
            inversedBy: image
            joinColumn:
                name: product_id
                referencedColumnName: id

Forms for them:
class ImageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('image', FileType::class)
                ->add('descimage', TextareaType::class);

    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Image::class,
        ));
    }
}

class ProductType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $current_user = $this->getUser();
        $builder
            ->add('name', HiddenType::class)
            ->add('product')
            ->add('price')
            ->add('short_description')
            ->add('description')
            ->add('brochure', FileType::class, array('label' => 'Type File'))
            ->add('company')
            ->add('logo')
            ->add('location')
            ->add('url' , HiddenType::class)
            ->add('user_foto', FileType::class, array('label' => 'Upload File'))
            ->add('save', SubmitType::class);
        $builder->add('image', CollectionType::class, array(
            'entry_type' => ImageType::class,
            'prototype' => true,
            'allow_add' => true,
            'allow_delete' => true,

        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Product::class,
        ));
    }

Relationships between two entities are configured:
Product entity
class Product {
//..................
/**
     * Add image
     *
     * @param \App\EducationBundle\Entity\Image $image
     *
     * @return Product
     */
    public function addImage(\App\EducationBundle\Entity\Image $image)
    {

        $this->image[] = $image;
        $image->setProduct($this);
        $this->image->add($image);
        return $this;
    }
//...............

entity Image:
class Image {
//...................
/**
     * Set product
     *
     * @param \App\EducationBundle\Entity\Product $product
     *
     * @return Image
     */
    public function setProduct(\App\EducationBundle\Entity\Product $product = null)
    {

        $this->product = $product;
    }
//......................................

subform:twig
<td colspan="8" class="tags" data-prototype=" <span class='label-key '>{{ form_label(form.image.0)|e }} </span><span class='image-label'>{{ form_label(form.image.0.image)|e }}</span><span class='image-widget'>{{ form_widget(form.image.0.image)|e }}</span> <span class='description-label'>Description image</span><span class='description-widget'>{{ form_widget(form.image.0.descimage)|e }}</span>">
 </td>

controller:
public function createAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();

        $product = new Product();
        $img = new Image();

        //$img->setProdimage(null);
        $product->getImage()->add($img);


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

        $product->setName($this->getUser());

        if ($form->isSubmitted() && $form->isValid()) {
            $file = $product->getBrochure();
            $fileName = rand(1111, 9999).md5(uniqid()).'.'.$file->guessExtension();

            $file->move(
                $this->getParameter('brochures_directory'),
                $fileName
            );

            if($img->getImage())
            {
                $imagefile = $img->getImage();
                $imagefileName = md5(uniqid()).'.'.$imagefile->guessExtension();
                $imagefile->move(
                    $this->getParameter('image_directory'),
                    $imagefileName
                );
                $img->setImage($this->getParameter('image_directory').$imagefileName);
                $em->persist($img);
            }

            $img->setProduct($product);

            $product->setBrochure($this->getParameter('brochures_directory').$fileName);


            //print_r($images);

            $em->persist($product);
            //$em->flush();
            //return $this->redirectToRoute('product_show', array('id' => $product->getId()));
        }

        $data['form'] = $form->createView();
        return $this->render('AppEducationBundle:Products:create.html.twig', $data);
    }

What is the main catch?
the Image entity is saved as follows:
First object: saved as it should be, there is an absolute path to the image, a description for the picture, the id of the product that is saved as expected.
the second object of this entity and subsequent objects:
the path is not correct, generated by UploadedFile (tmp/....) an object of non-string type data arrives, the id is written null, the description for the picture is preserved as expected (what is filled in the form is recorded), after a short search and study of how and what and where comes I realized that the possible reason is related to the data place $product->getImage()->add($img); more precisely, you need to implement it in this way or from an entity or controller, so that subsequent objects dynamically add a connection to this entity. Help kind people!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis, 2016-10-10
@AndreyShakhtarin

<?php

class Product
{
    private $images;
    public function __construct()
    {
        $this->images = new ArrayCollection()
    }
    public function addImage(Image $image)
    {
        $this->images[] = $image;
        return $this;
    }
    public function removeImage(Image $image)
    {
        $this->images->removeElement($image);
        return $this;
    }
    public function getImages()
    {
        return $this->images;
    }
}

$product = new Product();
$form = $this->createForm(ProductType::class);
$form->handleRequest($request);

if ($form->isValid()) {
    foreach ($product->getImages() as $image) {
        $this->upload($image); // or DoctrineEvent prePersist Image
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question