Symfony:使用 dropzone 上传文件

Syfmony: upload files with dropzone

我正在使用 Symfony 4.1 开发一个简单的 CMS 之王。

关于我的问题,我们有 2 个实体:

所以为了添加 Post,我有一个 PostType:

<?php

namespace App\Form;

use App\Entity\Category;
use App\Entity\Post;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Class PostType
 * @package App\Form
 */
class PostType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('content', CKEditorType::class)
            ->add('categories', EntityType::class,
                [
                    'class'        => Category::class,
                    'required'     => true,
                    'choice_label' => 'name',
                    'multiple'     => true,
                ]
            )
            ->add('pictureFiles', FileType::class,
                [
                    'required' => false,
                    'multiple' => true,
                    'label'    => 'Add files...',
                    'attr' =>
                        [
                            'action' => '%kernel.project_dir%/public/media/posts'
                        ]
                ]
            )
            ->add('status')
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Post::class,
        ]);
    }
}

该表单对应的视图:

{% form_theme form '/admin/form/switch_btn_layout.html.twig' %}

{{ form_start(form) }}

    {{ form_errors(form) }}

    <div class="form-row">

        <div class="col-md-6">
            {{ form_row(form.name) }}
            {{ form_row(form.categories) }}
            {{ form_row(form.status) }}
        </div>

        <div class="col-md-6 dropzone" id="postDropzone">
            {{ form_row(form.pictureFiles, {'attr': {'class': 'dropzone'}} ) }}

            <div class="dropzone-previews" style="border: 1px solid red"></div>
        </div>
    </div>

    <div class="form-group">
        {{ form_row(form.content) }}
    </div>

    <div class="form-group">
        {{ form_row(form.status) }}
    </div>

    {{ form_rest(form) }}

    <button class="btn btn-success btn-lg btn-block" id="postSubmit">
        {{ button_label|default('Save') }}
    </button>

{{ form_end(form) }}

如您所见,文件的 "input" 作为拖放区 css class。 事实上,我的项目包括 oneup_uploader 包,用于 dropzone。

这里是oneup_uploader的配置:

oneup_uploader:
    mappings:
        # This is a mapping example, remove it and create your own mappings.
        post_image:
            frontend: dropzone
            namer: oneup_uploader.namer.uniqid
            storage:
                directory: '%kernel.project_dir%/public/media/posts'

还有我的 Dropzone 脚本:

Dropzone.autoDiscover = false;

var postDropzone = new Dropzone('.dropzone', {

    url: '%kernel.project_dir%/public/media/posts',
    // url: 'file/post',
    maxFiles: 10,
    addRemoveLinks: true,
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 100,

});

postDropzone.on("addedfile", function (file) {

    file.previewElement.addEventListener("click", function () {
        postDropzone.removeFile(file);
    })
});

我的问题是:

我也尝试过不使用OneUploaderBundle,而使用VichUploader:DB中的保存部分是完美的,但我不能link它到dropzone。

有人帮忙吗? 非常感谢 !

你应该传递 upload url 而不是 upload directory

在树枝中生成 url - {{ oneup_uploader_endpoint('post_image') }}

var postDropzone = new Dropzone('.dropzone', {
    url: '{{ oneup_uploader_endpoint('post_image') }}',
    // url: '%kernel.project_dir%/public/media/posts',
    // url: 'file/post',
    maxFiles: 10,
    addRemoveLinks: true,
    autoProcessQueue: false,
    uploadMultiple: true,
    parallelUploads: 100,

});

可能对新访客有用。 您可以使用扩展 Symfony Form 并添加新类型 DropzneType.

的库

1.Install图书馆

composer require emrdev/symfony-dropzone

这样您将拥有一个新的表单类型 DropzoneType

2.Use 在你的表单中这样输入

public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, array $options)
{ 

    // userFiles is OneToMany
    $builder->add('userFiles', DropzoneType::class, [
        'class' => File::class,
        'maxFiles' => 6,
        'uploadHandler'=>'uploadHandler',  // route name
        'removeHandler'=> 'removeHandler'// route name
   ]);
}

将 uploadHandler 和 removeHandler 选项更改为您的端点

3.Route uploadHandler/removeHandler 可能看起来像这样

/**
 * @Route("/uploadhandler", name="uploadHandler")
 */
public function uploadhandler(Request $request, ImageUploader $uploader) { 
    $doc = $uploader->upload($request->files->get('file'));  
    $file = new File(); 
    $file->setSrc($doc['src']);
    ...

    $this->getDoctrine()->getManager()->persist($file);
    $this->getDoctrine()->getManager()->flush();
    return new JsonResponse($file);
}


/**
 * @Route("/removeHandler/{id}", name="removeHandler")
 */
public function removeHandler(Request $request,File $file = null) {
    $this->getDoctrine()->getManager()->remove($file);
    $this->getDoctrine()->getManager()->flush();
    return new JsonResponse(true);
}

note that uploadhandler should return a File object