Ограничение на загрузку нескольких файлов - PullRequest
0 голосов
/ 26 сентября 2019

Я следовал руководству по управлению загрузкой нескольких файлов http://growingcookies.com/easy-multiple-file-upload-in-symfony-using-the-collectiontype-field/

Система загрузки нескольких файлов работает нормально.

Однако я хотел бы добавить ограничение, разрешающее только определенные типы файлов и устанавливать максимальный размер.

Для этого я добавлю @Assert\File:

/**
 * @Assert\File(
 *     maxSize = "300k",
 *     mimeTypes = {"application/pdf", "application/x-pdf", "text/plain", "application/msword",
 *     "application/vnd.ms-excel", "image/jpeg", "image/x-citrix-jpeg", "image/png", "image/x-citrix-png", "image/x-png", "image/gif",
 *     "application/zip"},
 *     mimeTypesMessage = "Liste des formats de fichiers acceptés : PDF, TXT, DOC, XLS, JPG, PNG, GIF"
 * )
 *
 * @ORM\OneToMany(targetEntity="Maps_red\TicketingBundle\Entity\TicketDocument", mappedBy="ticket", cascade={"persist"}, orphanRemoval=true)
 */
protected $documents;

При добавлении этого код больше не работает.Я получаю следующую ошибку:

Невозможно получить доступ к атрибуту («имя») для пустой переменной.

Эта ошибка появляется на странице добавления файлов при отправкеформа.Строка, соответствующая ошибке:

<div class="col col-xs-11" id="jsPreview{{ pos }}">{{ doc.vars.value.name }}</div>

Сообщение о нарушении ограничения: "The file could not be found."

Знаете ли вы, где моя ошибка?


Редактироватьдля @Denis Alimov:

Я попробовал ответить Денису Алимову с @Assert\All, но он возвращает ту же ошибку.Затем я попытался вставить ограничение в BuildForm.Теперь файлы .txt проходят без ошибок, но все остальные расширения всегда возвращают мне одну и ту же ошибку

Невозможно получить доступ к атрибуту («имя») для пустой переменной.


Редактировать для @Jakumi:

Моя веточка:

{% extends '@Ticketing/base.html.twig' %}

{% block title %}{{ 'New Ticket'|trans({}, 'TicketingBundle') }}{% endblock %}
{% block header %}<h1>{{ 'New Ticket'|trans({}, 'TicketingBundle') }}</h1>{% endblock %}

{% block form_group_class -%}
    col-sm-8
{%- endblock form_group_class %}


