Я действительно понятия не имею, где проблема находится, чтобы быть честным.

Может быть, Dropzone, Laravel (5.4), ... Так что я искренне надеюсь, что даже мысль поможет мне преодолеть эту проблему.

Когда я загружаю файлы, у меня не возникает проблем с js, но Laravel выдает мне следующую ошибку (для каждого файла):

Вызов неопределенного метода Symfony \ Component \ HttpFoundation \ File \ UploadedFile :: store ()

Это мой бэкэнд-код (ошибка устанавливается в методе portfolioStore):

    <?php

namespace App\Http\Controllers;

use App\Http\Requests\UploadPortfolioPhotoRequest; use App\PortfolioPhoto; use DebugBar\DebugBar; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage;

class AdminController extends Controller {
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('admin.home');
    }

    public function portfolioIndex()
    {
        $photos = PortfolioPhoto::all();

        return view ('admin.portfolio.index')->with('photos', $photos);
    }

    public function portfolioStore(UploadPortfolioPhotoRequest $request)
    {
        foreach ($request->files as $photo) {
            $filename = $photo->store('photos');

            $test = PortfolioPhoto::create([
                'filename' => $filename,
                'title' => 'title',
                'alt' => 'alt'
            ]);
        }

        return 'Upload successful!';
    }

    public function portfolioDelete()
    {
        return view ('admin.portfolio.index');
    } }

В любом случае, вот мой конфиг Dropzone:

var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);

var myDropzone = new Dropzone(document.body, { // Make the whole body a dropzone
    url: "/admin/portfolio", // Set the url
    thumbnailWidth: 80,
    thumbnailHeight: 80,
    parallelUploads: 20,
    previewTemplate: previewTemplate,
    autoDiscover: false,
    autoQueue: false, // Make sure the files aren't queued until manually added
    previewsContainer: "#previews", // Define the container to display the previews
    clickable: ".fileinput-button", // Define the element that should be used as click trigger to select files.
    headers: {
        'x-csrf-token': document.querySelectorAll('meta[name=csrf-token]')[0].getAttributeNode('content').value,
    }
});

myDropzone.on("addedfile", function(file) {
    // Hookup the start button
    file.previewElement.querySelector(".start").onclick = function() { myDropzone.enqueueFile(file); };
});

myDropzone.on("sending", function(file) {
    // And disable the start button
    file.previewElement.querySelector(".start").setAttribute("disabled", "disabled");
});

// Hide the total progress bar when nothing's uploading anymore
myDropzone.on("queuecomplete", function(progress) {
    var alertMsg = document.createElement('div'),
        actions = document.getElementById('actions');
    alertMsg.setAttribute('class', 'alert bg-success');
    alertMsg.innerHTML = 'Files successfully uploaded<a href="#" class="pull-right"><em class="fa fa-lg fa-close"></em></a>';
  actions.parentNode.insertBefore(alertMsg, actions.nextSibling);
});

// Setup the buttons for all transfers
// The "add files" button doesn't need to be setup because the config
// `clickable` has already been specified.
document.querySelector("#actions .start").onclick = function() {
    myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED));
};
document.querySelector("#actions .cancel").onclick = function() {
    myDropzone.removeAllFiles(true);
};

Вот мнение:

@extends('admin.layouts.app')

@section('content')
    <div class="row">
        <div class="col-xs-12">
            <div class="panel panel-default">
                <div class="panel-heading">Upload images</div>

                <div class="panel-body">
                    @if (count($errors) > 0)
                        <div class="row">
                            <div class="col-xs-12">
                                <div class="alert bg-danger" role="alert"><em class="fa fa-lg fa-warning">&nbsp;</em>
                                    <ul style="display: inline-block;">
                                        @foreach ($errors->all() as $error)
                                            <li>{{ $error }}</li>
                                        @endforeach
                                    </ul>
                                    <a href="#" class="pull-right"><em class="fa fa-lg fa-close"></em></a>
                                </div>
                            </div>
                        </div>
                    @endif

                    <div id="actions" class="row">
                        <div class="col-xs-12">
                            <div class="form-group">
                                <button class="btn btn-success fileinput-button">
                                    <i class="glyphicon glyphicon-plus"></i><span>Add files...</span>
                                </button>
                                <button type="submit" class="btn btn-primary start">
                                    <i class="glyphicon glyphicon-upload"></i> <span>Start upload</span>
                                </button>
                                <button type="reset" class="btn btn-warning cancel">
                                    <i class="glyphicon glyphicon-ban-circle"></i> <span>Cancel upload</span>
                                </button>
                            </div>
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-xs-12">
                            <div class="files" id="previews">
                                <div id="template" class="file-row">
                                    <div class="media">
                                        <div class="media-left">
                                            <img data-dz-thumbnail/>
                                        </div>
                                        <div class="media-body">
                                            <h4 class="media-heading name" data-dz-name></h4>
                                            <div class="col-xs-12"><strong class="error text-danger" data-dz-errormessage></strong></div>
                                            <div class="col-xs-12">
                                                <div class="col-sm-3">
                                                    <p class="size" data-dz-size></p>
                                                    <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
                                                        <div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
                                                    </div>
                                                </div>
                                                <div class="col-sm-9 text-right">
                                                    <button class="btn btn-primary start">
                                                        <i class="glyphicon glyphicon-upload"></i>
                                                        <span>Start</span>
                                                    </button>
                                                    <button data-dz-remove class="btn btn-warning cancel">
                                                        <i class="glyphicon glyphicon-ban-circle"></i>
                                                        <span>Cancel</span>
                                                    </button>
                                                    <button data-dz-remove class="btn btn-danger delete">
                                                        <i class="glyphicon glyphicon-trash"></i>
                                                        <span>Delete</span>
                                                    </button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-xs-12">
            <div class="panel panel-default">
                <div class="panel-heading">Portfolio</div>

                <div class="panel-body">
                    <div class="row">
                        @foreach($photos as $photo)
                            <div class="col-xs-6 col-md-3">
                                <a href="#" class="thumbnail">
                                    <img src="..." alt="...">
                                </a>
                            </div>
                        @endforeach
                    </div>
                </div>
            </div>
        </div>
    </div>@endsection

