1

How can I upload multiple images using only one file widget? Currently I have disabled mapping for the images (otherwise it would try to map to the values of the object, but then it would complain in the view because it's an array), but I have no idea how to get them back into the service.images array. What would be the best solution to this?

Service class

/**
 * Service
 *
 * @ORM\Table(name="services")
 * @ORM\Entity
 * @Gedmo\TranslationEntity(class="xxx\SiteBundle\Entity\ServiceTranslation")
 */
class Service
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @Gedmo\Translatable
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="price", type="decimal", scale=2)
     */
    private $price;

    /**
     * @var string
     *
     * @Gedmo\Slug(fields={"name"})
     * @ORM\Column(name="slug", type="string", length=128)
     */
    private $slug;

    /**
     * @var string
     *
     * @Gedmo\Translatable
     * @ORM\Column(name="description", type="text")
     */
    private $description;

    /**
     * @ORM\OneToMany(
     *     targetEntity="xxx\SiteBundle\Entity\ServiceTranslation",
     *  mappedBy="object",
     *  cascade={"persist", "remove"}
     * )
     */
    private $translations;

    /**
     * @ORM\OneToMany(
     *      targetEntity="xxx\SiteBundle\Entity\Image", mappedBy="service",
     *      cascade={"persist", "remove"}
     * )
     */
    private $images;

    public function __construct()
    {
        $this->translations = new ArrayCollection();
        $this->images = new ArrayCollection();
    }

    // everything else

}

Image class:

    /**
     * Image class.
     *
     * @ORM\Table(name="images")
     * @ORM\Entity
     * @Gedmo\Uploadable(filenameGenerator="SHA1", allowOverwrite=true, appendNumber=true)
     */
    class Image
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;

        /**
         * @ORM\Column(type="string", length=255)
         * @Gedmo\UploadableFileName
         */
        private $name;

        /**
         * @ORM\Column(type="string", length=255, nullable=true)
         * @Gedmo\UploadableFilePath
         */
        private $path;

        /**
         * @var
         */
        private $file;

        /**
         * @ORM\ManyToOne(targetEntity="xxx\SiteBundle\Entity\Service", inversedBy="images")
         * @ORM\JoinColumn(name="service_id", referencedColumnName="id")
         *
         */
        private $service;

        // everything else
}

Service form type:

$builder
    ->add('translations', 'a2lix_translations_gedmo', array(
        'translatable_class' => 'xxx\SiteBundle\Entity\Service',
        'label'  => false,
        'fields' => array(
            'name' => array(),
            'price' => array(
                'locale_options' => array(
                    'lt' => array(
                        'display' => false,
                    ),
                ),
            ),
            'description' => array(),
        ),
    ))
    ->add('images', 'file', array(
        'data_class' => 'xxx\SiteBundle\Entity\Image',
        'required' => false,
        'attr' => array(
            'accept' => 'image/*',
            'multiple' => 'multiple',
        ),
        'mapped' => false,
    ))
;

Controller

if ($form->isValid()) {

    $uploadableManager = $this->get('stof_doctrine_extensions.uploadable.manager');

    foreach ($service->getImages() as $image) {
        $uploadableManager->markEntityToUpload(
            $image,
            $image->getFile()
        );
    }

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

2 Answers 2

1

Alright, it seems I got it working.

$files = $request->files->get($form->getName());
foreach ($files['images'] as $imageData) {
    $image = new Image();

    $uploadableManager->markEntityToUpload(
        $image,
        $imageData
    );

    $em->persist($image);
}

Yeah, it doesn't look so good, but works..

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for being helpful... I would suggest to to give more details of the actions to be done on your controller.
0

One additional detail to save others some time: You should set the attribute multiple as a boolean value in the options of the file field instead of setting it manually as an 'attr':

->add('images', 'file', array(
    'data_class' => 'xxx\SiteBundle\Entity\Image',
    'required' => false,
    'attr' => array(
        'accept' => 'image/*'
    ),
    'multiple' => true,
    'mapped' => false,
))

This change ensures $files['images'] to be in array in any case, because when I select only 1 image, the object is returned without an array and I could not iterate over it with foreach.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.