Revision [17409]

This is an old revision of WikkaCakeExample made by BrianKoontz on 2007-08-12 03:36:27.

 

A WikkaCake Example


See also: WikkaCake


Overview

If you have yet to read the WikkaCake page, I'd suggest starting there first. This is actually an extension of that page, and provides an example of a completely self-contained Wikka action that has been written using the CakePHP framework. This is not a Cake tutorial. Instead, I will simply provide the code as-is and provide comments that are Wikka-specific.

If one has already set up and tested an embedded WikkaCake environment, then this application should run unmodified (in fact, it is the exact code that's currently running on my own machine).

All directory names are referenced from the top-level "caketest" directory.

This application is a simple database management app for saving, modifying, and deleting servers. It was developed for managing the public nameserver DB on the OpenNIC wiki. A publicly accessible version will be available shortly once testing is completed.

config/database.php
    var $default = array('driver' => 'mysql',
                                'connect' => 'mysql_pconnect',
                                'host' => 'localhost',
                                'login' => 'root',
                                'password' => 'root',
                                'database' => 'wikka_cake',
                                'prefix' => '');

Comments: This is the setup I use on my personal machine (no, it's not externally accessible, so I'm not giving away any state secrets here). Obviously, you will need to modify accordingly. If you haven't done so, simply copy config/database.php.default to config/database.php and modify that. Eventually, this will go away once I work on seamlessly accessing the Wikka DB authentication params.

public_access_servers.sql
CREATE TABLE IF NOT EXISTS public_access_servers (
    id              INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
    ip_addr         VARCHAR(15) NOT NULL,
    internic_hn     VARCHAR(50),
    opennic_hn      VARCHAR(50),
    owner           VARCHAR(50) NOT NULL,
    city            VARCHAR(50),
    state           CHAR(2),
    country         CHAR(2) NOT NULL,
    email           VARCHAR(50),
    last_verified   DATE,
    comments        LONGTEXT);

Comments: This is the DB schema upon which the following code is based. If you modify this, there's a good chance you'll need to modify one or more files below. Note that Cake expect, by default, a primary key called "id".

models/server.php
<?php
    class Server extends AppModel
    {
        var $name = 'Server';
        var $useTable = "public_access_servers";

        var $validate = array(
            'ip_addr' => VALID_NOT_EMPTY,
            'owner' => VALID_NOT_EMPTY,
            'country' => VALID_NOT_EMPTY
        );
    }
?>

Comments: $useTable reflects that fact that I've named my DB table in a non-conforming way.

controllers/servers_controller.php
<?php
    class ServersController extends AppController
    {
        var $name = 'Servers';
        var $layout = 'default';
        //var $wikka = $this->params['wakka'];
        //var $scaffold;

        /*
        function ServersController()
        {
            parent::__construct();
            // This doesn't work, as the params array isn't yet
            // available at time of class object construction!
            //$this->wikka = parent::$this->params['wakka'];
        }
        */


        function index()
        {
            $this->set('servers', $this->Server->findAll());
        }
        function add()
        {  
            if(false===$this->params['wakka']->IsAdmin())
            {  
                $this->redirect($this->base);
            }
            if(true===isset($this->data['Servers']['action']) &&
               false!==strpos($this->data['Servers']['action'], 'Cancel'))
            {  
                $this->redirect($this->base);
                exit;
            }
            uses('sanitize');
            $sanitize = new Sanitize();
            if(empty($this->data))
            {
                $this->render();
            }
            if(!empty($this->data))
            {
                $sanitize->cleanArray($this->data);
                if($this->Server->save($this->data))
                {
                    $this->flash('Your entry has been saved.', '', 1);
                }
                else
                {
                    $this->set('errorMessage', 'Please correct errors below.');
                    $this->render();
                }
            }
        }

        function delete()
        {
            if(false===$this->params['wakka']->IsAdmin())
            {
                $this->redirect($this->base);
            }

            if(isset($this->params['url']['id']))
            {
                $this->Server->del($this->params['url']['id']);
            }
            $this->redirect($this->base);
            exit;
        }

        function modify()
        {
            if(false===$this->params['wakka']->IsAdmin())
            {
                $this->redirect($this->base);
            }

            $id = null;
            if(isset($this->params['url']['id']))
            {
                $id = $this->params['url']['id'];
            }
            if(empty($this->data))
            {
                $this->Server->id = $id;
                $this->data = $this->Server->read();
            }
            else
            {
                uses('sanitize');
                $sanitize = new Sanitize();
                if(empty($this->data))
                {
                    $this->render();
                }
                if(!empty($this->data))
                {
                    $sanitize->cleanArray($this->data);
                    if($this->Server->save($this->data))
                    {
                        $this->flash('Your entry has been saved.', '', 1);
                    }
                    else
                    {
                        $this->set('errorMessage', 'Please correct errors below.');
                        $this->render();
                    }
                }
            }
        }
    }
?>

Comments: Look back at the changes you made in your webroot/index.php code. Remember this?

array('wakka'=>(object)$this)


That is how the Wikka instance is passed into the Cake framework so it's accessible in the controller (where the business logic resides). The commented-out construction above indicates that due to the way the Cake core libraries are bootstrapped, the Wikka instance isn't available until *after* the constructor has been called. Nor can it be set as a var (since only static assignments can be made to var-declared variables). So you'll need to call your Wikka lib functions within each method from which you need access.

I could have chosen to use the data filters provided by Wikka, but for simplicity sake I used the Cake built-in "sanitize" class. Also, note that the $this->flash(...) call doesn't redirect properly due to some interaction between Wikka and Cake. The link displays just fine, but one has to actually click the link for the redirect to occur.

views/layouts/default.thtml
<?php echo $content_for_layout; ?>

Comments: We don't want Cake to output any additional HTML <head> sections, as this is already handled by Wikka.

views/servers/index.thtml
<h1>Public Access Servers</h1>
<br/>
<table border="1">
<tr>
</tr>
<?php foreach ($servers as $server): ?>
<tr>
<?php if(true
$this->params['wakka']->IsAdmin()): ?>
<td><a class="keys" href="<?php echo $html->base.'?action=delete&id='.$server['Server']['id'] ?>">X</a> 
<a class="keys" href="<?php echo $html->base.'?action=modify&id='.$server['Server']['id'] ?>">M</a></td>
<?php endif; ?>
<td><?php echo $server['Server']['ip_addr']; ?></td>
<td><?php echo $server['Server']['internic_hn']; ?></td>
<td><?php echo $server['Server']['opennic_hn']; ?></td>
<td><?php echo $server['Server']['owner']; ?></td>
<td><?php echo $server['Server']['city']; ?></td>
<td><?php echo $server['Server']['state']; ?></td>
<td><?php echo $server['Server']['country']; ?></td>
<td><?php echo preg_replace('/@/', ' <at> ', $server['Server']['email']); ?></td>
<td><?php echo $server['Server']['last_verified']; ?></td>
<td><?php echo $server['Server']['comments']; ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php ?>

Comments:
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki