Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Cook up websites fast with CakePHP, Part 2: Bake bigger and better with CakePHP

Duane O'Brien, PHP developer, Freelance
Duane O'Brien has been a technological Swiss Army knife since the Oregon Trail was text only. His favorite color is sushi. He has never been to the moon.

Summary:  CakePHP is a stable production-ready, rapid-development aid for building websites in PHP. This "Cook up websites fast with CakePHP" series shows you how to build an online product catalog using CakePHP. Part 2 demonstrates how to use scaffolding and Bake to get a jump start on your application, and how to use CakePHP's access control lists (ACLs).

View more content in this series

Date:  15 Jan 2013 (Published 12 Dec 2006)
Level:  Intermediate PDF:  A4 and Letter (1077 KB | 31 pages)Get Adobe® Reader®

Activity:  135654 views
Comments:  

Using the Bake code generator

It's not necessary to completely throw away everything scaffolding gives you. By using Bake, the CakePHP code generator, you can generate a controller that contains functions that represent the scaffolding functionality and the views to go with it. For the products-related parts of Tor, this will be a huge time-saver.

In CakePHP V1.1, Bake was a PHP script that you called directly. Starting with CakePHP V1.2, the Bake functionality moved to the Cake Console, which you will learn about through the rest of this tutorial. You can simplify your life if you add the path /webroot/app/Console to your environment's PATH variable. This will allow you to call the Cake Console without specifying path information. You don't need to do this, and the tutorial will assume you have not. Additionally, you should run the Cake Console from your application's app directory—in this case, /webroot/app—or the Cake Console will think you are trying to do something new.

Before you proceed, make a copy of your existing app directory. Bake will overwrite the products controller, and you should always back up your files when an operation involves the word "overwrite" (or the words "copy," "delete," "format," or "voodoo"). If you have problems getting this to run, make sure the php executable is in your environment's PATH variable, and that you have the PHP Command Line Interface installed.

Baking your products controller

To use Bake, cd into the /webroot/app directory and launch the Cake Console: ../cake/Console/cake bake. You should be presented with a screen that looks like Figure 2.


Figure 2. Bake menu
Screen capture of the Bake menu

For the Tor application, the models you've written should be fine, so let's start with the controller. Press C to select the controller. The Cake Console will look at the application as it stands, ask you which database config you want to use, and present a list of possible controllers you might want to bake (see Figure 3).


Figure 3. Controller name
Screen capture of the Controller name

In this case, you are baking the Products controller, which should be controller No. 2. Bake will ask if you want to build the controller interactively. For now, press N to let Bake make all the decisions on its own, but later on, you should try building a controller interactively to get a feel for what Bake can do for you beyond this. Bake will then ask if you want to include some basic class methods (see Figure 4). Press Y—getting this code is the whole reason you are here. Next, Bake will ask if you want to create methods for admin routing. Press N—you don't need these right now. Bake will ask you to confirm the controller before continuing. When you continue, Bake will make sure you want to overwrite the existing controller (in this case, you do). Bake should then inform you that it's created the file /webroot/app/Controller/ProductsController.php and ask if you want to bake some unit test files. You can skip these for now. Once you are done, you will be returned to the Bake menu (see Figure 4).


Figure 4. Controller created
Screen capture after the Controller created

That's all there is to it. Exit the Cake Console, open up app/Controller/ProductsController.php and look at what Bake did for you. It should look something like Listing 9.


Listing 9. ProductsController.php after Bake

<?php
App::uses('AppController', 'Controller');
/**
 * Products Controller
 *
 * @property Product $Product
 */
