Pergunta

In my controllers a lot of code, about 1000 lines Advise how you can make more convenient, for example to make a piece of code in trait

components/ProductTrait.php

trait ProductTrait{

protected function getProductProvider(Product $model){
    $dataProductProvider = new CActiveDataProvider('Product', array(
            'criteria' => array(
                    'limit' => $pageLimit,
                    'condition' => 't.creatorId = :creatorId AND t.categoryId =:categoryId',
                    'order' => 't.created DESC',
                    'params' => array(
                            ':creatorId' => $model->creatorId,
                            ':categoryId' => $model->categoryId,
                    ),
            ),
            'pagination' => false,
            'sort' => false,
    ));
    return $dataProductProvider;
 }


}

Controller

class DealerController extends Controller{
use ProductTrait;
public function actionView($id){
    $model = $this->loadModel($id);
    if ($model === null) {
        throw new CHttpException(404, 'The requested page does not exist.');
    }
    $renderParams['productProvider'] = $this->getProductProvider($model);
 }  

}
Foi útil?

Solução

You can use Trait, but you can also use behaviors.

First you declare your behavior

class ProductBehavior extends CBehavior
{
    protected function getProductProvider(Product $model){
        $dataProductProvider = new CActiveDataProvider('Product', array(
            'criteria' => array(
                    'limit' => $pageLimit,
                    'condition' => 't.creatorId = :creatorId AND t.categoryId =:categoryId',
                    'order' => 't.created DESC',
                    'params' => array(
                            ':creatorId' => $model->creatorId,
                            ':categoryId' => $model->categoryId,
                    ),
            ),
            'pagination' => false,
            'sort' => false,
        ));
        return $dataProductProvider;
    }
}

Then you use it in your controller (don't forget to attach it, I've done it in the init method)

class DealerController extends Controller{

    public function init() {
        //Attach the behavior to the controller
        $this->attachBehavior("productprovider",new ProductBehavior);
    }

    public function actionView($id){
        $model = $this->loadModel($id);
        if ($model === null) {
            throw new CHttpException(404, 'The requested page does not exist.');
        }
        //We use the behavior methods as if it is one of the controller methods
        $renderParams['productProvider'] = $this->getProductProvider($model);
    }   
}

The main point of behaviors is it's working in php 5.3 whereas trait are not.

Now here's some difference between traits and behaviors:

  • A first difference with behaviors is that traits can not be parameterized.

In your controller you could declare the behaviors this way:

public function behaviors(){
        return array(
                'ProductBehavior ' => array(
                        'class' => 'components.behaviors.ProductBehavior',
                        'firstAttribute' => 'value',
                        'secondAttribute' => 'value',
                )
        );
}

Your ProductBehavior class would have 2 public attributes: firstAttribute and secondAttribute.

  • One thing traits lack when compared to behaviors is runtime attachement. If you want to extend a given (let's say 3rdParty) class with some special functionality, behaviors give you a chance to attach them to the class (or more specifically to instances of the class). Using traits, you had to to modify the source of the class.

  • A Wiki about behaviors

  • The Yii Guide
  • The CBehavior doc
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top