Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dropzone no valid MIME type in backend Laravel?

I have really no idea where the problem resides to be honest.

Might be Dropzone, Laravel (5.4), ... So I truly hope even a thought might help me get past this problem.

When I upload files, I don't get any js issues but Laravel throws me following error (for each file):

Call to undefined method Symfony\Component\HttpFoundation\File\UploadedFile::store()

This is my backend code (Error is set in the portfolioStore method):

    <?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');
    } }

In any case, here is my Dropzone config:

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);
};

Here is the view:

@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

So now I'm wondering whether the issue is related to a MIME type being undefined which cause the store method to not work. Or should I be looking elsewhere?

Any advice, ideas welcome :)

like image 525
Goowik Avatar asked Sep 04 '17 07:09

Goowik


2 Answers

The problem here is that the $request->files does not exist in the Laravel codebase. Since the Illuminate\Http\Request class extends the Symfony\Component\HttpFoundation\Request class, the files refers to the Symfony\Component\HttpFoundation\FileBag class which does happens to contain numerous Symfony\Component\HttpFoundation\File\UploadedFiles that do not have the store method.

Simple fix: Replace $request->files with $request->allFiles() which should give you an array of Illuminate\Http\UploadedFile classes which have the store method

Feel free to shoot any questions in the comment section if you need further help

like image 177
Paras Avatar answered Oct 03 '22 23:10

Paras


This seems to be no issue of dropzone.js to me. The error says "undefined method..." in the backend (laravel), so the method is not available to your object photo.

Have a look at the docs in laravel. (https://laravel.com/docs/5.4/filesystem#file-uploads)

Maybe you can try something like this:

foreach ($request->files as $photo) {
    $path = Storage::putFile('photos', $photo);
...
like image 33
dns_nx Avatar answered Oct 03 '22 23:10

dns_nx