Browse | Submit New Snippet | Create Package

 

Baked ENUMs

Type:
Function
Category:
Database Manipulation
License:
MIT/X Consortium License
Language:
PHP
 
Description:
This is a preliminary solution to solve the problem of baking your Models's, View's and Controller's with enum keys in the database.

It is not completely automatic and I can only tell you that it works with PHP5 and MySQL5.

As PHPNut stated in trac, the enum columns are too different across databases to make this standard (at least for now).

So if you are using something other than MySQL you will have to change the code in app_model.php accordingly.

Versions Of This Snippet::

Scott Bentley
Snippet ID Download Version Date Posted Author Delete
3580.1.52007-11-16 19:23Scott Bentley
Changes since last version::
I added some logic to get the default value from the database and move that selection to the top of the list. I would have liked to find a way to actually force the option as 'selected' in HTML rather than re-ordering the items, but I don't see any way to do that except with custom code in your model/controller/view.
2580.1.42006-11-03 14:21Ruben Barkow
Changes since last version::
i added the fix for bake.php
2460.1.32006-09-27 01:16John Zimmerman
Changes since last version::
Between the last couple version functionality for MySQL 5 was broken when support for MySQL 3 was added.

This version has been tested on MySQL 4 and 5 successfully.

Please do not update this snippet for MySQL 3 as Cake does not support v3 anyhow. If you need MySQL 3 support please create a new snippet.

Other bug fixes / enhancements are greatly appreciated.
2420.1.22006-09-15 23:38John Zimmerman
Changes since last version::
Fixed a bug with getting a table name that has underscores. Problem found by jpittendreigh@gmail.com, solution suggested by nate.
2100.1.12006-08-15 19:28Chris Shaffer
Changes since last version::
Modified the getEnumValues function to be backwards compatible for MySQL 3.
1850.12006-07-21 22:24John Zimmerman

Download a raw-text version of this code by clicking on "Download Version"

 


Latest Snippet Version: :0.1.5

<?php
class AppModel extends Model
{

    /**
     * Get Enum Values
     * Snippet v0.1.3
     * http://cakeforge.org/snippet/detail.php?type=snippet&id=112
     *
     * Gets the enum values for MySQL 4 and 5 to use in selectTag()
     */
    function getEnumValues($columnName=null, $respectDefault=false)
    {
        if ($columnName==null) { return array(); } //no field specified


        //Get the name of the table
        $db =& ConnectionManager::getDataSource($this->useDbConfig);
        $tableName = $db->fullTableName($this, false);


        //Get the values for the specified column (database and version specific, needs testing)
        $result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");

        //figure out where in the result our Types are (this varies between mysql versions)
        $types = null;
        if     ( isset( $result[0]['COLUMNS']['Type'] ) ) { $types = $result[0]['COLUMNS']['Type']; $default = $result[0]['COLUMNS']['Default']; } //MySQL 5
        elseif ( isset( $result[0][0]['Type'] ) )         { $types = $result[0][0]['Type']; $default = $result[0][0]['Default']; } //MySQL 4
        else   { return array(); } //types return not accounted for

        //Get the values
        $values = explode("','", preg_replace("/(enum)\('(.+?)'\)/","\\2", $types) );

        if($respectDefault){
                $assoc_values = array("$default"=>Inflector::humanize($default));
                foreach ( $values as $value ) {
                        if($value==$default){ continue; }
                        $assoc_values[$value] = Inflector::humanize($value);
                }
        }
        else{
                $assoc_values = array();
                foreach ( $values as $value ) {
                        $assoc_values[$value] = Inflector::humanize($value);
                }
        }

        return $assoc_values;

    } //end getEnumValues
}
?>

---------------------------------------------------------------------------------

<?php
/**
 * example code for your controller
 */
class ExamplesController extends AppController
{
    var $name = "Examples";

    function add() {

        /*
         * This is the addition to this action.  I have an enum column called
         * 'active' which I want the values for.  Bake already puts a variable
         * in the view called 'enumcolArray' to hold the values.  This is 
         * just setting the values for that for that variable using the code
         * we defined in app_model.php above.
         */
        $this->set('activeArray',    $this->Example->getEnumValues('active'));

        if(empty($this->data)) {
            $this->set('examples', null);
        } else {
            $this->cleanUpFields();
            if($this->Example->save($this->data)) {
                if(is_object($this->Session)) {
                    $this->Session->setFlash('The Example has been saved');
                    $this->redirect('/examples/index');
                } else {
                    $this->flash('Example saved.', '/examples/index');
                }
            } else {
                if(is_object($this->Session)) {
                    $this->Session->setFlash('Please correct errors below.');
                }
                $data = $this->data;
                $this->set('examples', $data);
            }
        }
    }

}

?>
---------------------------------------------------------------------------------
to fix the bake-script:

[---OPEN---]
cake/scripts/bake.php:
[---FIND---]
		/* ADD ACTION */
		$actions .= "\tfunction {$admin}add() {\n";
		
[---ADD AFTER---]
		foreach($modelObj->_tableInfo->value as $field){
			if (stristr($field['type'],"enum(")) $actions .= "\t\t\$this->set('".$this->__pluralName($field['name'])."', \$this->{$currentModelName}->getEnumValues('".$field['name']."'));\n";
		}
[---DONE---]
		

Submit a new version

You can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..