ENUM DB type in Yii
#1
Posted 25 June 2010 - 09:05 AM
Whats the best practice in Yii to work with database fields that its values are a list of items?
Currently, I'm using the ENUM type of MySQL, but I don't know how Yii can work with this type. Is there any way to retrieve the values of the enum type and that Yii manages it?
Thanks in advance.
Regards.
Kike
#2
Posted 28 June 2010 - 03:00 AM
public static function enumItem($model,$attribute) { $attr=$attribute; self::resolveName($model,$attr); preg_match('/\((.*)\)/',$model->tableSchema->columns[$attr]->dbType,$matches); foreach(explode(',', $matches[1]) as $value) { $value=str_replace("'",null,$value); $values[$value]=Yii::t('enumItem',$value); } return $values; }
Maybe you can do better with regExp, but this code at least works and gives you an array with the items.
#3
Posted 01 July 2010 - 10:50 AM
Regards:
Kike
#4
Posted 02 July 2010 - 02:50 AM
I have never had problem of performance with this, but I never had more than 4-5 dropdownlist from enum in a page, I use only in form.
Just pay attention to reuse the items if you have to place 500 times in a page.
#6
Posted 03 December 2010 - 12:21 AM
Hi! Nice solution.. I've seen others quite messed.
Sorry for my snoob question but I'm pretty new to Yii:

Where it's supposed to be sit that function? Is there a place where it *must be* or where it could be *comfortable* with the rest of the framework?
TIA,
Pampa
#7
Posted 03 December 2010 - 12:44 AM

I've dropped your code (commented out the line resolveName()) in my model file.
Then, in the view I've called it in this way:
<?php echo CHtml::activeDropDownList( $model,'status',$model->enumItem($model, 'status') ); ?>
Where 'status' is an ENUM('Active','Inactive','Deleted').
Hope to help someone

#8
Posted 03 December 2010 - 02:44 AM
In this class there are my helpers. As they are static, they can be called on the class itself:
class ZHtml extends CHtml { public static function enumItem($model,$attribute) { $attr=$attribute; self::resolveName($model,$attr); preg_match('/\((.*)\)/',$model->tableSchema->columns[$attr]->dbType,$matches); foreach(explode(',', $matches[1]) as $value) { $value=str_replace("'",null,$value); $values[$value]=Yii::t('enumItem',$value); } return $values; } public static function enumDropDownList($model, $attribute, $htmlOptions) { return CHtml::activeDropDownList( $model, $attribute,ZHtml::enumItem($model, $attribute), $htmlOptions); } }
This allow you to write in the view (without any change in the model):
<?php echo CHtml::activeDropDownList( $model,'status',ZHtml::enumItem($model, 'status') ); ?>
or , more tasty:
<?php echo ZHtml::enumDropDownList( $model,'status'); ?>
#9
Posted 14 December 2010 - 09:16 AM
suppose I have ENUM('Active','Inactive','Deleted')
How to get the value I saved in my text field when I want to modify the form?
If I select 'Inactive' and save then I noticed that 'Active' allways come first during any modification in the form.
Thanks!

#10
Posted 14 December 2010 - 10:23 AM
Just write
<?php echo ZHtml::enumDropDownList( $model,'status'); ?>and all will be fine.
If it is not saved the value, maybe is a problem of safe attributes.
#11
Posted 14 December 2010 - 10:37 AM
That's a great stuff!
Thanks

#12
Posted 14 December 2010 - 02:08 PM
I was wondering what else could be wrong.. this piece of code has 2 years and alway did his work.
Happy that it helped.
#13
Posted 13 June 2011 - 11:52 PM
<?php class ZHtml extends CHtml { public static function enumItem($model,$attribute) { $values = array(); $attr=$attribute; self::resolveName($model,$attr); if( $model->tableSchema instanceof CPgsqlTableSchema ) { $sql=<<<EOD SELECT enumlabel FROM pg_enum JOIN pg_type ON pg_type.oid = pg_enum.enumtypid WHERE pg_type.typname = :table EOD; $command=Yii::app()->db->createCommand($sql); $command->bindValue(':table',$model->tableSchema->columns[$attr]->dbType); $values=$command->queryColumn(); Yii::trace( "Enum values were: ".print_r( $values, true ) ); } else { if( preg_match('/\((.*)\)/',$model->tableSchema->columns[$attr]->dbType,$matches) > 0 ) { foreach(explode(',', $matches[1]) as $value) { $value=str_replace("'",null,$value); $values[$value]=Yii::t('enumItem',$value); } } } return $values; } public static function enumDropDownList($model, $attribute, $htmlOptions = array()) { return CHtml::activeDropDownList( $model, $attribute,ZHtml::enumItem($model, $attribute), $htmlOptions); } } ?>
#14
Posted 12 September 2011 - 08:22 PM
zaccaria, on 03 December 2010 - 02:44 AM, said:
In this class there are my helpers. As they are static, they can be called on the class itself:
class ZHtml extends CHtml { public static function enumItem($model,$attribute) { $attr=$attribute; self::resolveName($model,$attr); preg_match('/\((.*)\)/',$model->tableSchema->columns[$attr]->dbType,$matches); foreach(explode(',', $matches[1]) as $value) { $value=str_replace("'",null,$value); $values[$value]=Yii::t('enumItem',$value); } return $values; } public static function enumDropDownList($model, $attribute, $htmlOptions) { return CHtml::activeDropDownList( $model, $attribute,ZHtml::enumItem($model, $attribute), $htmlOptions); } }
This allow you to write in the view (without any change in the model):
<?php echo CHtml::activeDropDownList( $model,'status',ZHtml::enumItem($model, 'status') ); ?>
or , more tasty:
<?php echo ZHtml::enumDropDownList( $model,'status'); ?>
Hey,
Thanks for the concise instructions, I had to make one modification though, as enumDropDownList takes 3 arguments, the last one being $htmlOptions, i had to add array() as an argument, eg
<?php echo ZHtml::enumDropDownList($model,'status', array()); ?>
I'm pretty new to this so if that is dangerous, let me know.
Cheers!
#15
Posted 14 September 2011 - 10:03 AM
johnsnails, on 12 September 2011 - 08:22 PM, said:
Thanks for the concise instructions, I had to make one modification though, as enumDropDownList takes 3 arguments, the last one being $htmlOptions, i had to add array() as an argument, eg
echo ZHtml::enumDropDownList( $model,'status', array());
I'm pretty new to this so if that is dangerous, let me know.
Cheers!
Generally, $htmlOptions is given a default argument $htmlOptions=array()
I changed it to the following when I used it:
public static function enumDropDownList($model, $attribute, $htmlOptions=array()) { return CHtml::activeDropDownList($model, $attribute, ZHtml::enumItem($model, $attribute), $htmlOptions); }
#17
Posted 27 January 2012 - 09:02 PM
zaccaria, on 03 December 2010 - 02:44 AM, said:
<snip />
great helper class Zaccaria. Thanks!

To set the selected item when using in update forms add this snippet, (replace 'attr' in 2 places with your model attribute):
<?php echo ZHtml::enumDropDownList($model, 'attr', array( 'options'=>array('$model->attr'=>array('selected'=>true)), )) ?>
#19
Posted 25 May 2012 - 03:37 PM
#20
Posted 25 May 2012 - 03:38 PM