@push('styles')
<link href="{{asset('css/vendor/dropzone.css')}}"/>
@endpush

@push('scripts')
<script src="{{asset('js/vendor/dropzone.js')}}"></script>
<script src="{{asset('js/vendor/initialize/dropzone.cfg.js')}}"></script>
@endpush

Поэтому теперь мне интересно, связана ли эта проблема с неопределенным типом MIME, из-за которого метод store не работает. Или я должен искать в другом месте?

Любые советы, идеи приветствуются :)

8
Goowik 4 Сен 2017 в 10:43

5 ответов

Лучший ответ

Проблема в том, что $request->files не существует в кодовой базе Laravel. Поскольку класс Illuminate\Http\Request расширяет класс Symfony\Component\HttpFoundation\Request, files ссылается на класс Symfony\Component\HttpFoundation\FileBag, который содержит множество Symfony\Component\HttpFoundation\File\UploadedFile объектов, у которых нет метода store.

Простое исправление: Замените $request->files на $request->allFiles(), который должен дать вам массив Illuminate\Http\UploadedFile классов, имеющих метод store

Не стесняйтесь задавать любые вопросы в разделе комментариев, если вам нужна дополнительная помощь

2
Paras 7 Сен 2017 в 18:05

У меня была похожая проблема, но в моем случае просто не было свойства enctype="multipart/form-data", включенного в тег <form>. Как только я это сделал, это сработало. И я вижу, у вас также нет тега <form>.

<form action="/route" method="post" enctype="multipart/form-data">
    <!-- your code for dropzone goes here -->
</form>

И на заметку, в вашем методе portfolioStore() вашего контроллера AdminController,

foreach ($request->allFiles() as $photo) {
    $filename = $photo->store('photos');

    $test = PortfolioPhoto::create([
        'filename' => $filename,
        'title' => 'title',
        'alt' => 'alt'
    ]);
}

Пожалуйста, не делайте этого!

Вы создаете слишком много запросов на вставку здесь.

Рефакторинг это следующим образом. Вы можете уйти с одним запросом БД :)

$photos = [];
foreach ($request->files as $photo) {
    $filename = $photo->store('photos');

    $photos[] = [
        'filename' => $filename,
        'title' => 'title',
        'alt' => 'alt'
    ];
}
PortfolioPhoto::createMany($photos);

А также в предыдущем посте я ответил, как правильно хранить файлы в Laravel. Вы можете проверить это здесь. это может улучшить вашу $filename = $photo->store('photos'); часть.

Надеюсь, это поможет вам :)

2
Gayan 18 Сен 2017 в 02:44

< Сильный > ОБНОВЛЕНО

В Laravel вы получаете доступ к загруженным файлам с помощью метода file, который принимает имя файла ввода в качестве параметра. А из документов Dropzonejs:

Загруженные файлы могут быть обработаны так же, как если бы ввод html был таким: <input type="file" name="file" />

Итак, попробуйте это:

foreach ($request->file('file') as $photo) {
1
Don't Panic 13 Сен 2017 в 10:04

Кажется, это не проблема dropzone.js для меня. В сообщении об ошибке говорится «неопределенный метод ...» (laravel), поэтому метод недоступен для вашего объекта photo.

Посмотрите документы в Laravel. ( https://laravel.com/docs/5.4/filesystem#file-uploads )

Может быть, вы можете попробовать что-то вроде этого:

foreach ($request->files as $photo) {
    $path = Storage::putFile('photos', $photo);
...
2
dns_nx 4 Сен 2017 в 08:39