Yii-Active-Collection-Decorator

[center][size="5"]yii-active-collection-decorator[/size][/center]

This extension can decorate any ActiveRecord method which returns list of the ActiveRecord models and you can use collection as a single ActiveRecord model.

[size=4]

##Requirements

[/size]

Yii 1.*

[size=4]

##Installation

[/size]

[list=1]

[*] using git: go to the application.ext directory and clone project




$> git clone git@github.com:oncesk/yii-active-collection-decorator.git



[*] using archive: download archive and unpack it into application.ext directory, download extension

[/list]

[size=4]

##Yii configuration

[/size]

You can add extension into import section into your config/main.php file for class autoloading




return array(


  ...


  'import' => array(

    'ext.yii-active-collection-decorator.*'

  ),


  ...

);



[size=4]

##Usage

[/size]

Override method which should return list of the ActiveRecord models such as findAll and etc…

Into your ActiveRecord model




/**

 * @property integer $id

 * @property integer $status

 * @property string $name

 * @property string $avatar

 */

class User extends CActiveRecord {


  const STATUS_ACTIVE = 1;

  const STATUS_DELETED = 2;


  ...


  public function findAll($condition = '', $params = array()) {

    return ActiveCollectionDecorator::createCollection($this, parent::findAll($condition, $params));

  }


  ...


  public function relations() {

    return array(

            'posts' => array(self::HAS_MANY, 'Post', 'user_id'),

        );

  }

}




And now you can




$userCollection = User::model()->findAll();


//  simple foreach

foreach ($userCollection as $user) {

  //  $user is a User model object

}


//  ArrayAccess interface

echo $userCollection[0]->id; //  get id of the first User model in the list of the models


//  fetch any attribute as array

print_r($userCollection->name); //  output: array(0 => 'John Smith', 1 => 'Sara Mitchel', ...)


//  you can set attribute value for all models

$userCollection->status = User::STATUS_DELETED;


//  you can save all models

$userCollection->save();


//  deletion

$userCollection->delete();  // all users will be deleted


//  you can get relations

print_r($userCollection->posts);  // in output you can see posts of every user


//  filter models

$newFilteredCollection = $userCollection->filter(function (User $user) {

    return $user->status == User::STATUS_ACTIVE;

}); // will be returned new collection which contains only models with active users


//  get attribute names

print_r($userCollection->attributeNames());


//  get relations

print_r($userCollection->relations());


//  call any method in the model

$stats = $userColletion->getStatistics(); // $stats - array of each model result


//  get first model, if elements count == 0 will be returned null

if ($first = $userCollection->first()) {

    echo $first->name;

}


//  get last model, if elements count == 0 will be returned null

if ($last = $userCollection->last()) {

    echo $last->name;

}



[size=4]

##Resources

[/size]

I like the idea and the implementation looks so nice and tidy. I have a feeling this could be incorporated in the core framework, but I’d give it more thought.

BTW it’s probably the best practical example of using CMap I’ve seen to date.

it would be great =)