Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
CakePHP 2 Application Cookbook

You're reading from   CakePHP 2 Application Cookbook Over 60 useful recipes for rapid application development with the CakePHP framework.

Arrow left icon
Product type Paperback
Published in Aug 2014
Publisher
ISBN-13 9781782160083
Length 346 pages
Edition 3rd Edition
Languages
Tools
Arrow right icon
Toc

Table of Contents (14) Chapters Close

Preface 1. Lightning Introduction FREE CHAPTER 2. Advanced Routing 3. HTTP Negotiation 4. API Strategies 5. Using Authentication 6. Model Layer 7. Search and Pagination 8. Events System 9. Creating Shells 10. View Templates 11. Unit Tests 12. Migrations Index

Adding and editing records

While listing and viewing records is handy, the ability to create and edit records allows you to build up and maintain your data.

In this recipe, we'll create actions to both add new products and edit the existing ones in our database.

Getting ready

For this recipe, we'll continue using the products table from the previous recipe. We'll also extend the ProductsController that was created.

For the views, we'll add add.ctp and edit.ctp files to our app/View/Products/ directory, and also a form.ctp file in the Products/ directory that we'll create in app/View/Elements/.

How to do it...

Perform the following steps:

  1. Add the following add() method to the ProductsController class:
    public function add() {
      if ($this->request->is('post')) {
        $this->Product->create();
        if ($this->Product->save($this->request->data)) {
          $this->Session->setFlash(__('New product created'));
          return $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('Could not create product'));
      }
    }
  2. Just below the add() method, also add an edit() method:
    public function edit($id) {
      $product = $this->Product->findById($id);
      if (!$product) {
        throw new NotFoundException(__('Product not found'));
      }
      if ($this->request->is('post')) {
        $this->Product->id = $id;
        if ($this->Product->save($this->request->data)) {
          $this->Session->setFlash(__('Product updated'));
          return $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('Could not update product'));
      } else {
        $this->request->data = $product;
      }
    }
  3. Introduce the following content in the form.ctp element file:
    <?php
    echo $this->Form->create('Product');
    echo $this->Form->inputs();
    echo $this->Form->end(__('Submit'));
  4. Introduce the following content in the add.ctp file:
    <?php echo $this->element('Products/form'); ?>
  5. The edit.ctp file will also take the same content, but the header text will be changed to the following code:
    <?php echo $this->element('Products/form'); ?>
  6. Return to the index.ctp file, and change it's content to the following:
    <h2><?php echo __('Products'); ?></h2>
    <div>
      <?php echo $this->Html->link(__('Add new product'), array('action' => 'add')); ?>
    </div>
    <table>
      <tr>
        <th><?php echo $this->Paginator->sort('id'); ?></th>
        <th><?php echo $this->Paginator->sort('name'); ?></th>
        <th><?php echo $this->Paginator->sort('created'); ?></th>
        <th><?php echo __('Actions'); ?></th>
      </tr>
      <?php foreach ($products as $product): ?>
        <tr>
          <td><?php echo $product['Product']['id']; ?></td>
          <td><?php echo $this->Html->link($product['Product']['name'], array('action' => 'view', $product['Product']['id'])); ?></td>
          <td><?php echo $this->Time->nice($product['Product']['created']); ?></td>
          <td><?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $product['Product']['id'])); ?></td>
        </tr>
      <?php endforeach; ?>
    </table>
    <div>
      <?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}'))); ?>
    </div>
    <div>
      <?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>
  7. Navigate to /products in your web browser, and click one of the Edit links to modify a product. The following screenshot shows the screen that will appear:
    How to do it...
  8. Return to /products, and click on the Add new product link to create a new product. The following screenshot shows the screen that will appear:
    How to do it...

How it works...

Here, we extended our previous recipe by adding some extra methods to create new products and edit the existing ones. The add() method first checks whether the current request has been made using the HTTP POST method. If that's the case, we call the create() method on the Product model. This doesn't create a new record yet, but instead it prepares our model object for a new record to be created. We then call the save() method, passing the data provided in the request to it. The framework handles this internally through the Form helper, which we'll see in a moment. The condition checks whether the save is successful (here, a new record is created), and if so, it calls the setFlash() method on our Session component to register a success message to be displayed on the page that follows. We do the same in the event that the record could not be saved, and it provided a failure message. We then wrap up the method by redirecting the request to our index() action.

For the edit() method, we first check that the product for the given ID actually exists using the findById() method on the Product model. See the previous recipe, Listing and viewing records, for details on finding records. If the product doesn't exist, a NotFoundException is thrown; this is rendered as an error page. As with the add() method, we first check that the request was made via POST. However, instead of calling the create() method on our Product model, we set the $id property with the $id argument passed to our action. We then follow the same process of calling the save() method with the request data, as well as setting the result messages for the view and redirecting the request.

We finalize our edit action by populating the request data if it does not exist so that when you visit the form for editing, it's populated with the existing values from the products table.

For our views, we've taken the initiative to use an element. These are reusable sections of our views, which allow us to segment and organize our visual interface and cut down on duplicate code. Here, we've done this to avoid declaring the same form twice and reuse the same one instead. The framework is able to distinguish between the two (adding a record and editing a record) by the presence of an ID. In which case, it assumes that we're editing a record instead of creating one. In this file, we use the Form helper to generate a new form using the create() method and passing the name of the model to it, it will act against. We also called the inputs() method to create the required inputs based on the table schema and then called the end() method to complete the form.

For our add.ctp and edit.ctp view files, we included our element using the element() method, passing it the location of our form.ctp file. You'll notice that we created our element in the Products/ directory, as the form is intended for a product. We could change the contents of our element to receive the model name via an element parameter, making it more dynamic and, therefore, reusable even further. Finally, we updated the index.ctp view to include an Edit option using the link() method from the Html helper.

You'll also see that we passed the ID of each product to this method in our foreach() statement, thus generating a link for each product with its unique ID as part of the URL. We also added a link to "add a new product", which redirects you to the new add() action to create a new record in the products table.

See also

You have been reading a chapter from
CakePHP 2 Application Cookbook - Third Edition
Published in: Aug 2014
Publisher:
ISBN-13: 9781782160083
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image