Archive for February 2011

jquery UI tab in cake php

At first we have to copy all the JavaScript file inside D:\xampp\htdocs\cakephp\app\webroot\js
Here we use jquery and jquery UI javascript file and css file.
We now copy all the css file inside D:\xampp\htdocs\cakephp\app\webroot\css
Leter we will load this css and java script file.
Now Create a controller articles_controller.php inside D:\xampp\htdocs\cakephp\app\controllers
And write bellow code
01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?php
class ArticlesController extends AppController {
var $uses=null;
var $name = 'Articles';
var $helpers = array('Html','Form','Javascript');
 function index() {
          $this->set('page_heading', 'Jquery Tab');      
       }
}
?>
To load JavaScript helper we write this code
1
var $helpers = array('Html','Form','Javascript');

1 Comment

Cakephp: Creating and Sending Parameters Between Controller and View

Cakephp Step By Step Tutorial: We still wok with our first application at cakephp. But we will build controller and view better. Create parameters in controller and send it to view. It will make our application more flexible.
Create a new file books_controller.php within D:\xampp\htdocs\cakephp\app\controllers. Overwrite become like this:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
    class BooksController extends AppController {
        var $Books = 'Books';
        var $uses=null;
       function index() {
          $this->set('page_heading', 'Packt Book Store');
          $book  = array (
                   'book_title'   => 'Object Oriented Programming
                                                        with PHP5',
                   'author'     => 'Hasin Hayder',
                   'isbn'        => '1847192564',
                   'release_date' => 'December 2007'
                  );
          $this->set($book);
          $this->pageTitle = 'Welcome to the Packt Book Store!';

Leave a comment

Cakephp: Installation


Cake php Step By Step Tutorial: We will learn how to install Cakephp. We will install to our local computer. Before follow this instruction, please download Cake php at www.cakephp.com.
1. Open your root web server.
2. Put cakephp downloaded.
copy zip file in htdocs folder
3. Extract it, you will get a folder named liked “cakephp-cakephp-1.3.1-0-g0180daa“.
4. For simple

Leave a comment

Tutorial - CakePHP Ajax "Quick Save" with jQuery

July 15, 2011


When you are in an administration panel, sometimes you want a “quick save” feature that allows you to save without leaving the page.Here is how to accomplish this with CakePHP and jQuery.
To start, download jQuery and the jQuery Form Plugin JavaScript . Include them in your view with the JavaScript helper:
$javascript->link(array('jquery', 'form'), false);
Include the RequestHandler in your controller detect an Ajax save attempt.Also include the JavaScript helper if you haven’t already.
var $helpers = array('Javascript'); 
var $components = array('RequestHandler');
Next we want to override our save function with the ajax quick save.Put this right before your $this->Model->save($this->data) in your save action.
if ($this->RequestHandler->isAjax()) { 
  if ($this->Article->save($this->data)) { 
    echo 'success'; 
  } 
  Configure::write('debug', 0); 
  $this->autoRender = false;
  exit(); 
}
This detects if the request is ajax, then saves the data. Then it sends back a simple, “success” message to let you know things went fine. It also writes debug to 0 and doesn’t render anything, then exits.
Lastly, lets create and include a JavaScript file that performs the quick save.
jQuery(function($){ 
  $('<input type="button"value="Quick Save"/>') 
    .click(function(){ 
      $(this).parents("form:first").ajaxSubmit({ 
        success: function(responseText, responseCode) { 
          $('#ajax-save-message').hide().html(responseText).fadeIn(); 
          setTimeout(function(){ 
            $('#ajax-save-message').fadeOut(); 
          }, 5000); 
        } 
      }); 
      return false; 
    }) 
    .appendTo('form div.submit'); 
});
This adds a button called, “Quick Save” to each form on the page where a div with class="submit" exists (you may want to switch this to the id of the form you want to add quick save to). Then It also attaches a click event to the button that submits the form via the jQuery Form Plugin.
In a few simple steps, we’ve created a quick save feature that saves your data whenever you want without leaving the page.

Posted in | Leave a comment

Full CakePHP Application Part 1

This is the first article in a series that I will use to document the process of creating a fully featured web application in CakePHP. At the moment the whole series comes in at around 8 articles but I'm sure this will grow as I write up each one. My aim is to publish one article a week detailing the steps involved with setting up and coding a full working online DVD Catalog Application that will keep track of all my DVDs. I've been meaning to create such an application for a long time so I thought it would be a great project to put on my website.
In this first article I'm going to go through the steps of setting up your new CakePHP project, go through the requirements of the system, create the database structure and finally setup the Model's and associations. For this project I'm going to be using the newest 1.2 version of CakePHP, I haven't used it before so this will be a learning process for me as well.

Brief

With any new application I'm working on I like to outline a pretty simple brief or overview of what I want the app to achieve along with some of the functionality that the app will offer. For my DVD Catalog I want an application that will manage my ever growing collection of DVDs ( films and TV shows ). For each DVD that is entered into the application I want to add an image ( preferably a cover image ), a website URL, the Imdb website entry and a personal rating.
Along with being able to add / edit / delete DVDs I would like a front end display so that other people can go online and browse my collection as well. This front end will have search and filter functionality so that I can search by name or filter by format type etc. The front end also needs to be fully customisable so I'm going to implement a templating system where I can easily change the layout in the admin panel.

Requirements

Good planning is paramount to any system so here are the requirements for the DVD Catalog Application:
  • Formats
    • These are the different formats of DVD that will exist in the system.
    • A few examples of format types include dvd, dvdcopy, dvdrip, tvrip and hd.
    • Be able to add / edit / delete format types.
    • Be able to sort and filter DVDs by format type.
  • Types
    • These are the different types of DVD in the system.
    • Examples include Films and TV Shows.
    • Be able to add / edit / delete types.
    • Be able to sort and filter DVDs by Type.
  • Locations
    • These are the different locations where your DVDs will be stored.
    • Examples include spindle 1, spindle 2, etc.
    • Be able to add / edit / delete locations.
    • Be able to sort and filter DVDs by Location.
  • DVDs
    • These are the actual DVDs that you will enter into the system.
    • Each DVD will have a number of attributes:
      • The Format Type, is it a DVD? a Copied DVD? A DVD Rip?.
      • The Type, is it a Film? Is it a TV Show?
      • The Location.
      • Name.
      • Image URL.
      • Official Website.
      • Imdb Link.
      • Rating.
      • Number of Discs.
      • Number of Episodes if its a TV Show.
  • Genres
    • A DVD will be able to belong to a number of genres.
    • A Genre will have multiple DVDs.
    • An Admin will be able to add /edit / delete Genres from the system
    • A user will be able to:
      • Filter by Genre.
      • Search by Genre.
  • Admin Section
    • The application will have a password protected admin area where a logged in admin will be able to interact with the system.
    • Admins can add / edit / delete:
      • Formats
      • Types
      • Locations
      • DVDs
      • Templates
  • Front End
    • The application will have a front end that will be viewable to anyone.
    • The main front end will show all the DVDs in the system.
    • The number of displayed DVDs will be limited and so pagination will be required.
    • A user will be able to filter the DVDs by:
      • Format
      • Type
      • Location
      • DVD Rating
    • A user will also be able to search for DVDs.
    • A user will be able to bookmark search and filters.
    • A user will be able to select different templates, changing the appearance of the system.
  • Templates
    • The system will be able to incorporate numerous templates.
    • A template will be added by the admin of the application
    • The template name will be used to identify images and css used by the template
    • A user will be able to select the template to change the design.
Although I've tried to be as thorough as possible with the requirements at this early stage a few may be added during development. Going through the requirements before building an application will give you a good idea of how the system should work and how it all fits together. It also helps with the database design process and give you an idea of what tables you will need and the types of associations that the tables have with each other.

Database Structure

From the list of requirements I've come up with 8 different tables for the database which include Formats, Types, Locations, DVDS, Genres, Templates and Admins.
  • Formats
    • id, name, slug, description, created, modified, status
  • Types
    • id, name, slug, description, created, modified, status
  • Locations
    • id, name, slug, description, created, modified, status
  • DVDs
    • id, format_id, type_id, location_id, name, slug, image, website, imdb, rating, discs, episodes, created, modified, status
  • Genres
    • id, name, slug, created, modified, status
  • DVDS_Genres
    • id, dvd_id, genre_id
  • Templates
    • id, name, layout_name, description, image, created, modified, status
  • Admins
    • id, username, password, last_login, status
First create the new database either using PhpMyAdmin or by using this statement:
  1. CREATE DATABASE `dvdcatalog`;  
Formats, Types and Locations have exactly the same database fields but I've not combined them into one table and used a flag to identify them because I wanted to seperate out the logic for each type and it also makes it easier to sort and filter by the different tables when our system is up and running. The model associations between these tables and the DVD table will also be easier to maintain and establish. A "slug" has been entered that will be used for user friendly URLs so instead of seeing "/formats/view/1" you will see "/formats/view/dvdrip".

CREATE TABLE `formats` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 255 ) NOT NULL ,
`slug` VARCHAR( 255 ) NOT NULL ,
`desc` TEXT NOT NULL ,
`created` DATETIME NOT NULL ,
`modified` DATETIME NOT NULL ,
`status` TINYINT( 1 ) NOT NULL DEFAULT '1',
PRIMARY KEY ( `id` )
);
CREATE TABLE `types` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 255 ) NOT NULL ,
`slug` VARCHAR( 255 ) NOT NULL ,
`desc` TEXT NOT NULL ,
`created` DATETIME NOT NULL ,
`modified` DATETIME NOT NULL ,
`status` TINYINT( 1 ) NOT NULL DEFAULT '1',
PRIMARY KEY ( `id` )
);
CREATE TABLE `locations` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 255 ) NOT NULL ,
`slug` VARCHAR( 255 ) NOT NULL ,
`desc` TEXT NOT NULL ,
`created` DATETIME NOT NULL ,
`modified` DATETIME NOT NULL ,
`status` TINYINT( 1 ) NOT NULL DEFAULT '1',
PRIMARY KEY ( `id` )
);

The DVD table will store all our information for each DVD and will also contain "foreign keys" that will link a DVD to a Format, Type and Location.

CREATE TABLE `dvds` (
`id` INT NOT NULL AUTO_INCREMENT ,
`format_id` INT NOT NULL ,
`type_id` INT NOT NULL ,
`location_id` INT NOT NULL ,
`name` VARCHAR( 100 ) NOT NULL ,
`slug` VARCHAR( 100 ) NOT NULL ,
`image` VARCHAR( 255 ) NOT NULL ,
`website` VARCHAR( 255 ) NOT NULL ,
`imdb` VARCHAR( 255 ) NOT NULL ,
`rating` TINYINT NOT NULL ,
`discs` TINYINT NOT NULL ,
`episodes` TINYINT NOT NULL ,
`created` DATETIME NOT NULL ,
`modified` DATETIME NOT NULL ,
`status` TINYINT( 1 ) NOT NULL DEFAULT '1',
PRIMARY KEY ( `id` )
);

The Genre table will contain the name of the Genre along with a slug for friendly URLs. A Join table will also be needed to link up Genres with DVDs, this will be displayed in much more detail in our model associations but this allows DVDs to have multiple Genres and to allow a Genre to have multiple DVDs.

CREATE TABLE `genres` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 255 ) NOT NULL ,
`slug` VARCHAR( 255 ) NOT NULL ,
`created` DATETIME NOT NULL ,
`modified` DATETIME NOT NULL ,
`status` TINYINT( 1 ) NOT NULL DEFAULT '1',
PRIMARY KEY ( `id` )
);

