diff --git a/Form/Type/FileUploadType.php b/Form/Type/FileUploadType.php index 4204500ec0c880316d8a650dd37165e9bf37cc95..ec521012180cf2a49f12d92df882e3fc0dc73edf 100644 --- a/Form/Type/FileUploadType.php +++ b/Form/Type/FileUploadType.php @@ -7,9 +7,12 @@ namespace Irstea\FileUploadBundle\Form\Type; +use Irstea\FileUploadBundle\Controller\UploadController; +use Irstea\FileUploadBundle\Form\DataTranformer\UploadedFileTransformer; use Irstea\FileUploadBundle\Service\FileManagerInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolverInterface; @@ -48,29 +51,34 @@ class FileUploadType extends AbstractType $this->csrfProvider = $csrfProvider; } - public function buildView(FormView $view, FormInterface $form, array $options) + public function buildForm(FormBuilderInterface $builder, array $options) { - $this->buildWidgetView($view, $form, $options); - - $view->vars['widget_attr']['data-create-url'] = $this->router->generate('file_upload_create'); + $builder->setCompound(false); + $builder->addViewTransformer(new UploadedFileTransformer($this->fileManager)); } - public function setDefaultOptions(OptionsResolverInterface $resolver) + public function buildView(FormView $view, FormInterface $form, array $options) { - $this->setWidgetDefaultOptions($resolver); + $this->buildWidgetView($view, $form, $options); - $resolver->setDefaults( - [ - 'data_class' => '\Irstea\FileUploadBundle\Entity\UploadedFile', - 'multiple' => false, - ] - ); + $view->vars['widget_attr']['data-create-url'] = $this->router->generate('file_upload_create'); $view->vars['csrfToken'] = $this->csrfProvider->generateCsrfToken(UploadController::CSRF_INTENTION); } protected function getWidgetDefaults() { - return []; + return [ + 'multiple' => false, + 'accept_file_types' => '', + 'max_file_size' => 0, + 'min_file_size' => 0, + 'max_number_of_files' => 0, + 'bitrate_interval' => 512, + 'progress_interval' => 100, + 'recalculate_progress' => true, + 'max_chunk_size' => 1000000, + 'sequential_uploads' => false, + ]; } public function getName() diff --git a/Resources/js/widget/file_upload.js b/Resources/js/widget/file_upload.js index 650d4727a111f24ce8c609346cc4be676c1db895..3519ab9617033af47c1d5e64050691ed6f45c197 100644 --- a/Resources/js/widget/file_upload.js +++ b/Resources/js/widget/file_upload.js @@ -49,75 +49,79 @@ updateButtonVisibility(); // Activation - $this.fileupload({ - type: 'PUT', - autoUpload: true, - formData: {}, - multipart: false, - uploadTemplateId: null, - downloadTemplateId: null, - filesContainer: $this.find('.fileinput-entries'), - maxChunkSize: 1000000, - uploadTemplate: function(data) { - var rows = $(); - $.each(data.files, function (index, file) { - var row = $(uploadPrototype); - row.find('.name').text(file.name); - row.find('.size').text(formatSize(file.size)); - if (file.error) { - row.find('.error').text(file.error); - } - rows = rows.add(row); - }); - return rows; - }, - downloadTemplate: function(data) { - var rows = $(); - $.each(data.files, function (index, file) { - var row = $(downloadPrototype); - row.find('.size').html(formatSize(file.size)); - if (file.error) { + $this.fileupload($.extend( + options, + { + type: 'PUT', + autoUpload: true, + formData: {}, + multipart: false, + uploadTemplateId: null, + downloadTemplateId: null, + filesContainer: $this.find('.fileinput-entries'), + maxChunkSize: options.maxChunkSize || 1000000, + uploadTemplate: function(data) { + var rows = $(); + $.each(data.files, function (index, file) { + var row = $(uploadPrototype); row.find('.name').text(file.name); - row.find('.error').text(file.error); - } else { - row.find('.name a') - .text(file.name) - .attr('data-gallery', '') - .prop('href', file.url); - row.find('button.delete') - .attr('data-type', file.delete_type) - .attr('data-url', file.delete_url); + row.find('.size').text(formatSize(file.size)); + if (file.error) { + row.find('.error').text(file.error); + } + rows = rows.add(row); + }); + return rows; + }, + downloadTemplate: function(data) { + var rows = $(); + $.each(data.files, function (index, file) { + var row = $(downloadPrototype); + row.find('.size').html(formatSize(file.size)); + if (file.error) { + row.find('.name').text(file.name); + row.find('.error').text(file.error); + } else { + row.find('.name a') + .text(file.name) + .prop('href', file.url); + row.find('button.delete') + .attr('data-type', file.delete_type) + .attr('data-url', file.delete_url); + row.find('input:hidden') + .val(file.id); + } + rows = rows.add(row); + }); + return rows; + }, + submit: function (e, data) { + var $this = $(this), + file = data.files[0]; + $.post( + createUrl, + { file: { name: file.name, size: file.size, type: file.type, lastModified: file.lastModified } }, + function(response) { + data.url = response.url; + data.jqXHR = $this.fileupload('send', data); + } + ); + return false; + }, + progress: function (e, data) { + if(!data.context || e.isDefaultPrevented()) { + return; } - rows = rows.add(row); - }); - return rows; - }, - submit: function (e, data) { - var $this = $(this), - file = data.files[0]; - $.post( - createUrl, - { file: { name: file.name, size: file.size, type: file.type, lastModified: file.lastModified } }, - function(response) { - data.url = response.url; - data.jqXHR = $this.fileupload('send', data); - } - ); - return false; - }, - progress: function (e, data) { - if(!data.context || e.isDefaultPrevented()) { - return; + var progress = Math.floor(data.loaded / data.total * 100); + data.context.each(function () { + $(this).find('.progress') + .attr('aria-valuenow', progress) + .children().first().css('width',progress + '%'); + $(this).find('.progress-text').html(progress + '% ('+formatBitrate(data.bitrate)+')'); + }); } - var progress = Math.floor(data.loaded / data.total * 100); - data.context.each(function () { - $(this).find('.progress') - .attr('aria-valuenow', progress) - .children().first().css('width',progress + '%'); - $(this).find('.progress-text').html(progress + '% ('+formatBitrate(data.bitrate)+')'); - }); } - }).bind({ + )).bind({ fileuploadfailed: function (e, data) { $.ajax(data.url, { type: 'DELETE' }); }, diff --git a/Resources/views/Form/file_upload.html.twig b/Resources/views/Form/file_upload.html.twig index 167e6d75be3ef658538c47d0fcb0d0e3f1260e59..f80557300ed46d7041e30188c3987e0a19c2789a 100644 --- a/Resources/views/Form/file_upload.html.twig +++ b/Resources/views/Form/file_upload.html.twig @@ -8,38 +8,38 @@ </button> <span class="name"></span> (<span class="size"></span>) <span class="error danger"></span> </p> - <p class="progress"> + <p class="progress" style="display: none"> <div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div> </p> </div> {% endblock %} {% block file_upload_widget %} - <div id="{{ id }}" - data-widget="irsteaFileUpload" - data-create-url="{{ widget_attr['data-create-url'] }}" + <div id="{{ id }}" {{ block('widget_container_attributes') }} {{ block('widget_only_attributes') -}} data-download-prototype="{{ block('file_upload_entry_prototype')|e }}" data-upload-prototype="{{ block('file_upload_progress_prototype')|e }}"> <div class="fileinput-entries"> - {%- set file = value %} - {%- block file_upload_entry_prototype %} - {%- set file = file|default([]) %} - <p class="template-download"> - <input type="hidden" name="{{ name }}" value="{{ file.id|default }}"/> - <button class="btn btn-xs btn-danger delete" title="{% trans %}button.delete{% endtrans %}"> - {{- irstea_icon('trash') -}} - </button> <span class="name"> - <a{% if file %} href="{{ path('file_upload_get', {id: file.id}) }}"{% endif %}>{{ file.originalFilename|default }}</a> - </span> (<span class="size"> - {{- file.size|default -}} - </span>) - <span class="error danger"></span> - </p> - {% endblock -%} + {%- if value is not empty %} + {%- set file = value %} + {%- block file_upload_entry_prototype %} + {%- set file = file|default([]) %} + <p class="template-download"> + <input type="hidden" name="{{ full_name }}" value="{{ file.id|default }}"/> + <button class="btn btn-xs btn-danger delete" title="{% trans %}button.delete{% endtrans %}"> + {{- irstea_icon('trash') -}} + </button> <span class="name"> + <a{% if file %} href="{{ path('file_upload_get', {id: file.id, token: csrfToken}) }}"{% endif %}>{{ file.originalFilename|default }}</a> + </span> (<span class="size"> + {{- file.size|default -}} + </span>) + <span class="error danger"></span> + </p> + {% endblock -%} + {% endif -%} </div> <span class="btn btn-primary fileinput-button"> <span>{{ irstea_icon('upload') }} {% trans %}button.upload{% endtrans %}</span> - <input type="file" name="_dummy_{{ name }}" multiple="multiple"/> + <input type="file" name="_hack_{{ full_name }}"{% if widget_attr['data-create-url'] %} multiple="multiple"{% endif %}/> </span> </div> {% endblock file_upload_widget %}