Browse | Submit New Snippet | Create Package

 

Baked Enums (complete solution)

Type:
Class
Category:
Other
License:
GNU General Public License
Language:
PHP
 
Description:
This script will “fix” bake.php so that it handles enum fields in the same manner that scaffold does.

This snippet is similar to http://cakeforge.org/snippet/detail.php?type=snippet&id=112 by John Zimmerman, except that this solution automates the whole process, and it does not make another call to the database every time you need enum values.

The script is quite long, but 99% of it is from the original bake.php file. My modification are marked with:
/** begin enum modification **/
php code
/** end enum modification **/

The code consistes of 2 files:bake2.php and app_model.php

See the code comments for instructions.

Versions Of This Snippet::

Shawn Cook
Snippet ID Download Version Date Posted Author Delete
2551.0.02006-10-30 12:44Shawn Cook

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

 


Latest Snippet Version: :1.0.0

file:bake2.php
<?php
/**
 *
 * Bake2 extends class Bake to include support for enum fields in controllers.
 * !!This behavior makes bake.php consistent with scaffold.php, in respect to enum fields!!
 *
 * This script does not access the database to populate the enum values,
 * instead it uses the information in "_tableInfo" array populated by cakePHP Model
 * 
 * Compatibility:
 * This script has only been tested with:
 *		PHP 5
 *		MySQL
 *		cakePHP version 1.1.8.3544
 * Most of the code used in this file came directly from scaffold.php
 * So if you can use scaffolding in your project, then this should work as well
 *
 * Usage
 * 1. Place this file in the same directory as bake.php
 * 2. Place the accompanying file "app_model.php" in your app directory.
 * 3. Open bake.php and replace this line of code (line 104):
 * 		$pattyCake = new Bake();
 * 	  with these 2 lines of code
 * 		require_once 'bake2.php';
 *		$pattyCake = new Bake2();
 * 4. Then use bake php normally
 *
 * Hopefully someone from cakePHP will include these changes in the cakePHP distribution...
 *
 * @author		Shawn Cook (shawncook@chartermi.net)
 * @varsion 	1.0.0
 * @created		2006-10-30
 * @modified	2006-10-30
 */
 
/**
 * Bake is a command-line code generation utility for automating programmer chores.
 *
 */
class Bake2 extends bake{

/**
 * Action to create a Controller.
 *
 */
	function doController() {
		$this->hr();
		$this->stdout('Controller Bake:');
		$this->hr();
		$controllerName = '';
		$uses = array();
		$helpers = array();
		$components = array();
		$wannaUseSession = 'y';
		$wannaDoScaffolding = 'y';

		while ($controllerName == '') {
			$controllerName = $this->getInput('Controller name? Remember that Cake controller names are plural.');

			if ($controllerName == '') {
				$this->stdout('The controller name you supplied was empty. Please try again.');
			}
		}

		$inflect = & new Inflector();
		$controllerClassName = $inflect->camelize($controllerName);
		$doItInteractive = $this->getInput("Would you like bake to build your controller interactively?\nWarning: Choosing no will overwrite {$controllerClassName} controller if it exist.", array('y','n'), 'y');

		if (strtolower($doItInteractive) == 'y' || strtolower($doItInteractive) == 'yes') {
			$this->interactive = true;
			$wannaDoUses = $this->getInput("Would you like this controller to use other models besides '" . $inflect->singularize($controllerClassName) .  "'?", array('y','n'), 'n');

			if (strtolower($wannaDoUses) == 'y' || strtolower($wannaDoUses) == 'yes') {
				$usesList = $this->getInput("Please provide a comma separated list of the classnames of other models you'd like to use.\nExample: 'Author, Article, Book'");
				$usesListTrimmed = str_replace(' ', '', $usesList);
				$uses = explode(',', $usesListTrimmed);
			}
			$wannaDoHelpers = $this->getInput("Would you like this controller to use other helpers besides HtmlHelper and FormHelper?", array('y','n'), 'n');

			if (strtolower($wannaDoHelpers) == 'y' || strtolower($wannaDoHelpers) == 'yes') {
				$helpersList = $this->getInput("Please provide a comma separated list of the other helper names you'd like to use.\nExample: 'Ajax, Javascript, Time'");
				$helpersListTrimmed = str_replace(' ', '', $helpersList);
				$helpers = explode(',', $helpersListTrimmed);
			}
			$wannaDoComponents = $this->getInput("Would you like this controller to use any components?", array('y','n'), 'n');

			if (strtolower($wannaDoComponents) == 'y' || strtolower($wannaDoComponents) == 'yes') {
				$componentsList = $this->getInput("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, MyNiftyHelper'");
				$componentsListTrimmed = str_replace(' ', '', $componentsList);
				$components = explode(',', $componentsListTrimmed);
			}

			$wannaUseSession = $this->getInput("Would you like to use Sessions?", array('y','n'), 'y');

			$wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'n');

		}

