subbeta/upload-media-bundle

v0.1.2 2020-04-13 11:18 UTC

This package is auto-updated.

Last update: 2024-09-14 17:43:02 UTC


README

pipeline status coverage report

用于管理文件上传的 Symfony 扩展包,支持分块文件上传

该扩展包还包含 blueimp/jQuery-File-Upload 和 jQuery 资源。

安装

使用 Composer 安装此扩展包

$ composer require subbeta/upload-media-bundle

首先,注册扩展包

# config/bundles.php
return [
    // ...
    UploadMediaBundle\UploadMediaBundle::class => ['all' => true],
];

添加路由

# config/routes/upload_media.yaml
_media:
    resource: '@UploadMediaBundle/Resources/config/routes.yaml'
    #prefix:  /upload

安装资源

$ php bin/console assets:install

创建表单


use Symfony\Component\Form\AbstractType;
use UploadMediaBundle\Form\UploadMediaType;

class UploadType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(
                'image',
                UploadMediaType::class,
                array(
                    'label' => 'image',
                    // the following options can be set
                    //'multiple' => false,
                    //'additiona_data' => array("data" => 'data')   
                    //'data_class' => UploadedMedia::class,
            		//'accept' => 'image/*',
            		//'upload_path_name' => 'upload_media_ajax',  
                )
            )
        ;

        // ... 
    }
    
    // ... 
}

创建包含文件上传代码的模板


{# form rendering #}

<script src="{{ asset('bundles/uploadmedia/blueimp/js/vendor/jquery.ui.widget.js') }}"></script>
<script src="{{ asset('bundles/uploadmedia/blueimp/js/jquery.iframe-transport.js') }}"></script>
<script src="{{ asset('bundles/uploadmedia/blueimp/js/jquery.fileupload.js') }}"></script>

<script type="text/javascript">
$(document).ready(function() {
    
    $('#{{ form.image.vars.id }}_container input.fileupload').fileupload({
        url: $(this).data("url"),
        dataType: 'json',
        limitConcurrentUploads: 3,
        sequentialUploads: false,
        maxChunkSize: 1000000, // 1 MB
        submit: function (e, data) {
            var additional_data = $(this).data("additionaldata");
            data.formData = {};
            if(typeof additional_data === 'string') {
                data.formData["additionalData"] = data;
            } else {
                for (key in additional_data) {
                    var nk = "additionalData["+key+"]";
                    data.formData[nk] = additional_data[key];
                }
            }
        },
        start: function (e, data) {
            var container = $(this).closest('.fileupload-container');
            container.find('.progress-bar').css('width','0%').text("0%");
        },
        done: function (e, data) {
            $container = $(this).closest('.upload_media_container');
            $input = $container.find('input.upload_result');
            
            var obj = [];
            try {
                obj = JSON.parse($input.val());
            } catch(e) {
            }

            for (var i = 0; i < data.result.data.length; i++) {
                obj.push(data.result.data[i]);
            }            

            if ($input.attr("multiple") == null) {
                obj = [obj.pop()];
            }

            $input.val(JSON.stringify(obj));
        },
        progressall: function (e, data) {
            var progress = parseInt(data.loaded / data.total * 100, 10);
            var container = $(this).closest('.fileupload-container');
            container.find('.progress-bar').css('width',progress + '%').text(progress + '%');
        },
    });
});
</script>

从表单获取上传文件


public function uploadAction(Request $request): Response
{
	// ...

	$form->handleRequest($request);
	$images = $form->get('image')->getData();
	// images is a single UploadedMedia object, or an array of UploadedMedia objects in case of multiple => true

	// ...
}

事件

  • UploadMediaEvents::GETFILES
    GETFILES 事件在上传过程的开始时发生。
    此事件用于从请求中提取上传文件。
    默认情况下,它提取所有文件。
    @Event("UploadMediaBundle\Events\GetUploadedFilesEvent")

  • UploadMediaEvents::KEEPFILE
    KEEPFILE 事件在上传文件移动之前发生。
    此事件允许您决定文件是否应该移动(保留)或不应移动。
    如果没有移动,则文件在脚本执行后将删除。
    @Event("UploadMediaBundle\Events\KeepfileEvent")

  • UploadMediaEvents::UPLOAD
    UPLOAD 事件在文件上传后发生。
    此事件允许您移动、修改上传的文件。
    @Event("UploadMediaBundle\Events\UploadedEvent")

  • UploadMediaEvents::FILEDATA
    FILEDATA 事件在文件移动后,在创建响应之前发生。
    此事件允许您以数组形式修改将要发送回的数据。
    @Event("UploadMediaBundle\Events\GetFileDataEvent")

  • UploadMediaEvents::CHUNKDATA
    CHUNKDATA 事件在块上传后,在创建响应之前发生。
    此事件允许您以数组形式修改将要发送回的数据。
    @Event("UploadMediaBundle\Events\GetChunkDataEvent")

  • UploadMediaEvents::RESPONSE
    RESPONSE 事件在发送响应之前发生。
    此事件允许您修改响应。
    @Event("UploadMediaBundle\Events\GetResponseEvent")

自定义数据类

如果您想从上传的文件中获取自定义数据,则可能需要创建一个自定义数据类。要使其工作,您需要创建一个自定义数据类,将其设置在表单中,并可选地使用 UploadMediaEvents::FILEDATA 或 UploadMediaEvents::RESPONSE 事件修改响应。

创建数据类

该类必须实现UploadedMediaInterface接口!


use UploadMediaBundle\Contract\UploadedMediaInterface;

class MyDataClass implements UploadedMediaInterface
{
    // ... 
}

设置表单的 data_class


class UploadType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
    	// ... 
            ->add(
                'image',
                UploadMediaType::class,
                array(
                    'label' => 'image',
                    'data_class' => MyDataClass::class, 
                    // ... 
                )
    // ... 

修改返回的数据


use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use UploadMediaBundle\Event\GetFileDataEvent;
use UploadMediaBundle\Event\UploadMediaEvents;

class MediaSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            UploadMediaEvents::FILEDATA => [
                ['getMediaResponse', 0],
            ],
        ];
    }

    public function getMediaResponse(GetFileDataEvent $event)
    {
    	// ... 
    	$event->setData($data);
    }
}