Monday, April 02, 2012

Part 2: Create a simple image browser for CKEditor using PHP

Previously, I explained how to create a simple image browser for CKEditor using C# and .NET. In this post, I'll explain how to do the same thing in PHP, assuming you're familiar with PDO and how to query databases. The simple browser will look something like the image below (the styling will of course depend on any CSS you add to your page). This post assumes you already know how to create an instance of CKEditor and are familiar with some Javascript as well.


Problem: CKEditor has no file/image browser included with it.

Impact: The user has to manually input the image file path, which is undesirable because the user may not know the path and you don't want the user to mess around with files.

Solution:
The first thing I did was create a page, just a regular webpage to be the file/image browser, which I called browser.php. As with the .NET example, I created a table called "images" in a MySQL database, with the following columns:

image_id INT
image_filename VARCHAR
image_filepath VARCHAR


Now you can create a function or put an include to call the images from using the images table. The image_filename specifies the file name of the image and the image_filepath is just the directory path minus the file name. So if you keep your images in a folder called "images" put "images/" in the image_filepath column. Each image should have the image path of: image_filepath + image_filename. (You can use mysqli or PDO statements to query the database. It doesn't matter.)

I put each image as a link with a Javascript function I wrote called getUrl() attached to the link's onclick event. Additionally, when the custom browser is opened by CKEditor, it adds a query string to the browser URL like so:

...browser.php?CKEditor=editorname&CKEditorFuncNum=2&langCode=en

The GET variable CKEditorFuncNum is very important. This value will be used in the callback function. You can get it by accessing $_GET['CKEditorFuncNum']. The Javascript callback function you should use to send image URLs back to the editor so that it can populate with the correct URL when you embed the image is:

window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl [, data] );

Note: If the callback doesn't work or there's an error, make sure that you put a reference to the Javascript file "ckeditor.js" found at the ckeditor root folder on the page where you created the instance of CKEditor (e.g. add-article.php).

So you should have something like this for each image (I used PDO and put the retrieved data in the variable $images):

$cback = $_GET['CKEditorFuncNum']; //you should validate this; I didn't for this example
foreach ($images as $img) {
   //rootpath = root path of website
  $imgsrc = $rootpath . $img['image_filepath'] . $img['image_filename'];
  echo '<a href="" onclick="getUrl(' . $cback . ', ' . $imgsrc . ')">';
  echo '<img src="' . $imgsrc . '" />';
  echo '</a>';
}

You can change around the styling and add the file name below the image as well if you want. I did not in this post for simplicity's sake.

Now, write out your getUrl() function. You can either put this in a <script> block in your browser.php file or you can put it in an external Javascript file.

function getUrl(cback, imgfilepath)
{
  window.opener.CKEDITOR.tools.callFunction(cback, imgfilepath);
  window.close(); //close file browser when file chosen
}

Now back in your page where you put an instance of CKEditor, put the following line to let CKEditor know to use your custom file/image browser:

$CKEditor->config['filebrowserBrowseUrl'] = 'your path to your file browser';

Now test it all out. When you click on the image button in CKEditor you should now see a blue button labelled 'Browse Server.' Congratulations! That means CKEditor sees your browser.

Sources:
http://docs.cksource.com/CKEditor_3.x/Developers_Guide/File_Browser_(Uploader)/Custom_File_Browser, CKEditor documentation

4 comments:

  1. Hey,
    I've tried it in different ways, however it doesn't realy work.

    When I'm calling getUrl() nothing realy happens..

    Here's the code I'm using (unfortunatly I was not able to paste it here):

    http://pastebin.com/4CnWcxSs

    Would be great if you could provide me some help because that is exactly what I'm looking for.

    ReplyDelete
    Replies
    1. Hi Felix,

      I noticed you have a space between 'on' and 'click' on line 23 (echo '<a href="" ... '). It should be one word—'onclick'—with no spaces. Try that.

      Delete
    2. Oh thank you, no idea where that came from, but unfortunately that doesn't help to get it working :(

      Delete
    3. Hi Felix,

      I am assuming that you at least see the browser and the "Browse Server" button? Do you also see the images correctly? I would check to be sure all of the needed Javascript files are linked appropriately. As a quick check, you can try putting an alert() in your getUrl() function, one before the callback and one after just to see if it's failing on that line. If it does, check that you're specifying CKEditor's basepath so that the editor can find all of its files.

      See:
      http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Specifying_the_Editor_Path

      http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Integration

      If that still doesn't work, the only thing I can think of would be to check the image path. If you see the image, though, I don't think that would be the problem.

      Hope that helps.

      Delete