		if (strtolower($wannaDoScaffolding) == 'y' || strtolower($wannaDoScaffolding) == 'yes') {
			$controllerModel = $inflect->camelize($inflect->singularize($controllerClassName));
			$this->lowCtrl = $inflect->underscore($controllerName);
			loadModels();

			if(!class_exists($controllerModel)) {
				$this->stdout('You must have a model for this class to build scaffold methods. Please try again.');
				exit;
			}
			
			$tempModel = new $controllerModel();
			$actions .= "\n";
			$actions .= "\tfunction index() {\n";
			$actions .= "\t\t\$this->{$controllerModel}->recursive = 0;\n";
			$actions .= "\t\t\$this->set('{$this->lowCtrl}', \$this->{$controllerModel}->findAll());\n";
			$actions .= "\t}\n";
			$actions .= "\n";
			$actions .= "\tfunction add() {\n";
			$actions .= "\t\tif(empty(\$this->data)) {\n";

			foreach($tempModel->hasAndBelongsToMany as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$lowerFirst = strtolower(substr($association, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $association, 1);
					$actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
					$actions .= "\t\t\t\$this->set('selected{$association}', null);\n";
				}
			}
			/** begin enum modification **/
			$enumFlds = $tempModel->_tableInfo->filter(array($this,'isEnum'));
			$enumArraySets = '';
			foreach($enumFlds as $fld){
				$lowerName =strtolower($fld['name']);
				$enumArraySets .= "\t\t\t\$this->set('".$fld['name']."Array', \$this->{$controllerModel}->getEnumList('".$fld['name']."'));\n";
			}
			$actions .= $enumArraySets;
			/** end enum modification   **/
			
			foreach($tempModel->belongsTo as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$lowerFirst = strtolower(substr($model, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $model, 1);
					$actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
				}
			}
			$actions .= "\t\t\t\$this->render();\n";
			$actions .= "\t\t} else {\n";
			$actions .= "\t\t\t\$this->cleanUpFields();\n";
			$actions .= "\t\t\tif(\$this->{$controllerModel}->save(\$this->data)) {\n";
			if (strtolower($wannaUseSession) == 'y' || strtolower($wannaUseSession) == 'yes') {
			$actions .= "\t\t\t\t\$this->Session->setFlash('The ".$inflect->humanize($controllerModel)." has been saved');\n";
			$actions .= "\t\t\t\t\$this->redirect('/{$this->lowCtrl}/index');\n";
			} else {
			$actions .= "\t\t\t\t\$this->flash('{$controllerModel} saved.', '/{$this->lowCtrl}/index');\n";
			}
			$actions .= "\t\t\t} else {\n";
			if (strtolower($wannaUseSession) == 'y' || strtolower($wannaUseSession) == 'yes') {
			$actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
			}

			foreach($tempModel->hasAndBelongsToMany as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$associationModel = new $model();
					$lowerFirst = strtolower(substr($association, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $association, 1);
					$actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
					$actions .= "\t\t\t\tif(empty(\$this->data['{$association}']['{$association}'])) { \$this->data['{$association}']['{$association}'] = null; }\n";
					$actions .= "\t\t\t\t\$this->set('selected{$association}', \$this->data['{$association}']['{$association}']);\n";
				}
			}
			/** begin enum modification **/
			$actions .= $enumArraySets;
			/** end enum modification   **/
			foreach($tempModel->belongsTo as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$lowerFirst = strtolower(substr($model, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $model, 1);
					$actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
				}
			}
			$actions .= "\t\t\t}\n";
			$actions .= "\t\t}\n";
			$actions .= "\t}\n";
			$actions .= "\n";
			$actions .= "\tfunction edit(\$id) {\n";
			$actions .= "\t\tif(empty(\$this->data)) {\n";
			$actions .= "\t\t\t\$this->data = \$this->{$controllerModel}->read(null, \$id);\n";

			foreach($tempModel->hasAndBelongsToMany as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$associationModel = new $model();
					$lowerFirst = strtolower(substr($association, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $association, 1);
					$actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
					$actions .= "\t\t\t\$this->set('selected{$association}', \$this->_selectedArray(\$this->data['{$association}'], '{$associationModel->primaryKey}'));\n";
				}
			}
			/** begin enum modification **/
			$actions .= $enumArraySets;
			/** end enum modification   **/
			foreach($tempModel->belongsTo as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$lowerFirst = strtolower(substr($model, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $model, 1);
					$actions .= "\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
				}
			}
			$actions .= "\t\t} else {\n";
			$actions .= "\t\t\t\$this->cleanUpFields();\n";
			$actions .= "\t\t\tif(\$this->{$controllerModel}->save(\$this->data)) {\n";
			if (strtolower($wannaUseSession) == 'y' || strtolower($wannaUseSession) == 'yes') {
			$actions .= "\t\t\t\t\$this->Session->setFlash('The ".$inflect->humanize($controllerModel)." has been saved');\n";
			$actions .= "\t\t\t\t\$this->redirect('/{$this->lowCtrl}/index');\n";
			} else {
			$actions .= "\t\t\t\t\$this->flash('{$controllerModel} saved.', '/{$this->lowCtrl}/index');\n";
			}
			$actions .= "\t\t\t} else {\n";
			if (strtolower($wannaUseSession) == 'y' || strtolower($wannaUseSession) == 'yes') {
			$actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
			}

			foreach($tempModel->hasAndBelongsToMany as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$associationModel = new $model();
					$lowerFirst = strtolower(substr($association, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $association, 1);
					$actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
					$actions .= "\t\t\t\tif(empty(\$this->data['{$association}']['{$association}'])) { \$this->data['{$association}']['{$association}'] = null; }\n";
					$actions .= "\t\t\t\t\$this->set('selected{$association}', \$this->data['{$association}']['{$association}']);\n";
				}
			}
			/** begin enum modification **/
			$actions .= $enumArraySets;
			/** end enum modification   **/
			foreach($tempModel->belongsTo as $association => $relation) {
				if(!empty($relation['className'])) {
					$model = $relation['className'];
					$lowerFirst = strtolower(substr($model, 0, 1));
					$lowerName = preg_replace('/\\w/', $lowerFirst, $model, 1);
					$actions .= "\t\t\t\t\$this->set('{$lowerName}Array', \$this->{$controllerModel}->{$model}->generateList());\n";
				}
			}
			$actions .= "\t\t\t}\n";
			$actions .= "\t\t}\n";
			$actions .= "\t}\n";
			$actions .= "\n";
			$actions .= "\tfunction view(\$id) {\n";
			$actions .= "\t\t\$this->set('".$inflect->singularize($this->lowCtrl)."', \$this->{$controllerModel}->read(null, \$id));\n";
			$actions .= "\t}\n";
			$actions .= "\n";
			$actions .= "\tfunction delete(\$id) {\n";
			$actions .= "\t\tif(\$this->{$controllerModel}->del(\$id)) {\n";
			if (strtolower($wannaUseSession) == 'y' || strtolower($wannaUseSession) == 'yes') {
			$actions .= "\t\t\t\$this->Session->setFlash('The ".$inflect->humanize($controllerModel)." deleted: id '.\$id.'');\n";
			$actions .= "\t\t\t\$this->redirect('/{$this->lowCtrl}/index');\n";
			} else {
			$actions .= "\t\t\t\$this->flash('{$controllerModel} deleted: id '.\$id.'.', '/{$this->lowCtrl}/index');\n";
			}
			$actions .= "\t\t}\n";
			$actions .= "\t}\n";
			$actions .= "\n";
			if(!empty($tempModel->hasAndBelongsToMany)) {
			$actions .= "\tfunction _selectedArray(\$data, \$key) {\n";
			$actions .= "\t\t\$array = array();\n";
			$actions .= "\t\tif(!empty(\$data)) {\n";
			$actions .= "\t\t\tforeach(\$data as \$var) {\n";
			$actions .= "\t\t\t\t\$array[\$var[\$key]] = \$var[\$key];\n";
			$actions .= "\t\t\t}\n";
			$actions .= "\t\t}\n";
			$actions .= "\t\treturn \$array;\n";
			$actions .= "\t}\n";
			$actions .= "\n";
			}
		}