CREATE TABLE `dvds_genres` (
`id` INT NOT NULL AUTO_INCREMENT ,
`dvd_id` INT NOT NULL ,
`genre_id` INT NOT NULL ,
PRIMARY KEY ( `id` )
);
The templates table will store all the information relatating to the template, the layout name will be used to choose the images that the template will use along with the css file that will change the look and appearence of the front end system.

CREATE TABLE `templates` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  `layout_name` varchar(100) NOT NULL,
  `description` text NOT NULL,
  `image` varchar(255) NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  `status` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`id`)
);

The final table (admins) will be used to store the username and password of any user that has access to the admin area of the application.

CREATE TABLE `admins` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(100) NOT NULL,
  `password` varchar(100) NOT NULL,
  `last_login` datetime NOT NULL,
  `status` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`id`)
);

Using CakePHP conventions our database table names are all plural and our join table is the plural names of the two tables in alphabetical format. This ensures that CakePHP will automatically be able to connect to the database and create associated data with Cake's inbuilt Automagic methods.

Setting up CakePHP

First thing to do is download the latest version of CakePHP at the time of writing this is currently 1.2.0.6311. I do all my development locally using Xampp and I'm going to setup a virtual host so that I can simulate an online enviornment. For information on how do this please visit my previous article on setting up a local web server and using virtual hosts.
Now I have created my virtual host called "dvdcatalog" and I've extracted CakePHP 1.2 beta to the directory. To check that everything is working goto "http://catalog" and you should be greeted with the default screen.
CakePHP DVD Catalog Application Image 1 The first thing its telling us to do is change the value of "Security.salt" in app/config/core.php, so open up core.php and change the default value of the security.salt variable. I've used this excellent website to generate a random string.

// app/config/core.php line: 153

Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');

Whilst I have the core.php file open I've changed the security setting from high to low for development purposes so that I can stay logged in longer. Note that I need to change this back when the system is live. I've also enable admin routing, which will allow us to easily create an admin section, this will be discussed in detail later in development.


// app/config/core.php line: 149

// from
Configure::write('Security.level', 'high');
// to
Configure::write('Security.level', 'low');

// uncomment this line:69
Configure::write('Routing.admin', 'admin');

CakePHP DVD Catalog Application Image 2 Now we need to make sure that our application can connect to the database, the default cake screen is telling us that the database configuration file is not present and that we need to rename the file located in the config folder. Open up your renamed "database.php" file and enter your database username, password and table name.

var $default = array(
    'driver' => 'mysql',
    'persistent' => false,
    'host' => 'localhost',
    'port' => '',
    'login' => 'username',
    'password' => 'password',
    'database' => 'dvdcatalog',
    'schema' => '',
    'prefix' => '',
    'encoding' => ''
);


Reload the application in your browser and if everything went well CakePHP can now connect to your database.
CakePHP DVD Catalog Application Image 3

Creating the Model files and Associations

The next stage is to create the model files for the system and setup the associations between the tables. Before you go any further please read and re-read the Associations section of the Models chapter in the manual. This section is essential to understanding how tables relate to each other.
From our database tables we have a number of relationships:
  • A DVD belongs to:
    • A Format
    • A Type
    • A Location
  • A DVD has and belongs to many:
    • Genres
  • A Format has many:
    • DVDs
  • A Type has many:
    • DVDs
  • A Location has many:
    • DVDs
  • A Genre has many and belong to:
    • DVDs
