I think this is the wright channel to aks this Questtion.
Hi I want to use CKEeditor for my blog.
The text is working, but when I add an image to the textarea I get immediately an error Cannot upload file: name.extention.
When I check the network tab I have an error 500 xhr.
I tried this locally and on my domain. same error.
This is my code:
Route
Route::post('upload', [\App\Http\Controllers\admin\PostController::class, 'upload'])->name('upload');
Blade/Livewire post-add.blade.php
@push('styles')
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
@endpush
<div class="p-6 bg-white border border-gray-200 shadow-md dark:bg-gray-800 dark:border-gray-700">
<form wire:submit.prevent="save" enctype="multipart/form-data" method="POST" class="space-y-6">
@csrf
<div class="flex justify-between space-x-4">
<div class="w-1/2">
<x-form.label for="title" value="Title" />
<x-form.input wire:model="title" type="text" name="title" required />
<x-form.input-error for="title" class="mt-2" />
</div>
<div class="w-1/2">
<x-form.label for="categories" value="Categories" />
<div wire:ignore>
<select id="categories" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 select2" multiple>
@foreach($categories as $category)
<option value="{{ $category->id }}">{{ $category->title }}</option>
@endforeach
</select>
</div>
<x-form.input-error for="post.categories" class="mt-2" />
</div>
</div>
<div class="flex space-x-4">
<div class="w-1/2">
<x-form.label for="image" value="Image" />
<x-form.input wire:model="image" name="image" type="file" required />
<div wire:loading wire:target="image">
<x-popups.loading />
</div>
<x-form.input-error for="image" class="mt-2" />
</div>
</div>
<div wire:ignore>
<x-form.label for="body" value="Post" />
<x-form.textarea wire:model.defer="body" name="body" id="body" />
<x-form.input-error for="body" class="mt-2" />
</div>
<div class="flex items-center space-x-4">
<div class="w-1/2">
<x-form.label for="published_at" value="Date to publish" />
<x-form.input wire:model="published_at" type="date" name="published_at" />
<x-form.input-error for="published_at" class="mt-2" />
</div>
<div>
<label class="relative inline-flex items-center mr-5 cursor-pointer">
<input wire:model="active"
name="active"
id="active"
value="1"
aria-describedby="active"
type="checkbox"
class="sr-only peer"
checked
>
<div class="w-11 h-6 bg-gray-200 rounded-full peer dark:bg-gray-700 peer-focus:ring-4 peer-focus:ring-orange-300 dark:peer-focus:ring-orange-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-orange-500"></div>
<span class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">Active</span>
</label>
</div>
</div>
<div class="flex justify-end space-x-2">
<x-buttons.secondary type="button" onclick="history.back()" class="px-3 py-2 text-xs font-medium">Cancel</x-buttons.secondary>
<x-buttons.primair class="px-3 py-2 text-xs font-medium">Save</x-buttons.primair>
</div>
</form>
</div>
@push('scripts')
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<script src="https://cdn.ckeditor.com/ckeditor5/31.1.0/classic/ckeditor.js"></script>
<script>
document.addEventListener("livewire:load", () => {
let el = $('#categories')
initSelect()
Livewire.hook('message.processed', (message, component) => {
initSelect()
})
Livewire.on('setCategoriesSelect', values => {
el.val(values).trigger('change.select2')
})
el.on('change', function (e) {
@this.set('post.categories', el.select2("val"))
})
function initSelect () {
el.select2({
placeholder: '{{__('Select your option')}}',
allowClear: !el.attr('required'),
})
}
})
</script>
<script>
ClassicEditor
.create(document.querySelector('#body'), {
ckfinder: {
uploadUrl: '{{ route('admin.upload', ['_token' => csrf_token()]) }}'
}
})
.catch(error => {
console.error(error);
});
</script>
@endpush
Controller PostController
<?php
namespace App\Http\Controllers\admin;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Post;
use Cviebrock\EloquentSluggable\Services\SlugService;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('admin.posts.index');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$categories = Category::all();
return view('admin.posts.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(Post $post)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Post $post)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Post $post)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Post $post)
{
//
}
public function upload(Request $request)
{
try {
$post = new Post();
$post->id = 0;
$post->exists = true;
$image = $post->addMediaFromRequest('upload')->toMediaCollection('thumb');
return response()->json([
'uploaded' => true,
'url' => $image->getUrl('thumb')
]);
} catch (\Exception $e) {
return response()->json(
[
'uploaded' => false,
'error' => [
'message' => $e->getMessage()
]
]
);
}
}
}
Livewire PostAdd
<?php
namespace App\Http\Livewire\Admin\Posts;
use App\Models\Category;
use App\Models\Post;
use Cviebrock\EloquentSluggable\Services\SlugService;
use Livewire\Component;
use Livewire\WithFileUploads;
class PostAdd extends Component
{
use WithFileUploads;
public $categories = [];
public $title;
public $slug;
public $image;
public $body;
public $active;
public $published_at;
public $post = [
'categories' => []
];
protected $rules = [
'title' => 'required|min:3',
'slug' => 'required|string',
'image' => 'nullable|mimes:jpg,jpeg,png,svg,gif|max:2048',
'body' => 'nullable|min:10',
'active' => 'nullable',
'published_at' => 'nullable',
'post.categories' => 'array',
'post.categories.*' => 'required|integer',
];
public function updatedTitle()
{
$this->slug = SlugService::createSlug(Post::class, 'slug', $this->title);
}
public function mount()
{
$this->categories = Category::all();
$this->user_id = current_user()->id;
}
public function save()
{
$this->validate();
$post = Post::create([
'user_id' => $this->user_id,
'title' => $this->title,
'slug' => $this->slug,
'body' => $this->body,
'active' => $this->active,
'published_at' => $this->published_at,
]);
$this->image->storeAs('posts', $post->id.'.'.$this->image->extension());
$post->update(['image' => 'posts/'.$post->id.'.'.$this->image->extension()]);
$post->categories()->sync($this->post['categories']);
$this->reset('post');
$this->emit('setCategoriesSelect', []);
session()->flash('success', 'Blogpost has been created');
return redirect()->route('admin.posts.index');
}
}
I can't figured out what I'm doing wrong. Please Help me.