Какой сайт сейчас может обойтись без редактора? Да, можно добавить поля типа file и загружать. Но когда в материале нужен целых несколько картинок, то это неудобно и не технологично. Но чтобы редактор умел загружать картинку, как редактор должен знать как ее отправить, так и серверная часть знать то, как ее получить, сохранить и вернуть на нее ссылку. Этим и займемся.
Я уже писал о методе бесплатной загрузки картинок в редакторе CKEditor 4. Там же я упоминал что опишу метод загрузки картинок с редактором TinyMCE. Вот в этом материале об этом и будет речь. Для обоих вариантов, что непосредственно установленный на сайте и подключаемый с него, что редактор с облачной загрузкой, серверная часть особо не отличается и в этом примере я покажу именно версию с подгружаемым редактором.
Шаг 1: Идем на сайт TinyMCE
Сам сайт. Регистрируемся. Подтверждаем аккаунт через почту и авторизуемся. Видим перед собой Панель пользователя, с ключом для API.
Шаг 2: Установка редактора на страницу
Вот в синем поле код и есть подключение на страницу. Из него строку:
<script src="https://cdn.tiny.cloud/1/XXXXXXXXXXXXXXXXXXXXXXXXXX/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
Вставляем в шапку, а лучше перед закрывающим тегом </body>. В этой строке, вместо XXXXXXXXXXXXXXXXXXXXXXXXXX должен быть ваш уникальный ключ.
Вторая часть скрипта - запуск самого редактора, немного модифицируем:
<script>
document.addEventListener('DOMContentLoaded', function(){
tinymce.init({
selector: 'textarea',
plugins: 'advlist autolink lists link image charmap print preview hr anchor pagebreak',
toolbar_mode: 'floating',
});
});
</script>
Этот код цепляет редакторы на все элементы textarea на странице. А выполнение скрипта мы обернули в обработчик события, которое наступит после загрузки страницы. Таким образом загрузится вся страница и после уже инициализируется сам редактор.
Но и это еще не все. Для того чтобы редактор подгрузился, он должен быть на разрешенном домене. Для этого идем на вкладку, в меню слева - Approved Domains и в поле вводим домен, на котором сайт работает. Вы можете внести несколько доменов. Введя домен жмем кнопку ADD. Как видим, в списке уже добавлен домен localhost, на тот случай если вы разрабатываете сайт локально. В этом случае добавлять сайт не нужно. Но для каждого домена где отображается редактор должен быть введен домен. В противном случае редактор не загрузится.
То есть, в самом простом виде ваша страница должна выглядеть так:
<html>
<head>
<title>TinyMCE Example</title>
</head>
<body>
<textarea name="body" rows="6"></textarea>
<script src="https://cdn.tiny.cloud/1/XXXXXXXXXXXXXXXXXXXXXXXXXX/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
<script>
document.addEventListener('DOMContentLoaded', function(){
tinymce.init({
selector: 'textarea',
plugins: 'advlist autolink lists link image charmap print preview hr anchor pagebreak',
toolbar_mode: 'floating',
});
});
</script>
</body>
</html>
Когда мы закончили с подключением редактора на страницу, переходим к загрузке фото из него.
Шаг 3: Вносим правки в код инициализации редактора
В этом шаге мы меняем часть кода, отвечающую за инициализацию редактора, добавляя в нее обработчик загрузки файла. Кроме этого в коде будет еще несколько моментов, которые вы можете использовать и в своих задачах, по своему усмотрению.
<script>tinymce.init({
width : "100%",
//здесь добавили возможность не подключать редактор на элементы с классом mceNoEditor
selector: 'textarea:not(.mceNoEditor)',
//подключили русский язык
language:"ru",
//я замени идущие полным набором расширения на меньшее количество версий
//plugins: 'a11ychecker advcode casechange quickbars formatpainter linkchecker autolink lists checklist media mediaembed pageembed permanentpen powerpaste table advtable tinycomments tinymcespellchecker image code fullscreen',
//и настроил панель по своему
//toolbar: 'a11ycheck addcomment showcomments casechange checklist code formatpainter pageembed permanentpen table blockquote numlist bullist fullscreen',
plugins: 'quickbars autolink lists media image code fullscreen link',
toolbar: 'code formatpainter table blockquote numlist bullist fullscreen link unlink removeformat',
toolbar_mode: 'floating',
tinycomments_mode: 'embedded',
//toolbar: false,
menubar: false,
//inline: true,
tinycomments_author: 'guest',
// images_upload_url: 'postAcceptor.php',
//automatic_uploads: false,
//вместо отправки в файл, добавим свой обработчик загрузки
images_upload_handler: function (blobInfo, success, failure) {
//методом JavaScript создаем форму
var xhr, formData;
//создаем обьект отправки запроса аяксом
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
//указываем ему action на нужную нам ссылку
xhr.open('POST', '/uploader/tiny');
//подставляем csrf токен в заголовок, чтобы сайт не выбивал нам ошибку об устаревшей форме
//или запрете ее отправки
var token = '{{ csrf_token() }}';
xhr.setRequestHeader("X-CSRF-Token", token);
xhr.onload = function() {
//в этой функции обаботка ошибки
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
//в противном случае вызываем калбек успеха
success(json.location);
};
//создаем отправлямые данные формы
formData = new FormData();
//добавляем к ней поле с нашим файлом
formData.append('file', blobInfo.blob(), blobInfo.filename());
//отправляем
xhr.send(formData);
}
});</script>
Максимально сколько мог и считал нужным, описал комментариями код обработки загрузки файла на сервер. Теперь очередь добавить обработку на сторону Laravel.
Шаг 4: Контроллер обработки загрузки файла на Laravel, а так же роутинг
Идем в папку Laravel, в консоли и выполняем команду добавления контроллера:
php artisan make:controller Fileuploader
После выполнения, создастся файл контроллера в папке app\Http\Controllers, в него добавляем обработку загрузки файла:
<?php namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Request;
class Fileuploader extends Controller {
public function uploadTiny(Request $request){
//если установлен плагин DebugBar, функция ниже его отключает для запроса
app('debugbar')->disable();
//проверяем загружается ли файл с названием file
if (\request()->file('file',false)){
//получаем расширение файла
$fileFormat = \request()->file('file')->getClientOriginalExtension();
//проверяем на допустимый формат
$PhotoValidFormat = array('jpg', 'png', 'gif', 'jpeg', 'bmp');
//проверяем есть ли ошибка при загрузке файла
if (in_array(strtolower($fileFormat), $PhotoValidFormat) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
//создаем новое имя для файла
$PhotoName = uniqid() . '.' . \request()->file('file')->getClientOriginalExtension();
//получаем и проверяем размер файла
$fileSize = number_format($_FILES['file']['size'] / 1048576, 2);//to mb
if ($fileSize <= 50) {
//если размер допустимый, перемещаем файл в папку uploaded
//не забудьте ее создать, а так же прописать путь в файле config/filesystems.php,
//в моем случае это подобного вида:
//'uploaded' => [
// 'driver' => 'local',
// 'root' => storage_path().'/public/images/uploaded',
// ],
//перемещаем файл и проверяем перемещение на успешность
if ( \request()->file('file')->move(storage_path('uploaded'), $PhotoName)) {
return json_encode(array(
'location'=>env('APP_URL').'/storage/uploaded/'.$PhotoName
));
} else
$res = -1;
} //bad format or size not allowed for php.ini
else {
if (isset($_FILES['file']['error']) && $_FILES['file']['error'] == 1)
$res = -1;
else
$res = 0;
}
//возвращаем в обработчик нужный формат ответа
echo json_encode(array('res' => $res));
}
}
}
}
Да, кто-то вполне корректно может заметить что можно использовать функции фреймворка и код изящнее, но я добавлял этот код давно и он просто работает, а времени на переписывание конкретно этого куска у меня нет. Так что, если кто-то желает, может загрузить свой материал или написать функцию в комментариях. А мы двигаемся дальше.
Нужно добавить роутинг. В файл routes/web.php добавляем строки:
Route::group(['prefix'=>'uploader'],function(){
Route::match(['get','post'],'/tiny',[\App\Http\Controllers\Fileuploader::class,'uploadTiny']);
});
Результат теперь виден в редакторе
Собственно на этом все.
Отзывы
Пока нет комментариев
Для того чтобы оставить комментарий, авторизуйтесь.