Wednesday, 13 August 2014

Full CakePHP 1.2 App Part 3

CakePHP 1.2 Full Application
Welcome to the 3rd article in a series on creating a full CakePHP 1.2 Application. If your new and interested in the project then check out part 1 and part 2 to get fully up to speed on the application in question and see what I've done so far. Just quickly, last time I went through creating the Controller and Views for the Formats table in the database and at the end I could view / add / edit and delete formats using the application.
In this article I'm going to create the Controllers and Views for the Types and Locations. This is going to be pretty simple because they include the exact same functionality as the Formats that was created previously. At the end of the article I will be able to start adding even more data to the database and have a strong understanding of the way CakePHP deals with data.

Types and Locations

I'll concentrate on the Controllers first so create two new files named types_controller.php andlocations_controller.php respectively. Each file will contain the same methods as theformats_controller.php which include index(), view(), admin_index(), admin_add(), admin_edit() and admin_delete().
/**
 * Types Controller
 *
 * file: /app/controllers/types_controller.php
 */
class TypesController extends AppController {
 // good practice to include the name variable
 var $name = 'Types';
 
 // load any helpers used in the views
 var $helpers = array('Html', 'Form');

 /**
  * index()
  * main index page of the types page
  * url: /types/index
  */
 function index() {

 }

 /**
  * view()
  * displays a single Type and all related dvds
  * url: /types/view/type_slug
  */
 function view($slug = null) {

 }

 /**
  * admin_index()
  * main index for admin users
  * url: /admin/types/index
  */
 function admin_index() {

 }

 /**
  * admin_add()
  * allows an admin to add a type
  * url: /admin/types/add
  */
 function admin_add() {

 }

 /**
 * admin_edit()
 * allows an admin to edit a type
 * url: /admin/types/edit/1
 */
 function admin_edit($id = null) {

 }

 /**
  * admin_delete()
  * allows an admin to delete a Type
  * url: /admin/Types/delete/1
  */
 function admin_delete($id = null) {

 }

}
Instead of coding the two files from scratch I simply copied and pasted the code from my Formats Controller into the newly created files and changed all the references from the plural Formats toTypes/Locations and I also changed the singular Format to Type/Location. This will ensure that the correct Model will be used and thus the correct table in the database.
/**
 * index()
 * main index page of the types page
 * url: /types/index
 */
function index() {
 // this tells cake to ignore related type data such as dvds
 $this->Type->recursive = 0;

 // get all types from database where status = 1
 $types = $this->Type->findAll("status=1");

 // save the types in a variable for the view
 $this->set('types', $types);
}
The 3 Controllers Formats, Types and Locations have the exact same functionality so copying and pasting code is the most efficient way of getting up and running.
Next up are the View files, I created two new folders called types and locations inside the/app/views folder and the View files from the formats directory were copied over and all references of Formats was changed to Types and Locations respectively.
<?php

// file: /app/views/types/admin_index.ctp

?>
<div class="types index">

 <h2>Types Admin Index</h2>
    <p>Currently displaying all types in the application.</p>

    <?php
 // check $types variable exists and is not empty
 if(isset($types) && !empty($types)) :
 ?>

    <table>
     <thead>
         <tr>
             <th>Id</th>
                <th>Name</th>
                <th>Slug</th>
                <th>Description</th>
                <th>Created</th>
                <th>Modified</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
         <?php
   // initialise a counter for striping the table
   $count = 0;

   // loop through and display format
   foreach($types as $type):
    // stripes the table by adding a class to every other row
    $class = ( ($count % 2) ? " class='altrow'": '' );
    // increment count
    $count++;
   ?>
            <tr<?php echo $class; ?>>
             <td><?php echo $type['Type']['id']; ?></td>
                <td><?php echo $type['Type']['name']; ?></td>
                <td><?php echo $type['Type']['slug']; ?></td>
                <td><?php echo $type['Type']['desc']; ?></td>
                <td><?php echo $type['Type']['created']; ?></td>
                <td><?php echo $type['Type']['modified']; ?></td>
                <td>
                <?php echo $html->link('Edit', array('action'=>'admin_edit', $type['Type']['id']) );?>
                <?php echo $html->link('Delete', array('action'=>'admin_delete', $type['Type']['id']), null, sprintf('Are you sure you want to delete Type: %s?', $type['Type']['name']));?>
                </td>
            </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
    
    <?php
 else:
  echo 'There are currently no Types in the database.';
 endif;
 ?>
    
 <ul class="actions">
  <li><?php echo $html->link('Add a Type', array('action'=>'add')); ?></li>
 </ul>

</div>
To test that everything is working correctly add / edit / delete some types and locations athttp://dvdcatalog/admin/types and http://dvdcatalog/admin/locations and if everything was copied successfully you should have no problems.
CakePHP 1.2 Full Application Image 3 CakePHP 1.2 Full Application Image 4 CakePHP 1.2 Full Application Image 5

CakePHP Data

I think that the single most useful feature of CakePHP is how it deals with data and the ease with which it handles associations. If the Model's are setup correctly with relationships between tables in the database then retrieving and adding related data is all handled by the framework and is one less thing that I need to worry about.
In the index() method of the Controllers there is a assignment of the recursive variable, this tells Cake how deep you want associated data to be processed. For example by setting the value to be 0 no associated data will be fetched in this case no DVDs associated with a type will be retreived from the database:
// $this->Type->recursive = 0;
// $types = $this->Type->findAll("status=1");
Array
(
    [0] => Array
        (
            [Type] => Array
                (
                    [id] => 1
                    [name] => Film
                    [...] => ...
                )
        )

    [1] => Array
        (
            [Type] => Array
                (
                    [id] => 2
                    [name] => TV Show
                    [...] => ...
                )
        )
)
If I change this value to 1 then the DVDs will be processed, a sample of the data is below. If I changed this value to 2 then the associated data of DVDs will be fetched from the database. Its a hierarchy and allows us to drill down into the associated data which is extremely helpful but not always needed and thats why it's set to 0 in the index() methods.
// $this->Type->recursive = 1;
// $types = $this->Type->findAll("status=1");
Array
(
    [0] => Array
        (
            [Type] => Array
                (
                    [id] => 1
                    [name] => Film
                )

            [Dvd] => Array
                (
                )
        )
    [1] => Array
        (
            [Type] => Array
                (
                    [id] => 2
                    [name] => TV Show
                )
            [Dvd] => Array
                (
                )
        )
)
For more info check out the manual on the recursive variable. As you can see from the retrieved data CakePHP works on a series of Conventions and will always retrieve data in an array whose array key is the Model name of the data being processed and any related data will by seperated into its own array, also by Model name.

No comments:

Post a Comment