Laravel: Добавление CKEditor 5 и сохранение его в базе данных MySQL
CKEditor - это широко используемый WYSIWYG (What You See Is What You Get) редактор. Он предоставляет все основные функции, необходимые для форматирования.
Редактор отлично работает, но для загрузки файлов через редактор необходимо написать дополнительный код.
В этом руководстве я покажу, как можно добавить CKeditor 5 к HTML-элементу и сохранить его в базе данных MySQL в Laravel 9.
1. Конфигурация базы данных
Откройте файл .env. Укажите хост, имя базы данных, имя пользователя и пароль.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tutorial
DB_USERNAME=root
DB_PASSWORD=
2. Структура таблицы
Создайте новую таблицу messages с помощью миграции.
php artisan make:migration create_messages_table
- Теперь перейдите в папку database/migrations/ из корня проекта.
- Найдите файл PHP, который заканчивается на create_messages_table, и откройте его.
- Определите структуру таблицы в методе up().
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->string('subject');
$table->text('message');
$table->timestamps();
});
}
Запустите миграцию
php artisan migrate
3. Модель
Создайте модель сообщений
php artisan make:model Messages
- Откройте файл app/Models/Messages.php.
- Укажите назначаемые атрибуты модели - тему и сообщение, используя свойство $fillable.
Готовый код
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Messages extends Model
{
use HasFactory;
protected $fillable = [
'subject','message'
];
}
4. Контроллер
Создайте контроллер PagesController
php artisan make:controller PagesController
Импортируйте модель Validator, Session и Messages.
Создайте 3 метода
- index() - Загрузить представление индекса.
- uploadFile() - С помощью этого метода загрузите выбранный файл из CKEditor. Доступ к файлу по имени загружаемого файла.
Проверьте файл. Если файл не валидирован, присвойте $data['uploaded'] значение 0, а сообщение об ошибке - $data['error']['message'].
Если проверка прошла успешно, загрузим файл в папку uploads.
После загрузки присвойте $filename значение $data['fileName'], 1 - $data['uploaded'], а $filepath - $data['url'].
- submitform() - С помощью этого метода обработайте отправку формы.
Проверьте правильность введенных значений. Если они не прошли валидацию, вернем на страницу с сообщением об ошибке, иначе вставляем новую запись в таблицу messages и укажим сообщение об успехе в SESSION flash.
Перенаправим страницу на /.
Готовый код
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Session;
use App\Models\Messages;
class PagesController extends Controller
{
public function index(){
return view('index');
}
// Upload CkEditor file
public function uploadFile(Request $request){
$data = array();
$validator = Validator::make($request->all(), [
'upload' => 'required|mimes:png,jpg,jpeg|max:2048'
]);
if ($validator->fails()) {
$data['uploaded'] = 0;
$data['error']['message'] = $validator->errors()->first('upload');// Error response
}else{
if($request->file('upload')) {
$file = $request->file('upload');
$filename = time().'_'.$file->getClientOriginalName();
// File upload location
$location = 'uploads';
// Upload file
$file->move($location,$filename);
// File path
$filepath = url('uploads/'.$filename);
// Response
$data['fileName'] = $filename;
$data['uploaded'] = 1;
$data['url'] = $filepath;
}else{
// Response
$data['uploaded'] = 0;
$data['error']['message'] = 'File not uploaded.';
}
}
return response()->json($data);
}
// Submit form
public function submitform(Request $request){
$validator = Validator::make($request->all(), [
'subject' => 'required',
'message' => 'required',
]);
if ($validator->fails()) {
return redirect()->Back()->withInput()->withErrors($validator);
}else{
// Insert record
Messages::create([
'subject' => $request->subject,
'message' => $request->message
]);
Session::flash('message','Form submit Successfully.');
}
return redirect('/');
}
}
5. Маршрут (Routes)
Откройте файл routes/web.php и определите в нем 3 маршрута
- / - Загрузка представления индекса.
- /uploadFile - Используется для загрузки выбранного CKEditor файла.
- /submitform - Обработка отправки формы.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PagesController;
Route::get('/', [PagesController::class, 'index']);
Route::post('/submitform',[PagesController::class,'submitform'])->name('submitform');
Route::post('/uploadFile',[PagesController::class,'uploadFile'])->name('uploadFile');
6. Скачать CKEditor 5
Скачайте библиотеку CKEditor 5 отсюда или можете воспользоваться CDN
<!-- ckeditor5 JS -->
<script src="https://cdn.ckeditor.com/ckeditor5/35.4.0/classic/ckeditor.js"></script>
7. Представление (Views)
Создайте файл index.blade.php в папке resources/views/.
HTML
Создайте <form>. Установите ее действие на {{ route('submitform') }}.
Здесь создайте текстовое поле, элемент textarea и кнопку submit. Определите CKEditor для textarea.
Скрипт
Инициализируйте CKEditor на классе .editor. Использование ckfinder для установки URL загружаемого файла.
Установите uploadUrl в "{{route('uploadFile').'?_token='.csrf_token()}}". Здесь передайте CSRF-токен вместе с URL.
Готовый код
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Добавление CKEditor 5 и сохранение его в базе данных MySQL в Laravel</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" >
<style type="text/css">
.ck-editor__editable {
min-height: 250px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 mt-5" style="margin: 0 auto;">
<!-- Alert message (start) -->
@if(Session::has('message'))
<div class="alert alert-success">
{{ Session::get('message') }}
</div>
@endif
<!-- Alert message (end) -->
<form method="post" action="{{ route('submitform') }}">
@csrf
<div class="form-group mb-4">
<label class="control-label col-sm-2" for="subject">Subject:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" placeholder="Enter Subject" name="subject" value="{{ old('subject') }}">
</div>
<!-- Error -->
@if($errors->has('subject'))
<div class='text-danger mt-2'>
* {{ $errors->first('subject') }}
</div>
@endif
</div>
<div class="form-group mb-4">
<label class="control-label col-sm-2" for="message">Message:</label>
<div class="col-sm-10">
<textarea class="form-control editor" name="message"></textarea>
</div>
<!-- Error -->
@if($errors->has('message'))
<div class='text-danger mt-2'>
* {{ $errors->first('message') }}
</div>
@endif
</div>
<div class="form-group ">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-info">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- Script -->
<script src="https://cdn.ckeditor.com/ckeditor5/35.4.0/classic/ckeditor.js"></script>
<script type="text/jаvascript">
ClassicEditor
.create( document.querySelector( '.editor' ),{
ckfinder: {
uploadUrl: "{{route('uploadFile').'?_token='.csrf_token()}}",
}
} )
.then( editor => {
console.log( editor );
} )
.catch( error => {
console.error( error );
} );
</script>
</body>
</html>
Вывод
Данные элемента CKEditor напрямую доступны после отправки на стороне сервера.
Если вы хотите отобразить сохраненные данные CKEditor в базе данных MySQL, то считайте и сохраните их в элементе CKEditor textarea.
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.