CakePHP 1.3 - Simple Blog Example with Authentication ===================================================== Public domain ******************************************************************************** ### Preparing files and directories: 0. Rename cakephp directory : cd /var/www/htdocs tar xf ~/cakephp-cakephp-1.3.13-0-g924fb6f.tar.gz mv cakephp-cakephp-1.3.13-0-g924fb6f/ blog 0. Change app/tmp/ owner and all it's subdirectories : chown -R apache app/tmp/ 0. Change Security.salt and Security.cipherSeed values in app/config/core.php : Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi'); Configure::write('Security.cipherSeed', '76859309657453542496749683645'); ******************************************************************************** ### Preparing Database 0. Create a database : CREATE DATABASE blog; 0. Create a table with plural name and a primary key named 'id' : USE blog; CREATE TABLE posts ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, title VARCHAR(50), body TEXT, created DATETIME DEFAULT NULL, modified DATETIME DEFAULT NULL ); 0. Insert sample data for testing : INSERT INTO posts (title,body,created,modified) VALUES ('The title', 'This is the post body.', NOW(), NOW()); INSERT INTO posts (title,body,created,modified) VALUES ('A title once again', 'And the post body follows.', NOW(), NOW()); INSERT INTO posts (title,body,created,modified) VALUES ('Title strikes back', 'This is really exciting! Not.', NOW(), NOW()); 0. Rename database.php.default to database.php : mv app/config/database.php{.default,} 0. edit app/config/database.php , remove $test array and change $default array : class DATABASE_CONFIG { var $default = array( 'driver' => 'mysql', 'persistent' => false, 'host' => 'localhost', 'login' => 'root', 'password' => '', 'database' => 'blog', 'prefix' => '', //'encoding' => 'utf8', ); } 0. Check the result in browser : http://localhost/blog ******************************************************************************** ### Create a Model 0. Create a .php file, named same as database table name but singular, in app/models/ directory : ******************************************************************************** ### Create a Controller 0. Create a .php file, named same as database table name (plural) with _controller.php postfix in app/controllers directory : ******************************************************************************** ### Create an Acion/View pare: Showing the list of posts 0. Add an action named 'index' to controller : set('posts', $this->Post->find('all')); } } ?> 0. Create a directory, named same as database table (plural), in app/views/ directory: mkdir app/views/posts 0. Create a .ctp file, named same as action name in controller, in previously made directory :

Blog posts

