hamiha's avatar
Level 17

TincyMCE image upload to server with Laravel

Hello guys,

I'm tyring to upload images with TincyMCE cloud API version. So far submitting textarea with plain text works, but I'm stuck at adding images. I want to upload images to server storage, return URL link and save it in textarea with TinyMCE. I made a route that saves image and returns json with image path, but I get 500 TokenMismatchException in console, before it even hits the end point. I see the image in TincyMCE editor, but i also get red alert: Failed to upload image: HTTP Error: 500. Do i need to somehow add X-CSRF token when sending to the controller?

HTML code:

 <form method="POST" action="/news" enctype="multipart/form-data">
     {{ csrf_field() }}              
      <!--  Form Input  -->
            <textarea class="form-control" name="body" id="body" rows="8">
                 {{ old('body') }}
            </textarea>          
</form>

Here is the tinymce script:


<script>
        tinymce.init({
            selector: 'textarea',
            height: 500,
            setup: function (editor) {
                editor.on('init change', function () {
                    editor.save();
                });
            },
            plugins: [
                "advlist autolink lists link image charmap print preview anchor",
                "searchreplace visualblocks code fullscreen",
                "insertdatetime media table contextmenu paste imagetools"
            ],
            toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
            content_css: [
                '//fonts.googleapis.com/css?family=Lato:300,300i,400,400i',
                '//www.tinymce.com/css/codepen.min.css'
            ],
            image_title: true,
            automatic_uploads: true,
            images_upload_url: '/upload',
            file_picker_types: 'image',
            file_picker_callback: function(cb, value, meta) {
                var input = document.createElement('input');
                input.setAttribute('type', 'file');
                input.setAttribute('accept', 'image/*');
                input.onchange = function() {
                    var file = this.files[0];

                    var reader = new FileReader();
                    reader.readAsDataURL(file);
                    reader.onload = function () {
                        var id = 'blobid' + (new Date()).getTime();
                        var blobCache =  tinymce.activeEditor.editorUpload.blobCache;
                        var base64 = reader.result.split(',')[1];
                        var blobInfo = blobCache.create(id, file, base64);
                        blobCache.add(blobInfo);
                        cb(blobInfo.blobUri(), { title: file.name });
                    };
                };
                input.click();
            }
        });
    </script>


and the controller method, that is called on /upload ->

public function store()
    {
        $imgpath = request()->file('name')->store('uploads', 'public');
        return json_encode(['location' => $imgpath]);
    }

If i try to just save image in blob version straight to the database it works, but i think that using storage and URL would be better for performance.

Any help would be very appreciated.

0 likes
5 replies
hamiha's avatar
hamiha
OP
Best Answer
Level 17

I solved the problem with bypassing csrf verification by adding the following code in VerifyCsrfToken class

 protected  $except = [ '/upload' ];

and changing the store function to :

public function store()
{
    $imgpath = request()->file('name')->store('uploads', 'public');
    return response()->json_encode(['location' => $imgpath]);
}
1 like
eflames's avatar

This code works for me perfectly thanks... in 5.9 with tiny changes

return response()->json(['location' => '/' . $imgpath]);

json instead json_encode and concatenate '/' in response for image preview in form and using 'file' as a request->file name.

Sorry for my english btw. xD

lordzeph's avatar

Can you comment about where and how to add the controller method /upload? And where to add the function store() ? In my code I had 2 VerifyCsrfToken classes, which one I have to change?

  • Illuminate\Foundation\Http\Middleware\VerifyCsrfToken

or

  • Illuminate\Foundation\Http\Middleware\VerifyCsrfToken

I had to change "/upload" by "upload" in the script, but I dont know If I have to change it on VerifyCsrfToken too.

In the function store you wrote "uploads" with an "s", is that right?

Whithout "upload" in the script, I got no errors, but it will keep saving my images on database.

I will appreciate your help.

siddharth_9's avatar

My question is the image is uploaded and saved in the folder in the server side in the given path but if a user uploads 5 images and deletes 4 images then I should delete 4 images from the folder in the given path.

So if any user will press backspace key and delete key then delete should be done from whatever folder it is saved then please let me know or share me the code.

Please or to participate in this conversation.