官术网_书友最值得收藏!

Using external actions

In Yii, you can define controller actions as separate classes and then connect them to your controllers. This way, you can reuse some common functionality.

For example, you can move backend for autocomplete fields to an action and save some time by not having to write it over and over again.

Another simple example that we will review is deleting a model.

Getting ready

  1. Set up a new application using yiic webapp.
  2. Create a DB schema with the following script:
    CREATE TABLE `post` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `created_on` int(11) unsigned NOT NULL,
      `title` varchar(255) NOT NULL,
      `content` text NOT NULL,
      PRIMARY KEY  (`id`)
    );
    
    
    CREATE TABLE `user` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `username` varchar(200) NOT NULL,
      `password` char(40) NOT NULL,
      PRIMARY KEY  (`id`)
    );
  3. Generate Post and User models using Gii.

How to do it...

  1. Let's write a usual delete action for posts first, as follows:
    class PostController extends CController
    {
       function actionIndex()
       {
          $posts = Post::model()->findAll();
          $this->render('index', array(
             'posts' => $posts,
          ));
        }
    
       function actionDelete($id)
       {
          $post = Post::model()->findByPk($id);
          if(!$post)
             throw new CHttpException(404);
    
          if($post->delete())
             $this->redirect('post/index');
          
          throw new CHttpException(500);
       }
    }

    We have defined two actions. One lists all posts and another deletes a post specified if it exists and redirects back to index action.

  2. Now, let's do the same in a separate action class. Create DeleteAction.php in your protected/components directory as follows:
    class DeleteAction extends CAction
    {
       function run()
       {
          if(empty($_GET['id']))
             throw new CHttpException(404);
          
          $post = Post::model()->findByPk($_GET['id']);
          
          if(!$post)
             throw new CHttpException(404);
    
          if($post->delete())
             $this->redirect('post/index');
          
          throw new CHttpException(500);
       }
    }
  3. Let's use it inside our controller. Delete actionDelete, we will not need it anymore. Then, add the actions method:
    class PostController extends CController
    {
       function actions()
       {
          return array(
             'delete' => 'DeleteAction',
          );
       }
    
       …
    
    }
  4. OK. Now, we are using external delete action for post controller, but what about the user controller? To use our DeleteAction with UserController we need to customize it first. We do this as follows:
    class DeleteAction extends CAction
    {
       public $pk = 'id';
       public $redirectTo = 'index';
       public $modelClass;   
    
       function run()
       {
          if(empty($_GET[$this->pk]))
             throw new CHttpException(404);
          
          $model = CActiveRecord::model($this->modelClass)->findByPk($_GET[$this->pk]);
          
          if(!$model)
             throw new CHttpException(404);
    
          if($model->delete())
             $this->redirect($this->redirectTo);
          
          throw new CHttpException(500);
       }
    }
  5. Now, we can use this action for both post controller and user controller. For post controller, we do this as follows:
    class PostController extends CController
    {
       function actions()
       {
          return array(
             'delete' => array(
                'class' => 'DeleteAction',
                'modelClass' => 'Post',
             );
          );
       }
    
       …
    
    }
  6. For user controller, we do this as follows:
    class UserController extends CController
    {
       function actions()
       {
          return array(
             'delete' => array(
                'class' => 'DeleteAction',
                'modelClass' => 'User',
             );
          );
       }
    
       …
    
    }
  7. This way, you can save yourself a lot of time by implementing and reusing external actions for tasks of a similar type.

How it works...

Every controller can be built from external actions like a puzzle from pieces. The difference is that you can make external actions very flexible and reuse them in many places. In the final version of DeleteAction, we defined some public properties. As DeleteAction is a component, we can set its properties through config. In our case, we pass config into the actions controller method used to add actions to a module.

There's more…

For further information, refer to the following URLs:

主站蜘蛛池模板: 外汇| 南木林县| 丹凤县| 奇台县| 抚松县| 武定县| 长治县| 渝中区| 建昌县| 醴陵市| 平遥县| 淮阳县| 曲麻莱县| 建宁县| 仁寿县| 民和| 垣曲县| 饶河县| 浏阳市| 巴彦淖尔市| 绵竹市| 互助| 黔西| 林口县| 乌拉特前旗| 阳朔县| 济宁市| 临泉县| 南汇区| 英山县| 祁阳县| 黑龙江省| 莆田市| 临汾市| 天气| 蒙自县| 鱼台县| 如皋市| 岑巩县| 长寿区| 漳州市|