Friday, July 2, 2010

Integrating CKEditor and CakePHP : Part 4

In Part 3 of the series, I covered how to use the session to communicate from CakePHP to CKFinder the directories in which to browse and upload files. However, that was assuming the usage of PHP sessions in CakePHP. This article will cover how to use CakePHP database sessions.

The goal of this is to write as little code as possible, and make the most out of what has already been done. The term Don't Repeat Yourself (DRY) should be familiar to most (CakePHP) programmers.

So I took a close look at what I could do to make use of the CakePHP sessions. I don't need to start a new one, I just need to access one that might already be there.

Since we already have information getting written to out session via the ckeditor element, I don't need to make any changes there. Although I could probably change the values of path_to_destsvr_image and path_to_destsvr_file to use the DS definition, and it probably wouldn't be a bad thing to use the Session component or CakeSession library (however, as yet, I'm still using $_SESSION).

All the action is going to happen in our app/vendors/ckfinder/config.inc.php file. But first, lets convert the app to use database sessions!

First thing to do is add the cake_sessions table to the database. My CakePHP command lines are a little whacky, but here's what I did.

$ cd app
$ php ..\cake\console\cake.php schema create sessions


That's not quite what they want you to do in the CakePHP 1.3 manual, but it's what I did, and it installed the new table just dandy.

The next thing is to update the CakePHP Core to use the database.

Configure::write('Session.save', 'database');
Configure::write('Session.database', 'default');


Hey presto! CakePHP database sessions.

What we want to do is bootstrap into CakePHP from the config.inc.php, without firing off the CakePHP Dispatcher. So I've made a small change to app/webroot/index.php that will prevent the dispatcher from being run in the presence of a defined variable, EXTERNAL_APP. Almost at the end of the file, make this change:

if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
    return;
} else if (!defined('EXTERNAL_APP')) {
    $Dispatcher = new Dispatcher();
    $Dispatcher->dispatch();
}


Now we can update the vendors/ckeditor/config.inc.php to access the CakeSession object.

<?php 
/**
 * This file is included by the CKFinder config.php, and will
 * set up the basePath and permissions, as is specific for the project
 */
 
define('EXTERNAL_APP', true);
// starts from app/webroot/ckfinder/core/connector/php/connector.php
include_once '../../../../../index.php'; // targetting app/webroot/index.php
 
if (!class_exists('cakesession')) {
 require LIBS . 'cake_session.php';
}
 
$Session = new CakeSession();
$Session->start();
 
// What resource type are we playing with, Image or File
if ($_GET['type'] == 'Images') {
 $baseUrl = $Session->read('path_to_dest_image');
 $baseDir = $Session->read('path_to_destsvr_image'); 
} else  /* if ($_GET['type'] == 'File') */ {
 // File is the default
 $baseUrl = $Session->read('path_to_dest_file');
 $baseDir = $Session->read('path_to_destsvr_file');
}


And that was way too easy. You can now use whatever type of session handling you want, where it be PHP or database, and the information can be shared between CKFinder and CakePHP. I even may use this method to integrate CakePHP with legacy code, as I have previously done with CodeIgniter.

The hard part is going to be integrating Authentication, and using CakePHP ACLs to define CKFinder ACLs. And I'll do a posting on that, just as soon as I work out how to do it.

-- edit: Added in the bit about converting actually use CakePHP database sessions.

Series Index : Part 1, Part 2, Part 3, Part 4, Part 5, Part 6

No comments:

Post a Comment