Id Title Created
Html->link($post['Post']['title'], array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
0. Check the result in browser : http://localhost/blog/posts ******************************************************************************** ### Create an Action/View pare: Showing a single post 0. Add an action named 'view' to controller : set('posts', $this->Post->find('all')); } function view($id = null) { $this->Post->id = $id; $this->set('post', $this->Post->read()); } } ?> 0. Create a .ctp file, named same as the action name, in views directory:

Created:

0. Check the result in browser : http://localhost/blog/posts http://localhost/blog/posts/view/1 ******************************************************************************** ### Create an Action/View pare: Adding a post 0. Include required helpers and components to the controller: set('posts', $this->Post->find('all')); } function view($id = null) { $this->Post->id = $id; $this->set('post', $this->Post->read()); } } ?> 0. Add an action named 'add' to controller : set('posts', $this->Post->find('all')); } function view($id = null) { $this->Post->id = $id; $this->set('post', $this->Post->read()); } function add() { if (!empty($this->data)) { if ($this->Post->save($this->data)) { $this->Session->setFlash('Your post has been saved.'); $this->redirect(array('action' => 'index')); } } } } ?> 0. Create a .ctp file, named same as the action name, in views directory:

Add Post

Form->create('Post'); echo $this->Form->input('title'); echo $this->Form->input('body', array('rows' => '3')); echo $this->Form->end('Save Post'); ?> 0. Add a link to this action in app/views/posts/index.ctp : Html->link('Add Post', array('controller' => 'posts', 'action' => 'add')); ?> 0. Check the result in browser : http://localhost/blog/posts http://localhost/blog/posts/add ******************************************************************************** ### Data Validation 0. Add required validation array to Model: array('rule' => 'notEmpty'), 'body' => array('rule' => 'notEmpty') ); } ?> ******************************************************************************** ### Create an Action: Deleting a post 0. Add an action named 'delete' to controller : set('posts', $this->Post->find('all')); } function view($id = null) { $this->Post->id = $id; $this->set('post', $this->Post->read()); } function add() { if (!empty($this->data)) { if ($this->Post->save($this->data)) { $this->Session->setFlash('Your post has been saved.'); $this->redirect(array('action' => 'index')); } } } function delete($id) { if ($this->Post->delete($id)) { $this->Session->setFlash('The post with id: ' . $id . ' has been deleted.'); $this->redirect(array('action' => 'index')); } } } ?> 0. Edit 'index' view and Add a link to 'delete' action with appropriate table header:

Blog posts

Html->link('Add Post', array('controller' => 'posts', 'action' => 'add')); ?>
Id Title Actions Created
Html->link($post['Post']['title'], array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?> Html->link('Delete', array('action' => 'delete', $post['Post']['id']), null, 'Are you sure?')?>
0. Check the result in browser : http://localhost/blog/posts http://localhost/blog/posts/delete/3 ******************************************************************************** ### Create an Action/View pare: Editing a post 0. Add an action named 'edit' to controller : set('posts', $this->Post->find('all')); } function view($id = null) { $this->Post->id = $id; $this->set('post', $this->Post->read()); } function add() { if (!empty($this->data)) { if ($this->Post->save($this->data)) { $this->Session->setFlash('Your post has been saved.'); $this->redirect(array('action' => 'index')); } } } function delete($id) { if ($this->Post->delete($id)) { $this->Session->setFlash('The post with id: ' . $id . ' has been deleted.'); $this->redirect(array('action' => 'index')); } } function edit($id = null) { $this->Post->id = $id; if (empty($this->data)) { $this->data = $this->Post->read(); } else { if ($this->Post->save($this->data)) { $this->Session->setFlash('Your post has been updated.'); $this->redirect(array('action' => 'index')); } } } } ?> 0. Create a .ctp file, named same as the action name, in views directory:

Edit Post

Form->create('Post', array('action' => 'edit')); echo $this->Form->input('title'); echo $this->Form->input('body', array('rows' => '3')); echo $this->Form->input('id', array('type' => 'hidden')); echo $this->Form->end('Update Post'); ?> 0. Add a link to this action in app/views/posts/index.ctp :

Blog posts

Html->link('Add Post', array('controller' => 'posts', 'action' => 'add')); ?>
Id Title Actions Created
Html->link($post['Post']['title'], array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?> Html->link('Delete', array('action' => 'delete', $post['Post']['id']), null, 'Are you sure?') ?> Html->link('Edit', array('action' => 'edit', $post['Post']['id']));?>
0. Check the result in browser: http://localhost/blog/posts http://localhost/blog/posts/edit/2 ******************************************************************************** ### Routes 0. Change default route in app/config/routes.php : Router::connect('/', array('controller' => 'posts', 'action' => 'index')); 0. Check the result in browser: http://localhost/blog/ ******************************************************************************** Authentication ============== ******************************************************************************** ### Preparing Database 0. Create a table named 'users' with id, username and password fields (password shuold be at least 40 characters) : USE blog; CREATE TABLE users ( id integer auto_increment primary key, username char(50), password char(40) ); ******************************************************************************** ### Making MVC for user model 0. Bake complete MVC for user model using cake console : cake/console/cake bake all user 0. Repair tmp directory permissions chown -R apache app/tmp ******************************************************************************** ### Enabling site wide authentication 0. Create a file in app/app_controller.php : redirect($this->Auth->logout()); } 0. Add a view for login in app/views/users/login.ctp: Session->flash('auth'); echo $this->Form->create('User'); echo $this->Form->input('username'); echo $this->Form->input('password'); echo $this->Form->end('Login'); ?> 0. Add 'Logout' link in app/views/posts/index.ctp: Html->link('Logout', array('controller' => 'users', 'action' => 'logout')); ?>
******************************************************************************** ### Adding first user 0. Temporarily disable authentication for all actions: Auth->allow('*'); } } 0. Add first user in browser: http://localhost/weblog/users/add 0. Enable autentication again: