Загрузка изображений в Ckeditor 4 для Laravel 5.3

В небольших проектах, где требуется минимальный функционал от wysiwyg редактора, я использую стандартную версию Ckeditor. ckeditor позволяет вставлять в текст изображения, загружая их перед этим на сервер. Обычно этим занимается файловый менеджер, который открывается при нажатии на кнопку "Обзор файлов"

ckeditor-insert-image.jpg

Но иногда функционал файлового менеджера избыточен. Требуется просто выбрать файл на компьютере, загрузить его и вставить в текст. Для этого используется плагин uploadimage, который необходимо подключить к ckeditor. Удобно сразу сконфигурировать ckeditor с этим плагином, чтобы не мучаться с разрешением зависимостей этого плагина. Uploadimage добавляет новую вкладку в окно вставки изображения.

ckeditor-upload-image-tab.jpg

Чтобы плагин заработал, нужно в конфигурационном файле ckeditor config.js необходимо прописать путь до обработчика загрузок изображений на сервере.

public/ckeditor/config.js

config.filebrowserUploadUrl = '/upload-image';

На этом настройка ckeditor завершена. Теперь реализуем функционал загрузки на сервере. Добавим новый роут в файле web.php. Для упрощения и наглядности, код загрузки изображения я не буду выносить в отдельный контроллер, а напишу прямо роутах.

routes/web.php

Route::post('upload-image', function(
    \Illuminate\Http\Request $request,
    Illuminate\Contracts\Validation\Factory $validator
) {
    $v = $validator->make($request->all(), [
        'upload' => 'required|image',
    ]);

    $funcNum = $request->input('CKEditorFuncNum');

    if ($v->fails()) {
        return response(
            "<script>
                window.parent.CKEDITOR.tools.callFunction({$funcNum}, '', '{$v->errors()->first()}');
            </script>"
        );
    }

    $image = $request->file('upload');
    $image->store('public/uploads');
    $url = asset('storage/uploads/'.$image->hashName());

    return response(
        "<script>
            window.parent.CKEDITOR.tools.callFunction({$funcNum}, '{$url}', 'Изображение успешно загружено');
        </script>"
    );
});

Здесь я валидирую входящие данные, и, если валидация пройдена, загружаю изображение в папку public/uploads. Т.к. используется Laravel 5.3, то изображение сохраняется в папку storage, которая не доступна из Web. Поэтому необходимо создать симлинк в эту папку командой php artisan storage:link. Всё это подробно описано в документации: https://laravel.com/docs/5.3/filesystem#the-public-disk.

Т.к. ckeditor присылает изображение POST запросом, а laravel проверяет CSRF токен, который ckeditor не передаёт, необходимо вписать только что созданный роут в исключения, чтобы laravel не проверял token:

app/Http/Middleware/VerifyCsrfToken.php

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'upload-image',
    ];
}