With a "belongsTo" relationship we need to specifiy the foreign key in the database and so each DVD in the database has a format_id, type_id and location_id that will relate to the primary key of the coresponding table. A "hasAndBelongsToMany" is a special type of association that requires an extra "join" table, this is because a DVD an belong to many genres and a single genre can have many DVDs. This is also called a "many-to-many" relationship and the extra table keeps track of all the associations. The beauty of using CakePHP is that if your database and associations are setup correctly the finding and saving of related data will be done automatically for you, which makes the development process much easier.
Generally you have a model file for each of the tables in the database so here are the files:
/**
 * file: app/model/dvd.php
 *
 * Dvd Model
 */
class Dvd extends AppModel {
    // good practice to include the name variable
    var $name = 'Dvd';
 
    // setup the belongs to relationships
    var $belongsTo = array(
        'Format'=>array(
            'className'=>'Format'
        ),
        'Type'=>array(
            'className'=>'Type'
        ),
        'Location'=>array(
            'className'=>'Location'
        )
    );
 
    // setup the has and belongs to many relationship
    var $hasAndBelongsToMany = array(
        'Genre'=>array(
            'className'=>'Genre'
        )
    );
}

/**
 * file: app/model/format.php
 *
 * Format Model
 */
class Format extends AppModel {
    // good practice to include the name variable
    var $name = 'Format';
 
    // setup the has many relationships
    var $hasMany = array(
        'Dvd'=>array(
            'className'=>'Dvd'
        )
    );
}

/**
 * file: app/model/type.php
 *
 * Type Model
 */
class Type extends AppModel {
    // good practice to include the name variable
    var $name = 'Type';
 
    // setup the has many relationships
    var $hasMany = array(
        'Dvd'=>array(
            'className'=>'Dvd'
        )
    );
}

/**
 * file: app/model/location.php
 *
 * Location Model
 */
class Location extends AppModel {
    // good practice to include the name variable
    var $name = 'Location';
 
    // setup the has many relationships
    var $hasMany = array(
        'Dvd'=>array(
            'className'=>'Dvd'
        )
    );
}

/**
 * file: app/model/genre.php
 *
 * Genre Model
 */
class Genre extends AppModel {
    // good practice to include the name variable
    var $name = 'Genre';
 
    // setup the has and belongs to many relationship
    var $hasAndBelongsToMany = array(
        'Dvd'=>array(
            'className'=>'Dvd'
        )
    );
}


/**
 * file: app/model/template.php
 *
 * Template Model
 */
class Template extends AppModel {
    // good practice to include the name variable
    var $name = 'Template';
}

Wrapping Up

Ok so I've covered quite a lot of ground in the first article from an inital brief I've created a number of requirements for the system and from those I've created a database structure that hopefully won't change much as I create the system. I've downloaded and installed the latest version of CakePHP to a virtual host on my local development setup so when the time comes to migrating the system online it should be relatively easy. From the database tables I've created the Model files and setup the associations between them, initially these have been configured to the minimum but as the application progresses I will be covering the more advanced features.
At the moment the application doesn't do anything but this will soon change as I add new features and functionality over the upcoming weeks. What I have done is gone through the process of starting a new project and the planning and thinking that needs to go into a project before you even start coding. With a strong base of requirements and a well thought out database design your application will be easier to code & maintain and the time spent at this stage will save you time in the later stages of development.

Posted in | Leave a comment

Full CakePHP Application Part 2


CakePHP 1.2 Full Application Image 1

This is the second article in the series on creating a full DVD Catalog online web application with CakePHP 1.2. Last time I went through the process of beginning a new application from scratch. I created a small brief which led to quite a few requirements that the application will need to do and from those requirements I came up with a database structure that should hold up throughout the project life cycle. Finally I sent up CakePHP on my local computer using Xampp with a Virtual Host and created the Model files for the application. If you have not yet read the first article then please go back and have a quick look so you (hopefully) know what I'm talking about.
In this article I'm going to focus on the Formats table of the application and this includes creating a controller to deal with the functionality that the application will offer such as adding, editing and deleting formats. As well as the controller I'm going to create the related views for all the Format actions and at the end of the article we will be able to start adding data to the application.

Formats

To begin we need to create a new controller file called formats_controller.php and place this in the controllers directory. If you are having trouble with the concept of a controller visit the Controllers Chapter of the CakePHP manual. Generally a Controller takes care of all the business logic of the application with each method inside the file taking care of an action that the system does.
For example each method inside a controller corresponds to a URL of the system, if a user visits http://dvdcatalog/admin/formats/add then the logic inside the admin_add() method of the Formats Controller would be processed. This makes it very easy to organise and maintain your code and is one of the main benefits of using the MVC software pattern.
When creating a new controller I like to code all of the methods I'm likely to use and for the Formats Controller I will need the following:
  • index()
  • view()
  • admin_index()
  • admin_add()
  • admin_edit()
  • admin_delete()
So far the Formats Controller looks like this:
  1. /** 
  2.  * Formats Controller 
  3.  * 
  4.  * file: /app/controllers/formats_controller.php 
  5.  */  
  6. class FormatsController extends AppController {  
  7.     // good practice to include the name variable  
  8.     var $name = 'Formats';  
  9.       
  10.     // load any helpers used in the views  
  11.     var $helpers = array('Html''Form');  
  12.   
  13.     /** 
  14.      * index() 
  15.      * main index page of the formats page 
  16.      * url: /formats/index 
  17.      */  
  18.     function index() {  
  19.   
  20.     }  
  21.   
  22.     /** 
  23.      * view() 
  24.      * displays a single format and all related dvds 
  25.      * url: /formats/view/format_slug 
  26.      */  
  27.     function view($slug = null) {  
  28.   
  29.     }  
  30.       
  31.     /** 
  32.      * admin_index() 
  33.      * main index for admin users 
  34.      * url: /admin/formats/index 
  35.      */  
  36.     function admin_index() {  
  37.   
  38.     }  
  39.   
  40.     /** 
  41.      * admin_add() 
  42.      * allows an admin to add a format 
  43.      * url: /admin/formats/add 
  44.      */  
  45.     function admin_add() {  
  46.   
  47.     }  
  48.   
  49.     /** 
  50.      * admin_edit() 
  51.      * allows an admin to edit a format 
  52.      * url: /admin/formats/edit/id 
  53.      */  
  54.     function admin_edit($id = null) {  
  55.   
  56.     }  
  57.   
  58.     /** 
  59.      * admin_delete() 
  60.      * allows an admin to delete a format 
  61.      * url: /admin/formats/delete/id 
  62.      */  
  63.     function admin_delete($id = null) {  
  64.   
  65.     }  
  66.   
  67. }  

Index Methods and Views

The index() and admin_index() methods are going to retrieve all the active formats from the database and send them to the view so that they can be displayed to the user.
  1. /** 
  2.  * index() 
  3.  * main index page of the formats page 
  4.  * url: /formats/index 
  5.  */  
  6. function index() {  
  7.     // this tells cake to ignore related format data such as dvds  
  8.     $this->Format->recursive = 0;  
  9.   
  10.     // get all formats from database where status = 1  
  11.     $formats = $this->Format->findAll("status=1");  
  12.   
  13.     // save the formats in a variable for the view  
  14.     $this->set('formats'$formats);  
  15. }  
  16.   
  17. /** 
  18.  * admin_index() 
  19.  * main index for admin users 
  20.  * url: /admin/formats/index 
  21.  */  
  22. function admin_index() {  
  23.     // this tells cake to ignore related format data such as dvds  
  24.     $this->Format->recursive = 0;  
  25.   
  26.     // get all formats from database where status = 1  
  27.     $formats = $this->Format->findAll("status=1");  
  28.   
  29.     // save the formats in a variable for the view  
  30.     $this->set('formats'$formats);  
  31. }  
Next we need to create new View files called index.ctp and admin_index.ctp in the /app/views/formats folder. The views files are pretty basic and will output the formats in a table.
  1. <?php  
  2.   
  3. // file: /app/views/formats/admin_index.ctp  
  4.   
  5. ?>  
  6. <div class="formats index">  
  7.   
  8.     <h2>Formats Admin Index</h2>  
  9.     <p>Currently displaying all formats in the application.</p>  
  10.   
  11.     <?php  
  12.     // check $formats variable exists and is not empty  
  13.     if(isset($formats) && !empty($formats)) :  
  14.     ?>  
  15.   
  16.     <table>  
  17.         <thead>  
  18.             <tr>  
  19.                 <th>Id</th>  
  20.                 <th>Name</th>  
  21.                 <th>Slug</th>  
  22.                 <th>Description</th>  
  23.                 <th>Created</th>  
  24.                 <th>Modified</th>  
  25.                 <th>Actions</th>  
  26.             </tr>  
  27.         </thead>  
  28.         <tbody>  
  29.             <?php  
  30.             // initialise a counter for striping the table  
  31.             $count = 0;  
  32.   
  33.             // loop through and display format  
  34.             foreach($formats as $format):  
  35.                 // stripes the table by adding a class to every other row  
  36.                 $class = ( ($count % 2) ? " class='altrow'"'' );  
  37.                 // increment count  
  38.                 $count++;  
  39.             ?>  
  40.             <tr<?php echo $class; ?>>  
  41.                 <td><?php echo $format['Format']['id']; ?></td>  
  42.                 <td><?php echo $format['Format']['name']; ?></td>  
  43.                 <td><?php echo $format['Format']['slug']; ?></td>  
  44.                 <td><?php echo $format['Format']['desc']; ?></td>  
  45.                 <td><?php echo $format['Format']['created']; ?></td>  
  46.                 <td><?php echo $format['Format']['modified']; ?></td>  
  47.                 <td>  
  48.                 <?php echo $html->link('Edit'array('action'=>'admin_edit'$format['Format']['id']) );?>  
  49.                 <?php echo $html->link('Delete'array('action'=>'admin_delete'$format['Format']['id']), null, sprintf('Are you sure you want to delete Format: %s?'$format['Format']['name']));?>  
  50.                 </td>  
  51.             </tr>  
  52.             <?php endforeach; ?>  
  53.         </tbody>  
  54.     </table>  
  55.       
  56.     <?php  
  57.     else:  
  58.         echo 'There are currently no Formats in the database.';  
  59.     endif;  
  60.     ?>  
  61.       
  62.     <ul class="actions">  
  63.         <li><?php echo $html->link('Add a Format'array('action'=>'add')); ?></li>  
  64.     </ul>  
  65.   
  66. </div>  
CakePHP 1.2 Full Application Image 1

View Method and View

The view() method will be used by a user to list all the DVDs that belong to a particular format, the method will first check that the slug isn't null and will then retrieve the slug from the database using one of CakePHP's magic findByFieldName() methods. If the format has been found then I will save it for the View.
  1. /** 
  2.  * view() 
  3.  * displays a single format and all related dvds 
  4.  * url: /formats/view/format_slug 
  5.  */  
  6. function view($slug = null) {  
  7.     // if slug is null  
  8.     if(!$slug) {  
  9.         // set a flash message  
  10.         $this->Session->setFlash('Invalid id for Format''flash_bad');  
  11.         // redirect user  
  12.         $this->redirect(array('action'=>'index'));  
  13.     }  
  14.       
  15.     // find format in database  
  16.     $format = $this->Format->findBySlug($slug);  
  17.       
  18.     // if format has been found  
  19.     if(!empty($format)) {  
  20.         // set the format for the view  
  21.         $this->set('format'$format);  
  22.     } else {  
  23.         // set a flash message  
  24.         $this->Session->setFlash('Invalid id for Format''flash_bad');  
  25.         // redirect user  
  26.         $this->redirect(array('action'=>'index'));  
  27.     }  
  28. }  
The View file will display a few details of the format along with all the DVDs that belong to the format. A simple table is used to loop through the DVDs with a view link for each one.
  1. <?php  
  2.   
  3. // page: /app/views/formats/view.ctp  
  4.   
  5. ?>  
  6.   
  7. <div class="formats view">  
  8.     <h2>Viewing Format: <?php echo $format['Format']['name']; ?></h2>  
  9.       
  10.     <dl>  
  11.         <dt>Name:</dt>  
  12.         <dd><?php echo $format['Format']['name']; ?></dd>  
  13.           
  14.         <dt>Description:</dt>  
  15.         <dd><?php echo $format['Format']['desc']; ?></dd>  
  16.           
  17.         <dt>Created</dt>  
  18.         <dd><?php echo $format['Format']['created']; ?></dd>  
  19.     </dl>  
  20.       
  21.     <?php if(!empty($format['Dvd'])): ?>  
  22.       
  23.     <div class="related">  
  24.         <h3>DVDs with this Format</h3>  
  25.         <table>  
  26.             <thead>  
  27.                 <tr>  
  28.                     <th>Name</th>  
  29.                     <th>Actions</th>  
  30.                 </tr>  
  31.             </thead>  
  32.             <tbody>  
  33.                 <?php foreach($format['Dvd'as $dvd): ?>  
  34.                 <tr>  
  35.                     <td><?php echo $dvd['name']; ?></td>  
  36.                     <td><?php echo $html->link('View''/dvds/view/'.$dvd['slug']);?></td>  
  37.                 </tr>  
  38.                 <?php endforeach; ?>  
  39.             </tbody>  
  40.         </table>  
  41.     </div>  
  42.       
  43.     <?php endif; ?>  
  44.       
  45.     <ul class="actions">  
  46.         <li><?php echo $html->link('List Formats'array('action'=>'index'));?></li>  
  47.     </ul>  
  48. </div>  
CakePHP 1.2 Full Application Image 2

Admin Add Method and View

The admin_add() method will process the form data and try to add the information to the database. The method first checks that the form has been submitted, creates a slug from the name of the format and finally adds the format to the database. If the save() was successful then the user is redirected to the index page with a "success" flash message and if not the application displays a "failure" flash message.
  1. /** 
  2.  * admin_add() 
  3.  * allows an admin to add a format 
  4.  * url: /admin/formats/add 
  5.  */  
  6. function admin_add() {  
  7.     // if the form data is not empty  
  8.     if (!empty($this->data)) {  
  9.         // initialise the format model  
  10.         $this->Format->create();  
  11.   
  12.         // create the slug  
  13.         $this->data['Format']['slug'] = $this->slug($this->data['Format']['name']);  
  14.   
  15.         // try saving the format  
  16.         if ($this->Format->save($this->data)) {  
  17.             // set a flash message  
  18.             $this->Session->setFlash('The Format has been saved''flash_good');  
  19.             // redirect  
  20.             $this->redirect(array('action'=>'index'));  
  21.         } else {  
  22.             // set a flash message  
  23.             $this->Session->setFlash('The Format could not be saved. Please, try again.''flash_bad');  
  24.         }  
  25.     }  
  26. }  

Slugs

I have covered the creation of slugs in a previous article but I'll quickly go through it here as well. The first thing to do is create a new app_controller.php file located in the /app folder of the application. This file is useful as any methods you create in here will be available to every controller by calling:
  1. $this->methodName();  
Although CakePHP has an inbuilt slug function it doesn't deal with a few characters correctly so I've created my own:
  1. /** 
  2.  * App Controller 
  3.  * 
  4.  * file: /app/app_controller.php 
  5.  */  
  6. class AppController extends Controller {  
  7.   
  8.     /** 
  9.      * slug() 
  10.      * creates a slug from a string 
  11.      */  
  12.     function slug($str) {  
  13.         // replace spaces with underscore, all to lowercase  
  14.         $str = strtolower(str_replace(' ''_'$str));  
  15.   
  16.         // create regex pattern  
  17.         $pattern = "/[^a-zA-Z0-9_]/";  
  18.   
  19.         // replace non alphanumeric characters  
  20.         $str = preg_replace($pattern''$str);  
  21.   
  22.     return $str;  
  23.     }  
  24. }  
The function first replaces all spaces with underscores, converts all the characters to lower case and finally uses a regular expression to remove all characters that are not letters, numbers and underscores. In the admin_add() method I use this function to turn the name of the format into a slug before the save() takes place so that it is added to the database.

Flash Messages

In a previous article I came up with a way to display custom flash messages depending on the success/failure of the action. This is useful to show feedback to the user about the system such as a green box for a success action and a red box for a failure action.
Looking at the setFlash() function in more detail in the API I found that this functionality is built in by changing the layout that the flash message is displayed in. To make use of this I created two new layouts that will wrap the message in a div to indicate success or failure.
  1. <?php  
  2. // file: /app/views/layouts/flash_good.ctp  
  3. ?>  
  4.   
  5. <div class="flash_good">  
  6. <?php echo $content_for_layout; ?>  
  7. </div>  
  8.   
  9. <?php  
  10. // file: /app/views/layouts/flash_bad.ctp  
  11. ?>  
  12.   
  13. <div class="flash_bad">  
  14. <?php echo $content_for_layout; ?>  
  15. </div>  
I can now use CSS to style these flash messages accordingly. Next up is the view for the admin_add() method, create a new file called admin_add.ctp in the formats view folder (/app/views/formats). The view file contains the form that will be displayed when an admin visits http://dvdcatalog/admin/formats/add and looks like this:
  1. <?php  
  2.   
  3. // file: /app/views/formats/admin_add.ctp  
  4.   
  5. ?>  
  6. <div class="formats form">  
  7. <?php echo $form->create('Format');?>  
  8.     <fieldset>  
  9.         <legend>Add a Format</legend>  
  10.         <?php  
  11.         // create the form inputs  
  12.         echo $form->input('name'array('label'=>'Name: *'));  
  13.         echo $form->input('desc'array('label'=>'Description:''type'=>'textarea'));  
  14.         ?>  
  15.     </fieldset>  
  16. <?php echo $form->end('Add');?>  
  17. </div>  
  18.   
  19. <ul class="actions">  
  20.     <li><?php echo $html->link('List Formats'array('action'=>'index'));?></li>  
  21. </ul>  
CakePHP 1.2 Full Application Image 3 I've used the form helper to quickly create a form that contains two inputs, one for the title and one for the description. Initially I had a bit of trouble understanding how the form helper works in the CakePHP 1.2 due to the lack of official documentation but looking in the API gave me a clearer picture.

Form Validation

One of the many things that has been severely beefed up in the new version of Cake is the built in data validation and gives us loads of options for some pretty advanced validation. For the Add Format form I want the Name of the format to be a mandatory field with an error message displayed if the name is not present. To do this I need to add a rule to the Format Model:
  1. // file: /app/models/format.php  
  2.   
  3. // setup form validation for formats  
  4. var $validate = array(  
  5.     // name field  
  6.     'name' => array(  
  7.         // must not be empty  
  8.         'rule'      => VALID_NOT_EMPTY,  
  9.         // error message to display  
  10.         'message'   => 'Please enter a Format Name'  
  11.     )  
  12. );  
These rules come into play when the save() method is run in the controller, if the form successully validates then the data is inputted to the database if not the form is displayed again with the error messages defined in the Model.
CakePHP 1.2 Full Application Image 4

Admin Edit Method and View

The admin_edit() method is very simiar to the admin_add(), the only difference is that we need to find the format in the database and save it for the View so that the form will be pre populated with data so that we can edit the information.
The method takes an id as a parameter and this is first checked to see if it is null or empty, if it is the admin is redirected to the index page. If the form has been submitted we need to create a new slug and save the data to the database. This is the same as the admin_add() method. Finally if the form has not been submitted we need to find the Format from the database using the id that was passed as an argument.
  1. /** 
  2.  * admin_edit() 
  3.  * allows an admin to edit a format 
  4.  * url: /admin/formats/edit/1 
  5.  */  
  6. function admin_edit($id = null) {  
  7.     // if the id is null and the form data empty  
  8.     if (!$id && empty($this->data)) {  
  9.         // set a flash message  
  10.         $this->Session->setFlash('Invalid Format''flash_bad');  
  11.         // redirect the user  
  12.         $this->redirect(array('action'=>'index'));  
  13.     }  
  14.   
  15.     // if the form data is empty  
  16.     if (!empty($this->data)) {  
  17.         // create the slug  
  18.         $this->data['Format']['slug'] = $this->slug($this->data['Format']['name']);  
  19.   
  20.         // try saving the form data  
  21.         if ($this->Format->save($this->data)) {  
  22.             // set a flash message  
  23.             $this->Session->setFlash('The Format has been saved''flash_good');  
  24.             // redirect  
  25.             $this->redirect(array('action'=>'index'));  
  26.         } else {  
  27.             // set a flash message  
  28.             $this->Session->setFlash('The Format could not be saved. Please, try again.''flash_bad');  
  29.         }  
  30.     }  
  31.   
  32.     // if form has not been submitted  
  33.     if (empty($this->data)) {  
  34.         // find the format from the database and populate the form data  
  35.         $this->data = $this->Format->read(null, $id);  
  36.     }  
  37. }  
A corresponding admin_edit.ctp View file needs to be created like before and this will show a populated form to allow the data to edited. In order for the edit to work correctly I must include a hidden form field of the id of the format so that CakePHP knows this is an edit form and it will populate the form correctly.
I'm also going to display all the related DVDs that belong to a Format, the DVDs are automatically retrieved from the database when the $this->Format->read() was made so I'm going to loop through them all and display them in a table. This allows the DVD to viewed and edited directly from here to make things easier for the admin, although and this stage there are no DVDs in the database.
  1. <?php  
  2.   
  3. // file: /app/views/formats/admin_edit.ctp  
  4.   
  5. ?>  
  6. <div class="formats form">  
  7. <?php echo $form->create('Format');?>  
  8.     <fieldset>  
  9.         <legend>Edit Format</legend>  
  10.         <?php  
  11.         // a hidden form input field, required in a edit form  
  12.         echo $form->input('id'array('type'=>'hidden'));  
  13.         // create the form inputs  
  14.         echo $form->input('name'array('label'=>'Name: *'));  
  15.         echo $form->input('desc'array('label'=>'Description:''type'=>'textarea'));  
  16.         ?>  
  17.     </fieldset>  
  18. <?php echo $form->end('Edit');?>  
  19. </div>  
  20.   
  21. <?php if(!empty($this->data['Dvd'])): ?>  
  22.   
  23. <div class="related">  
  24.     <h3>DVDs with this Format</h3>  
  25.     <table>  
  26.         <thead>  
  27.             <tr>  
  28.                 <th>Id</th>  
  29.                 <th>Name</th>  
  30.                 <th>Actions</th>  
  31.             </tr>  
  32.         </thead>  
  33.         <tbody>  
  34.             <?php foreach($this->data['Dvd'as $dvd): ?>  
  35.             <tr>  
  36.                 <td><?php echo $dvd['id']; ?></td>  
  37.                 <td><?php echo $dvd['name']; ?></td>  
  38.                 <td><?php echo $html->link('Edit''/admin/dvds/edit/'.$dvd['id']);?></td>  
  39.             </tr>  
  40.             <?php endforeach; ?>  
  41.         </tbody>  
  42.     </table>  
  43. </div>  
  44.   
  45. <?php endif; ?>  
  46.   
  47. <ul class="actions">  
  48.     <li><?php echo $html->link('List Formats'array('action'=>'index'));?></li>  
  49. </ul>  
CakePHP 1.2 Full Application Image 5

Delete Method

The delete() method instead of deleting an item completely from the database will change the status of the Format from "1" to "0". This is just a security precaution so that no data is actually deleted from the database and if you do accidently delete something you can easily restore the data using PhpMyAdmin or an SQL statement.
The method first checks that the id is valid and then saves the id of the Format to the current Format model. This ensures that when the saveField() is ran CakePHP only performs the operation on the Format with the specified id. If the delete was a success the user is redirected to the index page with a flash message.
  1. /** 
  2.  * admin_delete() 
  3.  * allows an admin to delete a format 
  4.  * url: /admin/formats/delete/1 
  5.  */  
  6. function admin_delete($id = null) {  
  7.     // if the id is null  
  8.     if (!$id) {  
  9.         // set flash message  
  10.         $this->Session->setFlash('Invalid id for Format''flash_bad');  
  11.         // redirect  
  12.         $this->redirect(array('action'=>'index'));  
  13.     }  
  14.   
  15.     // set the id of the format  
  16.     $this->Format->id = $id;  
  17.   
  18.     // try to change status from 1 to 0  
  19.     if ($this->Format->saveField('status', 0)) {  
  20.         // set flash message  
  21.         $this->Session->setFlash('The Format was successfully deleted.''flash_good');  
  22.     } else {  
  23.         // set flash message  
  24.         $this->Session->setFlash('The Format could not be deleted. Please try again.''flash_bad');  
  25.     }  
  26.       
  27.     // redirect  
  28.     $this->redirect(array('action'=>'index'));  
  29. }  

Wrapping Up

Now that the Formats Controller and Views have been created we can start to populate the database with data. All of the Methods and Views that I've gone through are pretty much the building blocks of any CakePHP Application. The Create Read Update Delete (CRUD) functionality is a standard way to interact with the database and if you fully understand how this works most of the application can be completed without too many problems.
I've covered quite a few topics in this article. These include Controllers, Models, Views, Form Validation, Flash Messages, Layouts and slug creation. If you do get stuck then check out the official manual or send me an email.

Source Code

The source code for this article can be downloaded using this link. If these articles are helping you out why not consider donating I can always use a beer! :)

Posted in | Leave a comment