Introduction to CakePHP for Designers: Part II

In the first tutorial, I covered basic foundations of views, and set out create a simple task management application. This tutorial will focus on controllers, which interact with both views and models. The process of the MVC framework is a simple paradigm, where controllers handle requests, get data from the model as needed, and process the request by giving feedback to the user through views. Controllers play an important middle-man role in MVC applications.

To help illustrate the role controllers play, consider a bank. Customers request information from the bank through ATMs, online banking websites, and bank employees. Customers don’t have direct access to the bank’s safe, they must request this information from ATMs and bank tellers, etc. ATMs and tellers represent the controller in our analogy. They facilitate the requests of customers by accessing account information and money. This information is then processed and returned to the customer. In the same way, users of an MVC application make requests to the controller through views. These requests are received by the controller. The controller requests data from the database through models. Controllers then return data to views.

CakePHP controllers work closely with models to facilitate data from the database. This means we need to create a database and a table to get our controller working. We could bypass the model (controllers don’t technically need models in some cases) and just use our controller, but that would only be confusing to those learning the importance of controllers in working with both models and views.

Lets start by creating a database. For simplicity, lets name the database “taskmaster” (I know, totally cheezy :-/). You should have a working MySQL database server running. This tutorial will not go into the details of setting up MySQL and PHP. Fire up your favorite MySQL management tool, or use the handy terminal if that suits you. I’m going to type the following to login via the terminal:

mysql -u root -p

MySQL will prompt you for a password. Once you type in your password (default is blank, or no password) you will see the mysql prompt. Type in:

create database taskmaster;

Don’t forget the semi-colon! Verify that the database was created by typing in:

show databases

Now that we have our database created, lets create a table. Enter the following query to create your first table.

CREATE TABLE `tasks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `description` varchar(255) NOT NULL,
  `completed` tinyint(1) DEFAULT '0',
  `created` datetime,
  `modified` datetime,
  PRIMARY KEY (`id`)
);

This might seem like a simple table, but there are a few important conventions that CakePHP will reward. The table name “tasks” will ensure that we can create a controller called “TasksController” and a model called “Task”. We don’t have to do much configuration to start working with our data if we use these naming conventions. The lowercase id field is standard on any table in CakePHP. Created and modified columns will be automatically updated by CakePHP when we save a new record or update one. We don’t even have to worry about these columns when saving data.

Lets create a few records so we have actual data to retrieve from our model via the controller. Run the following queries to get some tasks in the tasks table:

INSERT INTO tasks (description, created, modified)
    VALUES ('Take out the trash.', NOW(), NOW());
INSERT INTO tasks (description, created, modified)
    VALUES ('Wash the car.', NOW(), NOW());

Note: I added NOW() twice to simulate what CakePHP will do when we create a new task within the application.

Now that our table is created and has a few tasks entered, lets jump over to our CakePHP application. The first order of business is telling CakePHP about our database. Navigate to app/config/database.php and change the default connection to match your database information. Mine looks like the following:

var $default = array(
	'driver' => 'mysql',
	'persistent' => false,
	'host' => 'localhost',
	'login' => 'root',
	'password' => '',
	'database' => 'taskmaster',
	'prefix' => '',
);

Create a new file in app/controllers called tasks_controller.php and populate with the following code:

<?php
class TasksController extends AppController {
	public $name = ‘Tasks’;
	
	public function index() {

	}
}

I’ve added an empty function for our default action. As you will see shortly, functions in controllers are actions requested by users through a URL. Index is the default action for any controller unless you specify otherwise in app/config/routes.php. Controller class names are camel-cased, and the file names use underscores, which is why TasksController’s filename is tasks_controller.php. Controllers are generally named the same as the name of the database table.

Now we need to create a model file. Create a new file in app/models called task.php and populate with the following:

<?php
class Task extends AppModel {
	public $name = ‘Task’;
}

We now have a skeleton model and controller. Since we have data, lets write our controller code to get our tasks from the database and then display them in the view. Our controller will request tasks from the tasks table, and for now, we will request all tasks (we only have two so far after all). Your tasks controller will look like this:

<?php
public function index() {
	$tasks = $this->Task->find('all');
	$this->set('tasks', $tasks);
}

We are getting all tasks in the database, using the Task model. $this->Task represents the model we just created. Both our controllers and models inherit a bunch of built-in functionality from AppController and AppModel.
$this->Task->find() is one such method. The controller then sets a variable for the view called “tasks” and is populated with an associative array that was returned from the find method. We have everything we need to display model data in the view…let’s get going!

Create a folder in app/views called tasks. This folder name also matches the controller name, which keeps our views organized. In the newly created folder, create a file called index.ctp, which matches our index function in TasksController, and paste the following:

<h1>Tasks</h1>
<table>
	<thead>
		<tr>
			<th scope="col">Id</th>
			<th scope="col">Description</th>
			<th scope="col">Complete?</th>
			<th scope="col">Created</th>
			<th scope="col">Modified</th>
		</tr>
	</thead>
	<tbody>
	<?php foreach($tasks as $task):
		$completed = $task['Task']['completed'] == FALSE ? 'No' : 'Yes';
	?>
		<tr>
			<td><?php echo $task['Task']['id']; ?></td>
			<td><?php echo $task['Task']['description']; ?></td>
			<td><?php echo $completed; ?> </td>
			<td><?php echo $task['Task']['created']; ?></td>
			<td><?php echo $task['Task']['modified']; ?></td>
		</tr>
	<?php endforeach; ?>
	</tbody>
</table>

You can now see the index action of our controller by navigating to the url of your application. Mine is http://localhost/cakephp-designers/tasks. The url contains our controller name “tasks”. You can omit the “index” action from the url because, like I mentioned above, index is the default action.

To illustrate how URLs match functions in a controller, you can navigate to http://localhost/cakephp-designers/tasks/index and get the same page. An add action might have this URL: http://localhost/cakephp-designers/tasks/add and would call a function called “add” in the TasksController class.

Our plain vanilla table has a foreach loop that loops through the data supplied from the controller that was assigned to a variable called tasks. It is important to understand the array structure that CakePHP returns when retrieving data from models. You can view the array by adding debug($tasks); in the view. You must have debugging turned on to see the array. You will notice that each record is contained in an associative array, where the key matches the model, or “Task”.

We now have a very simple, but functional controller. Our next tutorial will focus on learning about the form helper, getting data into our database from a form, validating that data through the model, and furthering your understanding of models and controllers in general. Until next time!

8 thoughts on “Introduction to CakePHP for Designers: Part II

  1. this was very useful!! a lot better than the cake documentation (: looking forward for more!!!

    THX!

  2. thanks, when part III and more
    i google more for explanation of this.set() and this.data , set , get data into/from view by controller…and nothing very explicit.
    Now i use the cake mvc style to a desktop aplication…and i don’t understand how canb i use this…
    scuse my english

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>