Saturday, September 26, 2015

Getting CKEditor to work with laravel 5.1

I rarely code in PHP these days but I had to use  Laravel, a great framework, for one of my project. My project required a WYSIWYG editor for its blogging section. I thought of giving ckeditor a try. The installation process was fairly simple.  All I had to do was place the necessary files/folders inside public directory (in my case) and then link the ckeditor.js file in my html. You can also use CDN to include ckeditor.The installation process was painless, however I found it very hard to get the file browser working. In this tutorial, I will talk about getting the file browser up and running.

During the time of writing this, my laravel version is 5.1.17(LTS). I am using Linux Mint 17.1 , sublime text 3 as my text editor, nginx as my server and mysql as my database. Except my laravel version and OS, the others are just extraneous, haha.

Ok, click in the editor`s image icon. You will see that there is no upload option.

To activate upload option, you have to add filebrowserImageUploadUrl.

CKEDITOR.replace('editor1',{
        filebrowserImageUploadUrl : "{{route('infos.upload',['_token' => csrf_token() ])}}",
        filebrowserWindowWidth  : 800,
        filebrowserWindowHeight : 500
    });



Here the filebrowserImageUploadUrl , will send a POST request to the route. If you remove the '_token' => csrf_token() you will get a tokenMismatch error.filebrowserWindowWidth & filebrowserWindowHeight is related with the appearance of the popup window`s dimension.

Lets create a route for 'info.upload'.

Route::post('infos/uploadImage',[
        'as' => 'infos.upload',
        'uses' => 'InfoController@uploadImage'
    ]);


uploadImage method in InfoController

public function uploadImage(Request $request)
    {
        $file = $request->file('upload');
        $uploadDestination = public_path() . '/uploads/about';
        $filename = preg_replace('/\s+/', '', $file->getClientOriginalName());
        $fileName = md5($filename) . "_" . $filename;
        $file->move($uploadDestination, $fileName);
    }


All the uploaded files will be upload to uploads/about folder, which is arbitrary.

At this point, your file should be uploaded. If not try opening your developers tool and check the network tab, there you can trace any errors.

Ok, now your file has been uploaded but you have to include it . To do that you have to add certain keys.
CKEDITOR.replace('editor1',{
        filebrowserBrowseUrl: "{{route('infos.image.browse')}}",
        filebrowserUploadUrl : '/browser/upload/type/all',
        filebrowserImageBrowseUrl: "{{route('infos.image.browse')}}",
        filebrowserImageUploadUrl : "{{route('infos.upload',['_token' => csrf_token() ])}}",
        filebrowserWindowWidth  : 800,
        filebrowserWindowHeight : 500
    });


Lets take a look at the routes now.

Route::post('infos/uploadImage',[
        'as' => 'infos.upload',
        'uses' => 'InfoController@uploadImage'
    ]);

    Route::get('infos/image/browse',[
        'as' => 'infos.image.browse',
        'uses' => 'InfoController@browseImage'
    ]);


This will how our controller looks right now:

public function uploadImage(Request $request)
    {
        $file = $request->file('upload');
        $uploadDestination = public_path() . '/uploads/about';
        $filename = preg_replace('/\s+/', '', $file->getClientOriginalName());
        $fileName = md5($filename) . "_" . $filename;
        $file->move($uploadDestination, $fileName);
    }

    public function browseImage(Request $request)
    {
        $test = $_GET['CKEditorFuncNum'];
        $images = [];
        $files = \File::files(public_path() . '/uploads/about');
        foreach ($files as $file) {
            $images[] = pathinfo($file);
        }
        return view('infos.file',[
            'files' => $images,
            'test' => $test
        ]);
     
    }


This will be the contents of our view file
@extends('app')

@section('content')
    @foreach($files as $file)
        <a href='{{url("uploads/about/".$file["basename"])}}'><img src='{{url("uploads/about/".$file["basename"])}}'></a>
    @endforeach
@endsection

@section('footer')
<script type="text/javascript">
$('a[href]').on('click', function(e){
    window.opener.CKEDITOR.tools.callFunction(<?php echo $test; ?>,$(this).find('img').prop('src'))
});
</script>
@endsection


This line of code window.opener.CKEDITOR.tools.callFunction(<?php echo $test; ?>,$(this).find('img').prop('src')) gets the url of clicked image and then put it into the url field.
That`s all there is to it.
If you run into any problem, leave a comment below. I hope to sort it out.

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Hello community
    Our team currently develop browser extension for better CDN hosting performance.
    Please follow the link and vote for one of these providers:
    I create a little survey and I really appreciate if we get some market information.
    CDN survey
    Microsoft Azure
    Namecheap CDN
    Cloudflare
    KeyCDN

    But is you didn't use any please don't answer at all.
    Very thank you.

    ReplyDelete