문제

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();
도움이 되었습니까?

해결책

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..

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top