CakePHP / DokuWiki integration

I want to use DokuWiki as 'CMS', and 'fit' some CakePHP applications in it… The hard part is sharing page layout (template) and user credentials in a transparent way.

Two approaches...

NOTE: this is 'work in progress'.

  1. Create a DokuWiki page with PHP code that invokes the CakePHP dispatcher, and render its output.
  2. Just create a normal CakePHP application, use an empty DokuWiki pages as layout.

The 2nd approach seemed the most promising.

Name conficts

Problems occur when including DokuWiki files in a CakePHP project: both use a Cache class. The easy solution is to change 'cache' into 'dokucache' in 2 lines of DokuWiki's inc/cache.php

class dokucache {
class cache_parser extends dokucache {

Getting the DokuWiki user info

Config

Doku keeps its user info in the session. Cake can access it by sharing the same session cookie. By default Doku uses 'DokuWiki'. For Cake this can be set in config.core.php. We also have to set the cookie path to '/'…

//Configure::write('Session.save', 'php');
Configure::write('Session.save', 'my_session');
Configure::write('Session.cookie', 'DokuWiki');

my_session.php:

<?php
// app/config/my_session.php
//
// Revert value and get rid of the referrer check even when,
// Security.level is medium
ini_restore('session.referer_check');
 
ini_set('session.use_trans_sid', 0);
ini_set('session.name', Configure::read('Session.cookie'));
 
// Cookie is now destroyed when browser is closed, doesn't 
// persist for days as it does by default for security
// low and medium
ini_set('session.cookie_lifetime', 0);
 
// Cookie path is now '/' even if you app is within a sub 
// directory on the domain
$this->path = '/';
ini_set('session.cookie_path', $this->path);
 
// Session cookie now persists across all subdomains
ini_set('session.cookie_domain', env('HTTP_BASE'));
?>

The session data can be displayed in a Doku page

<php>
echo '<p>session: name=' . session_name() . ', id='  . session_id() .'</p>' ;
echo("<pre>" . print_r($_SESSION, true) . '</pre>');
</php>

or a Cake view with:

<?php echo '<p>session: name=' . session_name() . ', id='  . session_id() .'</p>' ; ?>
<?php debug($_SESSION);?>

Usage

I choose to 'fetch' the user info in AppController:beforeFilter(). In this way the user information is available in all controllers:

class AppController extends Controller {
  function beforeFilter() {
    $result=array();
    $info = Set::classicExtract($this->Session->read(), '{s}.auth.info');
    foreach($info as $k) {        
      if (is_array($k)) {
        $result=$k;
      }
    }
    $this->set('userInfo', $result);
  }
}

In a view it can be displayed like:

<?php debug($userInfo);?>

which look like:

Array
(
    [pass] => $1$970eac71$dHPGOff8472KIHLLw1jpB/
    [name] => hansel
    [mail] => fijnesite@hpelbers.org
    [grps] => Array
        (
            [0] => admin
            [1] => user
        )
)

Getting the layout right

Quick and dirty way:

  • fetch a 'normal' page and save it as layout (views/layouts/doku.ctp
  • replace content part with '<?php echo $content_for_layout ?>'
  • add appropriate css file
  • add '$this→layout='doku';' in AppController:beforeFilter() in app_controller.php
   
Last modified: 2009/12/30 16:14 Mijn Fijne Site hosting en design