Yii: Returning array data from a ActiveRecord object

Posted by & filed under PHP, Programming.

Two simple ways to convert a ActiveRecord object into a array:

  1. Using cHTML::ListDatause CHtml::listData (see www.yiiframework.com/wiki/48/by-example-… )
    $users = User::model()->findAll();
    $usersArr = CHtml::listData( $users, 'id' , 'city');
    print_r( $usersArr );

    It will give you array id => city

    Array {
        2 => 'Paris',
        102 => 'Riga',
        // ...
  2. Using array_map (used this method last time, array_map rocks):
    $words = Word::model()->findAll();
    $data=array_map(create_function('$m','return $m->getAttributes();'),$words);


Yii Components

Posted by & filed under PHP, Programming.

Yii components can be quite handy, exposing functions to the entire app. This helps keep the controller thin and adheres to the DRY methodology.

To create a “Hello World” component, first we create the component in protected/components, and populate it with:

class Hello extends CApplicationComponent
    public function init() 
        // Any needed initialization for the component goes here

    public function World() 
        return "Hello World!";

Now that we have our component, the next step is to modify our protected/config/main.php, including our new component in the components array:




In the same file, we can set our component to be preloaded. Meaning it won’t be lazy loaded on first access, but rather preloaded on the app’s init.

	// preloading components

Lastly, we can access the output from our component by using something like:


Echoing this var should display “Hello World”

//Prints "Hello World"
echo Yii::app()->Hello->World();

Google AJAX APIs & Yii

Posted by & filed under Uncategorized.

I was snooping around the Yii documentation and came across system.web.helpers CGoogleApi. It’s here: www.yiiframework.com/doc/api/1.1/CGoogle…
Anyway, my interest was piqued, so I took a look at whatGoogle has to offer. I was expecting calendar, maps, search yadda. There LOTS more!

Google has a playground that you can use to demo the APIs: code.google.com/apis/ajax/playground

Translation, RSS Feeds, Maps/Directions, and all the other Google services are all right there!

jQuery-UI Themeroller & Yii Widgets

Posted by & filed under Uncategorized.

Here is the lowdown on theming jQuery:

  • Create the Theme: jqueryui.com/themeroller/
  • Extract and upload the contents of the theme’s css directory to /css/jui (we set this later on…)
  • Add themeUrl, theme, and cssFile (see example below). Be sure to set them according to the path of the files you just uploaded.
    themeurl is the base folder for the theme… usually in the css folder. I use /css/jui.
    theme is the folder name inside e.g. /css/jui/humanity
    cssfile is the theme’s cssfile.

$this->widget('zii.widgets.jui.CJuiAccordion', array(

/* optional: change visual
* themeUrl: "where the themes for this widget are located?"
* theme: theme name. Note that there must be a folder under themeUrl with the theme name
* cssFile: specifies the css file name under the theme folder. You may specify a
* single filename or an array of filenames
* try http://jqueryui.com/themeroller/
'themeUrl' => Yii::app()->baseUrl.'/css/jui' ,
'theme'=>'humanity', //try 'bee' also to see the changes
'cssFile'=>array('jquery-ui.css' /*,anotherfile.css, etc.css*/),


MySQL: Create a Unique Composite Key

Posted by & filed under Uncategorized.

I had a scenario where I want to ensure that multiple values are unique in a table. Meaning I want to allow this:

|name                tournamentid         | 
|=========================== |
| nathan gibbs              2                 |
| nathan gibbs              6                 |
| jeff tester                2                 |
| jeff tester                6                 |

But not this:

|name                tournamentid         | 
|=========================== |
| nathan gibbs              2                 |
| nathan gibbs              2                 |
| jeff tester                6                 |
| jeff tester                6                 |

This is suprisingly easy to use when we implement unique composite keys. For an existing table:

ALTER TABLE `TableName` ADD UNIQUE KEY (KeyOne, KeyTwo, ...);

Now if a insert is attempted the following error is thrown:

Integrity constraint violation: 1062 Duplicate entry ‘Nathan Riley-4’ for key ‘name’

In yii, we trap this using a custom validator class in components/CompositeUniqueKeyValidator.php:

if (count($keyColumns) == 1) {
throw new CException('CUniqueValidator should be used instead');
$columnsLabels = $object->attributeLabels();

$criteria = new CDbCriteria();
$keyColumnsLabels = array();
foreach ($keyColumns as &$column) {
$column = trim($column);
$criteria->compare($column, $object->$column);
$keyColumnsLabels[] = $columnsLabels[$column];
$criteria->limit = 1;

if ($class::model()->count($criteria)) {
$message = Yii::t('yii', $this->errorMessage, array(
'{columns_labels}' => join(', ', $keyColumnsLabels)
if ($this->addErrorToAllColumns) {
foreach ($keyColumns as $column) {
$this->addError($object, $column, $message);
else {
$this->addError($object, $attribute, $message);



Then in our model’s rules():

public function rules()
return array(
array('name', 'CompositeUniqueKeyValidator', 'keyColumns' => 'name, tournamentId'),

Yii model relationships()

Posted by & filed under Programming.

It’s very common to see new Yii users confusing the relations HAS_ONE and BELONGS_TO, and getting it wrong means you won’t get proper values back. And though we’ll talk about HAS_MANY as well, we’re specifically omitting the MANY_MANY relation because it’s a whole different animal.


Yii CGridView dropdown for page size

Posted by & filed under Programming.

I found myself in the need for a dropDownList to select the page size on a CGridView. I was amazed that only a few lines of code where required. So i thought i’d share.

On top of my controller action for the gridview (if you used CRUD, this is actionAdmin() ) i added:

// page size drop down changed
if (isset($_GET['pageSize'])) {
unset($_GET['pageSize']); // would interfere with pager and repetitive page size change

In the model (e.g. model/User.php) the data provider in search() is configured like:

return new CActiveDataProvider(get_class($this),array(
'pageSize'=> Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']),

And finally the view (e.g. views/user/admin.php) :

user->getState('pageSize',Yii::app()->params['defaultPageSize']); ?>

// change 'user-grid' to the actual id of your grid!!
'onchange'=>"$.fn.yiiGridView.update('user-grid',{ data:{pageSize: $(this).val() }})",

Et voilà, we have a page size selector that keeps it’s value in user state.

Forgot to mention the configuration in the application parameters:

// Accessable with Yii::app()->params['paramName']
'params'=>array (


Understanding Yii’s RBAC

Posted by & filed under Programming.

Yii is a very powerful PHP framework, and among other PHP frameworks it is distinguished by its great object-oriented design, MVC support, speed, flexibility and many other virtues. Recently I had some experience with the PRADO framework and chose Yii to build my image processing web application demo. It took some time for my app to stay in my home server sandbox and now it’s matured enough to be revealed to public.


Yii Fragment Caching

Posted by & filed under Uncategorized.

Fragment caching refers to caching a fragment of a page. For example, if a page displays a summary of yearly sale in a table, we can store this table in cache to eliminate the time needed to generate it for each request.

To use fragment caching, we call CController::beginCache() and CController::endCache() in a controller’s view script. The two methods mark the beginning and the end of the page content that should be cached, respectively. Like data caching, we need an ID to identify the fragment being cached.