		if($this->interactive === true) {
			$this->stdout('');
			$this->hr();
			$this->stdout('The following controller will be created:');
			$this->hr();
			$this->stdout("Controller Name:	$controllerName");

			if(count($uses)) {
				$this->stdout("Uses:            ", false);

				foreach($uses as $use) {
					if ($use != $uses[count($uses) - 1]) {
						$this->stdout(ucfirst($use) . ", ", false);
					} else {
						$this->stdout(ucfirst($use));
					}
				}
			}

			if(count($helpers)) {
				$this->stdout("Helpers:			", false);

				foreach($helpers as $help) {
					if ($help != $helpers[count($helpers) - 1]) {
						$this->stdout(ucfirst($help) . ", ", false);
					} else {
						$this->stdout(ucfirst($help));
					}
				}
			}

			if(count($components)) {
				$this->stdout("Components:            ", false);

				foreach($components as $comp) {
					if ($comp != $components[count($components) - 1]) {
						$this->stdout(ucfirst($comp) . ", ", false);
					} else {
						$this->stdout(ucfirst($comp));
					}
				}
			}
			$this->hr();
			$looksGood = $this->getInput('Look okay?', array('y','n'), 'y');

			if (strtolower($looksGood) == 'y' || strtolower($looksGood) == 'yes') {
				$this->bakeController($controllerClassName, $uses, $helpers, $components, $actions);

				if ($this->doUnitTest()) {
					$this->bakeUnitTest('controller', $controllerClassName);
				}
			} else {
				$this->stdout('Bake Aborted.');
			}
		} else {
			$this->bakeController($controllerClassName, $uses, $helpers, $components, $actions);
			exit();
		}
	}

	/**
	 * Filter function to find enum fields in _tableInfo
	 *
	 * @param unknown
	 * @return bool
	 */
	function isEnum($val){
		if(is_array($val) && isset($val['type']) && stristr($val['type'],'enum(') )
			return true;
		else
			return false;
	}
} //END CLASS bake2
?>
file:app_model.php
<?php
/**
 * Application model for Cake.
 *
 * This file is application-wide model file. You can put all
 * application-wide model-related methods here.
 *
 * PHP versions 4 and 5
 */
 
/**
 * Application model for Cake.
 *
 * This is a placeholder class.
 * Create the same file in app/app_model.php
 * Add your application-wide methods to the class, your models will inherit them.
 *
 * @package		cake
 * @subpackage	cake.cake
 */
class AppModel extends Model{


	/**
	* Retrieve a list of enum values for a specific field
	*
	* @param string
	* @return array
	*/
	function getEnumList($fldName){
		$fldInfoArray = $this->_tableInfo->findIn( 'name' , $fldName );
		foreach($fldInfoArray as $fldInfo)
			break;
			
		$lParenPos = strpos($fldInfo['type'], '(');
		$rParenPos = strpos($fldInfo['type'], ')');
	
		if (false != $lParenPos) {
			$type = substr($fldInfo['type'], 0, $lParenPos);
			$fieldLength = substr($fldInfo['type'], $lParenPos + 1, $rParenPos - $lParenPos - 1);
			$enumValues = split(',', $fieldLength);
			
			foreach($enumValues as $key => $enum) {
				$enum = trim($enum, "'");
				$enums[$enum] = $enum;
			}
		}else{
			$enums = array();
		}
		return $enums;
	}
}
?>
		

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..