{% block main %}

    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

    {% form_theme form 'bootstrap_4_layout.html.twig' _self %}

    <div class="box box-danger">
        <div class="box-header with-border">
            <h3 class="box-title">{{ 'Create a new ticket'|trans({}, 'TicketingBundle') }}</h3>
        </div>

        {% form_theme form 'bootstrap_3_horizontal_layout.html.twig' _self %}

        {{ form_start(form, {'attr': {'class': 'form-horizontal'} }) }}
        <div class="box-body">

            <div class="hr-line-dashed"></div>

            <div id="filesProto" data-prototype="{{ form_widget(form.documents.vars.prototype)|e }}"></div>

            <div class="form-group">
                <label class="col-sm-2 control-label" for="ticket_form_documents">Pièce-jointe</label>
                <div class="col-sm-8" id="filesBox">
                    {% set pos = 0 %}
                    {% for doc in form.documents %}
                        <div class="row">
                            <div class="col col-xs-1" id="jsRemove{{ pos }}" style="">
                                <button type="button" class="btn btn-danger" onclick="removeFile($(this));"><i class="fa fa-times" aria-hidden="true"></i></button>
                            </div>
                            <div class="col col-xs-11" id="jsPreview{{ pos }}">{{ doc.vars.value.name }}</div>

                            <div style="display:none">
                                {{ form_widget(doc) }}
                            </div>
                        </div>

                        {% set pos = pos + 1 %}
                    {% endfor %}
                </div>
            </div>

        </div>
        <!-- /.box-body -->

        <div class="box-footer">
            <div class="col-md-offset-2 col-sm-8">

                <button id="dropbutton" class="btn bg-ticketing btn-flat form-control" type="submit">
                    {{ 'Submit the ticket'|trans({}, 'TicketingBundle') }}
                </button>


            </div>
        </div>
        <!-- /.box-footer -->
        {{ form_end(form) }}
    </div>

    <script>
        var fileCount = '{{ form.documents|length }}';
        var removeButton = "<button type='button' class='btn btn-danger btn-xs' onclick='removeFile($(this));'><i class='fa fa-times' aria-hidden='true'></i></button>";
        function removeFile(ob)
        {
            ob.parent().parent().remove();
        }
        function createAddFile(fileCount)
        {
            // grab the prototype template
            var newWidget = $("#filesProto").attr('data-prototype');
            // replace the "__name__" used in the id and name of the prototype
            newWidget = newWidget.replace(/__name__/g, fileCount);
            newWidget = "<div style='display:none'>" + newWidget + "</div>";
            hideStuff = "";
            hideStuff += "<div class='col col-xs-1' id='jsRemove" + fileCount + "' style='display: none;'>";
            hideStuff += removeButton;
            hideStuff += "</div>";
            hideStuff += "<div class='col col-xs-11' id='jsPreview" + fileCount + "'>";
            hideStuff += "</div>";
            hideStuff += "<div class='col-sm-8'>";
            hideStuff += "<button type='button' id='jsBtnUpload" + fileCount + "' class='btn btn-default'>";
            hideStuff += "<i class='fa fa-plus'></i> {{ 'Pièce-jointe' | trans }}";
            hideStuff += "</button>";
            hideStuff += "</div>";
            $("#filesBox").append("<div class='form-group'>" + hideStuff + newWidget + "</div>");
            // On click => Simulate file behaviour
            $("#jsBtnUpload" + fileCount).on('click', function(e){
                $('#ticket_form_documents_' + fileCount + '_file').trigger('click');
            });
            // Once the file is added
            $('#ticket_form_documents_' + fileCount + '_file').on('change', function() {
                // Show its name
                fileName = $(this).prop('files')[0].name;
                $("#jsPreview" + fileCount).append(fileName);
                // Hide the add file button
                $("#jsBtnUpload" + fileCount).hide();
                // Show the remove file button
                $("#jsRemove" + fileCount).show();
                // Create another instance of add file button and company
                createAddFile(parseInt(fileCount)+1);
            });
        }
        $(document).ready(function(){
            createAddFile(fileCount);
            fileCount++;
        });
    </script>

{% endblock %}

Редактировать:

С {{doc.vars.value.имя ??''}} У меня больше нет ошибки !!

Тем не менее, кнопки удаления файлов по-прежнему отображаются:

<div class="col col-xs-1" id="jsRemove1" style="">
 <button type="button" class="btn btn-danger" onclick="removeFile($(this));"><i class="fa fa-times" aria-hidden="true"></i></button>
</div>

Как заставить эти кнопки исчезать, если тип файла не подходит

1 Ответ

0 голосов
/ 26 сентября 2019

Как уже упоминалось, используйте Все ограничения вот так

 /**
 * @Assert\All({
 *     @Assert\File(
 *         maxSize = "300k",
 *         mimeTypes = {"application/pdf", "application/x-pdf", "text/plain", "application/msword", "application/vnd.ms-excel", "image/jpeg", "image/x-citrix-jpeg", "image/png", "image/x-citrix-png", "image/x-png", "image/gif","application/zip"},
 *         mimeTypesMessage = "Liste des formats de fichiers acceptés : PDF, TXT, DOC, XLS, JPG, PNG, GIF"
 *     )
 * })
 */
 private $documents;

Также вы можете добавить ограничения к вашему DocumentType в методе buildForm

...