At the end of part one, we had a working CMS. Well, at least it was saving files and they could be displayed to the public. In today’s article, we are going to further advance our CMS. We will cover the following items:
Adding fckEditor should be the easiest process to the whole CMS. Download the latest version of fckEditor (http://www.fckeditor.net/download) and extract it to app/webroot/js. Now we need to update our pages_controller to load the Javascript helper when we are adding or editing a file. Simply update the $helpers array to include Javascript:
var $helpers = array(‘Html’, ‘Form’, ‘Javascript’);
Now, we need to update our app/views/pages/add.ctp and edit.ctp. Include the following lines at the top of the file:
<?php echo $javascript->link('fckeditor/fckeditor', false); ?>
<?php echo $javascript->codeBlock('
window.onload = function() {
var oFCKeditor = new FCKeditor( "PageBody" ) ;
oFCKeditor.BasePath = "/CMS/js/fckeditor/" ;
oFCKeditor.ReplaceTextarea() ;
}
', array('safe' => false, 'inline' => false)); ?>This will now make it a lot easier for our clients, who are most likely non-HTML savy, to add useful content to their web site.
Finally, let’s add a really useful feature – revision history. We want to accomplish two things here. One, each time a file is saved, we want to save the previous version and delete all revisions when a page is deleted. Two, we want to allow our client to view their revision history and restore to a previous version.
Let’s begin. We’ll start by creating a revision table. Now, we could simply update our pages table, but I like to separate these two tables. By putting them together, our pages index will be a lot bigger than it needs to be.
51&q=CREATE&lr=lang_en">CREATE 51&q=TABLE&lr=lang_en">TABLE `pages_revisions` (
`id` 51&q=INT&lr=lang_en">int(10) 51&q=UNSIGNED&lr=lang_en">unsigned 5.1/en/non-typed-operators.html">NOT 51&q=NULL&lr=lang_en">NULL 51&q=AUTO_INCREMENT&lr=lang_en">auto_increment,
`page_id` 51&q=INT&lr=lang_en">int(10) 51&q=UNSIGNED&lr=lang_en">unsigned 5.1/en/non-typed-operators.html">NOT 51&q=NULL&lr=lang_en">NULL,
`title` 51&q=VARCHAR&lr=lang_en">varchar(255) 5.1/en/non-typed-operators.html">NOT 51&q=NULL&lr=lang_en">NULL,
`body` 51&q=TEXT&lr=lang_en">text 5.1/en/non-typed-operators.html">NOT 51&q=NULL&lr=lang_en">NULL,
`created` 51&q=DATETIME&lr=lang_en">datetime 51&q=DEFAULT&lr=lang_en">default 51&q=NULL&lr=lang_en">NULL,
`modified` 51&q=DATETIME&lr=lang_en">datetime 51&q=DEFAULT&lr=lang_en">default 51&q=NULL&lr=lang_en">NULL,
51&q=PRIMARY%20KEY&lr=lang_en">PRIMARY KEY (`id`)
) 51&q=ENGINE&lr=lang_en">ENGINE=51&q=INNODB&lr=lang_en">InnoDB 51&q=DEFAULT&lr=lang_en">DEFAULT 51&q=CHARSET&lr=lang_en">CHARSET=latin1;We are going to want to create a model for this table, so let’s use the bakery again.
Start > Run
Type: "cmd" and press enter
Type: "cd \xampplite\htdocs\CMS" and press enter
Type: "cake\console\cake bake" and press enter
Type: "M" and press enter
Press enter to use default database config
Type: "2" and press enter for the PagesRevision model
Type: "n" and press enter
Type: "y" and press enter
Type: "y" and press enter
Type: "n" and press enter
Type: "y" and press enter
Type: "n" and press enter
Type: "Q" and press enterWe have now successfully created our PagesRevision model and associated it to our page model. To make this process simple and minimize the amout of work, we are going to simply update the beforeSave and afterDelete statements. In the beforeSave, we will save a copy of the current Page to our PagesRevision model and in our afterDelete statement, we will clean up our PagesRevision and remove all revisions for that page. Here is our two updated functions in our app/models/page.php:
function beforeSave() {
// only create revision if id is > 0
if (!empty($this->data['Page']['id'])) {
// import our PagesRevision model
App::import('model', 'PagesRevision');
// instantiate it
$this->PagesRevision = new PagesRevision();
$this->PagesRevision->saveRevision($this->data);
}
return true;
}
function afterDelete() {
// import our PagesRevision model
App::import('model', 'PagesRevision');
// instantiate it
$this->PagesRevision = new PagesRevision();
$this->PagesRevision->deleteRevision($this->data['Page']['id']);
}And here is our updated app/models/pages_revision.php:
function saveRevision($data) {
// get our current page
$this->Page->recursive = -1;
$page = $this->Page->find('first', array('conditions' => array('id' => $data['Page']['id'])));
$revision = array('PagesRevision' => array('page_id' => $page['Page']['id'], 'title' => $page['Page']['title'], 'body' =>
$page['Page']['body']));
$this->create();
$this->save($revision);
}
function deleteRevision($page_id) {
$this->deleteAll(array('page_id' => $page_id), false, false);
}I will leave part two up to you and that is creating a list of revisions and allowing a user to revert back to that version. To finish let’s summarize what we’ve learned in this two part series:

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 
Wonderful article. I been looking for one on a similar note. I guess you always have something up your sleeve.I read your first article and this one and I found them both very interesting. I’d like to make my own CMS, just purely for my personal sites. Also, Cake PHP seems very promising, at least that’s what I’m hearing from virtual everyone.Thanks for the tuts.
Sounds interesting. Thanks for info .I like You Now! (sounds weird.. should say I follow you Now!.. )