Creating reusable controller actions

Common actions, such as deleting the AR model by the primary key or getting data for AJAX autocomplete, could be moved into reusable controller actions and later attached to controllers as needed.

In this recipe we will create a reusable delete action that will delete the specified AR model by its primary key.

Getting ready

  1. Create a fresh Yii application using yiic webapp.
  2. Create a new database and configure it.
  3. Execute the following SQL:
    CREATE TABLE `post` (
      `id` int(11) NOT NULL auto_increment,
      `text` text,
      `title` varchar(255) default NULL,
      PRIMARY KEY  (`id`)
    );
    
    CREATE TABLE `comment` (
      `id` int(11) NOT NULL auto_increment,
      `text` text,
      PRIMARY KEY  (`id`)
    );
  4. Generate models for post and comment using Gii.

How to do it...

  1. Create protected/extensions/actions/EDeleteAction.php:
    <?php
    class EDeleteAction extends CAction
    {
      public $modelName;
      public $redirectTo = array('index'),
    
      /**
       * Runs the action.
       * This method is invoked by the controller owning this action.
       */
      public function run($pk)
      {
        CActiveRecord::model($this->modelName)->deleteByPk($pk);
        if(Yii::app()->getRequest()->getIsAjaxRequest())
        {
          Yii::app()->end(200, true);
        }
        else
        {
          $this->getController()->redirect($this->redirectTo);
        }
      }
    }
  2. Now, we need to attach it to the controller, protected/controllers/DeleteController.php:
    <?php
    class DeleteController extends CController
    {
      public function actions()
      {
        return array(
          'deletePost' => array(
            'class' => 'ext.actions.EDeleteAction',
            'modelName' => 'Post',
            'redirectTo' => array('indexPosts'),
          ),
          'deleteComment' => array(
            'class' => 'ext.actions.EDeleteAction',
            'modelName' => 'Comment',
            'redirectTo' => array('indexComments'),
          ),
        );
      }
    
      public function actionIndexPosts()
      {
        echo "I'm the index action for Posts.";
      }
    
      public function actionIndexComments()
      {
        echo "I'm the index action for Comments.";
      }
    }
  3. That's it. Now, you can delete a post by visiting /delete/deletePost/pk/<pk> and delete a comment by visiting /delete/deleteComment/pk/<pk>. After the deletion, you will be redirected to a corresponding index action.

How it works...

To create an external controller action, you need to extend your class from CAction. The only mandatory method to implement is run. In our case it accepts the parameter named pk from $_GET using the automatic parameter binding feature of Yii and tries to delete a corresponding model.

To make it customizable we've created two public properties configurable from the controller. These are modelName, which holds the name of the model we are working with, and redirectTo, which specifies a route the user will be redirected to.

Configuration itself is done by implementing the actions method in your controller. There you can attach the action once or multiple times and configure its public properties.

There's more...

There are two usable methods implemented in CAction. First is getController, which we can use to get an instance of the controller that the action is attached to. You will need it to redirect to another action or, for example, generate a URL.

Another method is getId, which returns the action name specified in the controller's actions method.

Further reading

To learn more about external controller action refer to the following API pages:

See also

  • The Creating reusable controllers recipe
  • The Making extensions distribution-ready recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.150.89