Laravel, CKEditor, filemanager and fix filemanager image URL issue

Are you looking for file upload functionality with CKEditor and Laravel?
I hope this blog post will help you.

1. Download the Ckeditor. This blog post is using Ckeditor 4. Unzip the downloaded file and put the extracted “ckeditor” folder under the Laravel Public folder. So we can use it in the Laravel View file.

2. Download the file manager. After downloading the package. Unzip the file and put the extracted folder under the “public/ckeditor” folder.

3. Create a controller class and add CKEditor file upload and browse functions.

<?php 
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Storage;

class Editor extends Controller {
	
	public function index(){
		return view('editor');
	}
	
	public function upload( Request $request ){
		if($request->hasFile('upload')) {
		
            //get filename with extension
            $fileNameWithExtension = $request->file('upload')->getClientOriginalName();
      
            //get filename without extension
            $fileName = pathinfo($fileNameWithExtension, PATHINFO_FILENAME);
      
            //get file extension
            $extension = $request->file('upload')->getClientOriginalExtension();
      
            //filename to store
            $fileNameToStore = $fileName.'_'.time().'.'.$extension;
      
            //Upload File
            $request->file('upload')->storeAs('public/uploads', $fileNameToStore);
 
            $CKEditorFuncNum = $request->input('CKEditorFuncNum');
            $url = asset('storage/uploads/'.$fileNameToStore); 
            $msg = 'Image successfully uploaded'; 
            $renderHtml = "<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3Ewindow.parent.CKEDITOR.tools.callFunction(%24CKEditorFuncNum%2C%20'%24url'%2C%20'%24msg')%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />";
			
            // Render HTML output 
            @header('Content-type: text/html; charset=utf-8'); 
            echo $renderHtml;
			
        }
	}
	
	public function browse( Request $request ){
		
		$files = Storage::files('public/uploads');
		//dd($files);
		$CKEditorFuncNum = $request->input('CKEditorFuncNum');
		
		$msg = 'Image successfully uploaded'; 
		foreach( $files as $file){
			$url = asset('storage/uploads/'.str_replace('public/uploads/', '', $file));
			$renderHtml = "<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%09%09%09function%20returnFileUrl()%20%7B%0A%09%09%09%09window.parent.CKEDITOR.tools.callFunction(%24CKEditorFuncNum%2C%20'%24url')%3B%0A%09%09%09%09window.close()%3B%0A%09%09%09%7D%0A%09%09%09%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />";
			$renderHtml .='<button onclick="returnFileUrl()">Select File</button>';
		}
		
		// Render HTML output 
		@header('Content-type: text/html; charset=utf-8'); 
		echo $renderHtml;
		
	}
}

4. Add Routes

Route::get('editor', 'Editor@index');
Route::post('ckeditor/image_upload', 'Editor@upload')->name('upload');
Route::get('ckeditor/image_browse', 'Editor@browse')->name('browse');

5. Create a view file to display the text editor.

<div class="container">
		<div class="row align-items-center">
			<div class="col">
				<h1 class="mb-3 text-center">Editor Testing</h1>
				<form method="POST" action="">
					@csrf
					<div class="row">
						<div class="col-lg-12 grid-margin stretch-card">
							<div class="card">
								<div class="card-body">
									@if ($errors->any())
										<div class="alert alert-danger">
											<ul class="">
												@foreach ($errors->all() as $error)
													<li>{{ $error }}</li>
												@endforeach
											</ul>
										</div>
									@endif
									
									<h4 class="card-title">{{ __('Page Content') }}</h4>
									<p class="card-description"></p>
									<div class="row">
										<div class="col-md-12">
											<div class="form-group">
												<label class="label">Page Title</label>
												<input type="text" class="form-control" name="title" value="{{ old('title') }}"/>
											</div>
										</div>
										<div class="col-md-12">
											<div class="form-group">
												<label class="label">Page Sub Heading</label>
												<input type="text" class="form-control" name="sub_title" value="{{ old('sub_title') }}"/>
											</div>
										</div>
										<div class="col-md-12">
											<div class="form-group">
												<label class="label">Page Content</label>
												<textarea class="form-control" id="content" name="content">{{ old('content') }}</textarea>
											</div>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
					
					
					<div class="row">
						<div class="col-lg-12">
							<div class="form-group">
								<div class="col-md-12 text-center">
									
									<button type="submit" class="btn btn-primary btn-lg">
										{{ __('Submit') }}
									</button>
								</div>
							</div>
						</div>
					</div>
				</form>
			</div>
		</div>
	</div>

6. Setup the CKEditor in the view file. Add following code at bottom in view file.

&lt;script src="{{ asset('ckeditor/ckeditor.js') }}"&gt;&lt;/script&gt;
&lt;script&gt;
CKEDITOR.config.allowedContent = true;
    CKEDITOR.replace('content', {
        filebrowserUploadUrl: "{{route('upload', ['_token' => csrf_token() ])}}",
        filebrowserUploadMethod: 'form',
		filebrowserBrowseUrl : "{{asset('ckeditor/filemanager/dialog.php')}}?type=2&editor=ckeditor&fldr=",
		filebrowserImageBrowseUrl : "{{asset('ckeditor/filemanager/dialog.php')}}?type=1&editor=ckeditor&fldr=",
        
    });
&lt;/script&gt;

7. Enable the Laravel Storage Link to execute the following command.

php artisan storage:link

8. Setup the filemanager configuration “public/ckeditor/filemanager/config/config.php“.

On line number 79.

'upload_dir' => '../../storage/',

On line number 80

'current_path' => '../../storage/',

We are updating the file storage path because we are using the Laravel storage link.

9. Fix the file path error. As per the screenshot, you might be facing this issue, so we can fix this with a small change in “public/ckeditor/filemanager/include.js

10. Either you can be using the “beutifyjs” tool to make more readable the JS file. Search the “function m(e)” function in this file and replace the full function with the following code.

function m(e) {
        var a = jQuery("#cur_dir").val();
        a = a.replace("\\", "/");
		a = a.replace("../../", "/");
        var t = jQuery("#sub_folder").val();
        t = t.replace("\\", "/");
		t = t.replace("../../", "/");
        var r = jQuery("#base_url").val(),
            i = jQuery("#fldr_value").val();
        i = i.replace("\\", "/");
		i = i.replace("../../", "/");
        for (var n = [], l = jQuery("#return_relative_url").val(), o = 1 == jQuery("#ftp").val(), u = 0; u < e.length; u++) {
            var c = e[u];
            o ? n.push(encodeURL(jQuery("#ftp_base_url").val() + jQuery("#upload_dir").val() + i + c)) : n.push(encodeURL((1 == l ? t + i : r + a) + c))
        }
        return n
    }

11. If you found the warning message on the file upload dialog box. It’s just because the error log is enabled. You can disable it. Place this code in “public/ckeditor/filemanager/dialog.php

ini_set('display_errors', 'off');