class ProductsController extends AppController {


/**
 * index method
 *
 * @return void
 */
    public function index() {
        $this->Product->recursive = 0;
        $this->set('products', $this->paginate());
    }

/**
 * view method
 *
 * @param string $id
 * @return void
 */
    public function view($id = null) {
        $this->Product->id = $id;
        if (!$this->Product->exists()) {
            throw new NotFoundException(__('Invalid product'));
        }
        $this->set('product', $this->Product->read(null, $id));
    }

/**
 * add method
 *
 * @return void
 */
    public function add() {
        if ($this->request->is('post')) {
            $this->Product->create();
            if ($this->Product->save($this->request->data)) {
                $this->Session->setFlash(__('The product has been saved'));
                $this->redirect(array('action' => 'index'));
            } else {
                $this->Session->setFlash(__('The product could not be saved. 
Please, try again.'));
            }
        }
        $dealers = $this->Product->Dealer->find('list');
        $this->set(compact('dealers'));
    }

/**
 * edit method
 *
 * @param string $id
 * @return void
 */
    public function edit($id = null) {
        $this->Product->id = $id;
        if (!$this->Product->exists()) {
            throw new NotFoundException(__('Invalid product'));
        }
        if ($this->request->is('post') || $this->request->is('put')) {
            if ($this->Product->save($this->request->data)) {
                $this->Session->setFlash(__('The product has been saved'));
                $this->redirect(array('action' => 'index'));
            } else {
                $this->Session->setFlash(__('The product could not be saved. 
Please, try again.'));
            }
        } else {
            $this->request->data = $this->Product->read(null, $id);
        }
        $dealers = $this->Product->Dealer->find('list');
        $this->set(compact('dealers'));
    }

/**
 * delete method
 *
 * @param string $id
 * @return void
 */
    public function delete($id = null) {
        if (!$this->request->is('post')) {
            throw new MethodNotAllowedException();
        }
        $this->Product->id = $id;
        if (!$this->Product->exists()) {
            throw new NotFoundException(__('Invalid product'));
        }
        if ($this->Product->delete()) {
            $this->Session->setFlash(__('Product deleted'));
            $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('Product was not deleted'));
        $this->redirect(array('action' => 'index'));
    }
}

This controller that you generated using the Cake Console contains the same basic functionality you got from scaffolding, but now you can tweak it to fit your needs. Pretty slick. Ready to go again?


Baking your products views

Now that you've baked the products controller, all Tor needs is some product views. Bake will do those for you, too. Start as before in your /webroot/app directory: ../cake/Console/cake bake.

The initial Bake menu should look just like it did when you baked the controller. This time, though, it's time to bake some views. Press V to select views. You will get another list of possible views to be baked. Products should still be No. 2 on the list. Bake will ask if you want to build your views interactively (No). You can come back later and play around with the different baking options.

Once you get past the options, Bake should inform you that it created the views (see Figure 5).


Figure 5. Bake informs you that it has created the views
Screen capture of Bake informing you that it has created the views

Exit the Cake Console, open the app/views/products/index.ctp view, and take a look. It should look something like Listing 10.


Listing 10. The index

<div class="products index">
    <h2><?php echo __('Products');?></h2>
    <table cellpadding="0" cellspacing="0">
    <tr>
            <th><?php echo $this->Paginator->sort('id');?></th>
            <th><?php echo $this->Paginator->sort('title');?>
	</th>
            <th><?php echo $this->Paginator->sort('dealer_id');?>
	</th>
            <th><?php echo $this->Paginator->sort('description');?>
	</th>
            <th class="actions"><?php echo __('Actions');?></th>
    </tr>
    <?php
    foreach ($products as $product): ?>
    <tr>
        <td><?php echo h($product['Product']['id']); ?>&nbsp;</td>
        <td><?php echo h($product['Product']['title']); ?>&snbsp;</td>
        <td>
            <?php echo $this->Html->link($product['Dealer']['title'], 
array('controller' => 'dealers', 'action' => 'view', $product['Dealer']
['id'])); ?>
        </td>
        <td><?php echo h($product['Product']['description']); ?>
&nbsp;</td>
        <td class="actions">
            <?php echo $this->Html->link(__('View'), array('action' => 
'view', $product['Product']['id'])); ?>
            <?php echo $this->Html->link(__('Edit'), array('action' => 
'edit', $product['Product']['id'])); ?>
            <?php echo $this->Form->postLink(__('Delete'), 
array('action' => 'delete', $product['Product']['id']), null, __('Are you sure you 
want to delete # %s?', $product['Product']['id'])); ?>
        </td>
    </tr>
<?php endforeach; ?>
    </table>
    <p>
    <?php
    echo $this->Paginator->counter(array(
    'format' => __('Page {:page} of {:pages}, showing {:current} records out 
of {:count} total, starting on record {:start}, ending on {:end}')
    ));
    ?>    </p>

    <div class="paging">
    <?php
        echo $this->Paginator->prev('< ' . __('previous'), array(), null, 
array('class' => 'prev disabled'));
        echo $this->Paginator->numbers(array('separator' => ''));
        echo $this->Paginator->next(__('next') . ' >', array(), null, 
array('class' => 'next disabled'));
    ?>
    </div>
</div>
<div class="actions">
    <h3><?php echo __('Actions'); ?></h3>
    <ul>
        <li><?php echo $this->Html->link(__('New Product'), 
array('action' => 'add')); ?></li>
        <li><?php echo $this->Html->link(__('List Dealers'), 
array('controller' => 'dealers', 'action' => 'index')); ?> </li>
        <li><?php echo $this->Html->link(__('New Dealer'), 
array('controller' => 'dealers', 'action' => 'add')); ?> </li>
    </ul>
</div>

Take a look in the those other views, as well. That's a whole lot of writing you didn't have to do. You'll be tweaking these views later to help lock down Tor.

Take it for a test drive

You've baked a controller and the necessary views for the products functionality. Take it for a spin. Start at http://localhost/products and walk through the various parts of the application. Add a product. Edit one. Delete another. View a product. It should look exactly like it did when you used scaffolding.


Bake bigger and better

This isn't the end of what Bake can do for you. There will be a couple exercises at the end of the tutorial to let you venture out on your own. Keep in mind that the code generated by Bake is intended to be your starting point, not the end of your development work. But it's a tremendous time-saver if used properly.

4 of 13 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=390704
TutorialTitle=Cook up websites fast with CakePHP, Part 2: Bake bigger and better with CakePHP
publish-date=01152013
author1-email=d@duaneobrien.com
author1-email-cc=