controller.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: controller_8php-source.html 675 2008-12-26 00:27:14Z gwoo $ */
00003 /**
00004  * Base controller class.
00005  *
00006  * PHP versions 4 and 5
00007  *
00008  * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
00009  * Copyright 2005-2008, Cake Software Foundation, Inc.
00010  *                              1785 E. Sahara Avenue, Suite 490-204
00011  *                              Las Vegas, Nevada 89104
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00018  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package         cake
00020  * @subpackage      cake.cake.libs.controller
00021  * @since           CakePHP(tm) v 0.2.9
00022  * @version         $Revision: 675 $
00023  * @modifiedby      $LastChangedBy: gwoo $
00024  * @lastmodified    $Date: 2008-12-25 18:27:14 -0600 (Thu, 25 Dec 2008) $
00025  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Include files
00029  */
00030     uses(DS . 'controller' . DS . 'component', DS . 'view' . DS . 'view');
00031 /**
00032  * Controller
00033  *
00034  * Application controller (controllers are where you put all the actual code)
00035  * Provides basic functionality, such as rendering views (aka displaying templates).
00036  * Automatically selects model name from on singularized object class name
00037  * and creates the model object if proper class exists.
00038  *
00039  * @package     cake
00040  * @subpackage  cake.cake.libs.controller
00041  *
00042  */
00043 class Controller extends Object{
00044 /**
00045  * Name of the controller.
00046  *
00047  * @var string
00048  * @access public
00049  */
00050     var $name = null;
00051 /**
00052  * Stores the current URL (for links etc.)
00053  *
00054  * @var string
00055  * @access public
00056  */
00057     var $here = null;
00058 /**
00059  * The webroot of the application
00060  *
00061  * @var string
00062  * @access public
00063  */
00064     var $webroot = null;
00065 /**
00066  * Action to be performed.
00067  *
00068  * @var string
00069  * @access public
00070  */
00071     var $action = null;
00072 /**
00073  * An array of names of models the particular controller wants to use.
00074  *
00075  * @var mixed A single name as a string or a list of names as an array.
00076  * @access protected
00077  */
00078     var $uses = false;
00079 /**
00080  * An array of names of built-in helpers to include.
00081  *
00082  * @var mixed A single name as a string or a list of names as an array.
00083  * @access protected
00084  */
00085     var $helpers = array('Html');
00086 /**
00087  * Parameters received in the current request, i.e. GET and POST data
00088  *
00089  * @var array
00090  * @access public
00091  */
00092     var $params = array();
00093 /**
00094  * POST'ed model data
00095  *
00096  * @var array
00097  * @access public
00098  */
00099     var $data = array();
00100 /**
00101  * Directory where controllers views are stored
00102  * Normaly this is automatically set
00103  *
00104  * @var string
00105  * @access public
00106  */
00107     var $viewPath = null;
00108 /**
00109  * Variables for the view
00110  *
00111  * @var array
00112  * @access public
00113  */
00114     var $viewVars = array();
00115 /**
00116  * Web page title
00117  *
00118  * @var boolean
00119  * @access public
00120  */
00121     var $pageTitle = false;
00122 /**
00123  * An array of model objects.
00124  *
00125  * @var array Array of model objects.
00126  * @access public
00127  */
00128     var $modelNames = array();
00129 /**
00130  * Base url path
00131  *
00132  * @var string
00133  * @access public
00134  */
00135     var $base = null;
00136 /**
00137  * Layout file to use (see /app/views/layouts/default.thtml)
00138  *
00139  * @var string
00140  * @access public
00141  */
00142     var $layout = 'default';
00143 /**
00144  * Automatically render the view (the dispatcher checks for this variable before running render())
00145  *
00146  * @var boolean
00147  * @access public
00148  */
00149     var $autoRender = true;
00150 /**
00151  * Automatically render the layout
00152  *
00153  * @var boolean
00154  * @access public
00155  */
00156     var $autoLayout = true;
00157 /**
00158  * Array of components a controller will use
00159  *
00160  * @var array
00161  * @access public
00162  */
00163     var $components = array();
00164 /**
00165  * The name of the View class a controller sends output to
00166  *
00167  * @var string
00168  * @access public
00169  */
00170     var $view = 'View';
00171 /**
00172  * File extension for view templates. Defaults to Cake's conventional ".thtml".
00173  *
00174  * @var string
00175  * @access public
00176  */
00177     var $ext = '.thtml';
00178 /**
00179  * Instance of $view class create by a controller
00180  *
00181  * @var object
00182  * @access private
00183  */
00184     var $__viewClass = null;
00185 /**
00186  * The output of the requested action.  Contains either a variable
00187  * returned from the action, or the data of the rendered view;
00188  * You can use this var in Child classes afterFilter() to alter output.
00189  *
00190  * @var string
00191  * @access public
00192  */
00193     var $output = null;
00194 /**
00195  * Automatically set to the name of a plugin.
00196  *
00197  * @var string
00198  * @access public
00199  */
00200     var $plugin = null;
00201 /**
00202  * Used to set methods a controller will allow the View to cache
00203  *
00204  * @var mixed
00205  * @access public
00206  */
00207     var $cacheAction = false;
00208 /**
00209  * Used to create cached instances of models a controller uses.
00210  * When set to true all models related to the controller will be cached,
00211  * this can increase performance in many cases
00212  *
00213  * @var boolean
00214  * @access public
00215  */
00216     var $persistModel = false;
00217 /**
00218  * Replaced with Controller::beforeFilter();
00219  *
00220  * @deprecated will not be avialable after 1.1.x.x
00221  */
00222     var $beforeFilter = null;
00223 /**
00224  * Replaced with Router::parseExtensions();
00225  *
00226  * @deprecated will not be avialable after 1.1.x.x
00227  */
00228     var $webservices = null;
00229 /**
00230  * Constructor.
00231  */
00232     function __construct() {
00233         if ($this->name === null) {
00234             $r = null;
00235 
00236             if (!preg_match('/(.*)Controller/i', get_class($this), $r)) {
00237                 die ("Controller::__construct() : Can't get or parse my own class name, exiting.");
00238             }
00239             $this->name = $r[1];
00240         }
00241 
00242         if ($this->viewPath == null) {
00243             $this->viewPath = Inflector::underscore($this->name);
00244         }
00245 
00246         $this->modelClass = Inflector::classify($this->name);
00247         $this->modelKey = Inflector::underscore($this->modelClass);
00248 
00249         if (is_subclass_of($this, 'AppController')) {
00250             $appVars = get_class_vars('AppController');
00251             $uses = $appVars['uses'];
00252             $merge = array('components', 'helpers');
00253 
00254             if ($uses == $this->uses && !empty($this->uses)) {
00255                 array_unshift($this->uses, $this->modelClass);
00256             } elseif ($this->uses !== null || $this->uses !== false) {
00257                 $merge[] = 'uses';
00258             }
00259 
00260             foreach ($merge as $var) {
00261                 if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) {
00262                     $this->{$var} = array_merge($this->{$var}, array_diff($appVars[$var], $this->{$var}));
00263                 }
00264             }
00265         }
00266         parent::__construct();
00267     }
00268 
00269     function _initComponents() {
00270         $component = new Component();
00271         $component->init($this);
00272     }
00273 /**
00274  * Loads and instantiates models required by this controller.
00275  * If Controller::persistModel; is true, controller will create cached model instances on first request,
00276  * additional request will used cached models
00277  *
00278  * @return mixed true when single model found and instance created error returned if models not found.
00279  * @access public
00280  */
00281     function constructClasses() {
00282         if ($this->uses === null || ($this->uses === array())) {
00283             return false;
00284         }
00285         if (empty($this->passedArgs) || !isset($this->passedArgs['0'])) {
00286             $id = false;
00287         } else {
00288             $id = $this->passedArgs['0'];
00289         }
00290         $cached = false;
00291         $object = null;
00292 
00293         if ($this->persistModel === true) {
00294             uses('neat_array');
00295         }
00296         if ($this->uses === false) {
00297             if (!class_exists($this->modelClass)) {
00298                 loadModel($this->modelClass);
00299             }
00300         }
00301 
00302         if (class_exists($this->modelClass) && ($this->uses === false)) {
00303             if ($this->persistModel === true) {
00304                 $cached = $this->_persist($this->modelClass, null, $object);
00305             }
00306 
00307             if (($cached === false)) {
00308                 $model =& new $this->modelClass($id);
00309                 $this->modelNames[] = $this->modelClass;
00310                 $this->{$this->modelClass} =& $model;
00311 
00312                 if ($this->persistModel === true) {
00313                     $this->_persist($this->modelClass, true, $model);
00314                     $registry = ClassRegistry::getInstance();
00315                     $this->_persist($this->modelClass . 'registry', true, $registry->_objects, 'registry');
00316                 }
00317             } else {
00318                 $this->_persist($this->modelClass . 'registry', true, $object, 'registry');
00319                 $this->_persist($this->modelClass, true, $object);
00320                 $this->modelNames[] = $this->modelClass;
00321             }
00322             return true;
00323         } elseif ($this->uses === false) {
00324             return $this->cakeError('missingModel', array(array('className' => $this->modelClass, 'webroot' => '', 'base' => $this->base)));
00325         }
00326 
00327         if ($this->uses) {
00328             $uses = is_array($this->uses) ? $this->uses : array($this->uses);
00329             $this->modelClass = $uses[0];
00330 
00331             foreach ($uses as $modelClass) {
00332                 $id = false;
00333                 $cached = false;
00334                 $object = null;
00335                 $modelKey = Inflector::underscore($modelClass);
00336 
00337                 if (!class_exists($modelClass)) {
00338                     loadModel($modelClass);
00339                 }
00340 
00341                 if (class_exists($modelClass)) {
00342                     if ($this->persistModel === true) {
00343                         $cached = $this->_persist($modelClass, null, $object);
00344                     }
00345 
00346                     if (($cached === false)) {
00347                         $model =& new $modelClass($id);
00348                         $this->modelNames[] = $modelClass;
00349                         $this->{$modelClass} =& $model;
00350 
00351                         if ($this->persistModel === true) {
00352                             $this->_persist($modelClass, true, $model);
00353                             $registry = ClassRegistry::getInstance();
00354                             $this->_persist($modelClass . 'registry', true, $registry->_objects, 'registry');
00355                         }
00356                     } else {
00357                         $this->_persist($modelClass . 'registry', true, $object, 'registry');
00358                         $this->_persist($modelClass, true, $object);
00359                         $this->modelNames[] = $modelClass;
00360                     }
00361                 } else {
00362                     return $this->cakeError('missingModel', array(array('className' => $modelClass, 'webroot' => '', 'base' => $this->base)));
00363                 }
00364             }
00365             return true;
00366         }
00367     }
00368 /**
00369  * Redirects to given $url, after turning off $this->autoRender.
00370  * Please notice that the script execution is not stopped after the redirect.
00371  *
00372  * @param string $url
00373  * @param integer $status
00374  * @access public
00375  */
00376     function redirect($url, $status = null) {
00377         $this->autoRender = false;
00378         $pos = strpos($url, '://');
00379         $base = strip_plugin($this->base, $this->plugin);
00380         if ($pos === false) {
00381             if (strpos($url, '/') !== 0) {
00382                 $url = '/' . $url;
00383             }
00384             $url = FULL_BASE_URL . $base . $url;
00385         }
00386 
00387         if (function_exists('session_write_close')) {
00388             session_write_close();
00389         }
00390 
00391         if (!empty($status)) {
00392             $codes = array(
00393                 100 => "HTTP/1.1 100 Continue",
00394                 101 => "HTTP/1.1 101 Switching Protocols",
00395                 200 => "HTTP/1.1 200 OK",
00396                 201 => "HTTP/1.1 201 Created",
00397                 202 => "HTTP/1.1 202 Accepted",
00398                 203 => "HTTP/1.1 203 Non-Authoritative Information",
00399                 204 => "HTTP/1.1 204 No Content",
00400                 205 => "HTTP/1.1 205 Reset Content",
00401                 206 => "HTTP/1.1 206 Partial Content",
00402                 300 => "HTTP/1.1 300 Multiple Choices",
00403                 301 => "HTTP/1.1 301 Moved Permanently",
00404                 302 => "HTTP/1.1 302 Found",
00405                 303 => "HTTP/1.1 303 See Other",
00406                 304 => "HTTP/1.1 304 Not Modified",
00407                 305 => "HTTP/1.1 305 Use Proxy",
00408                 307 => "HTTP/1.1 307 Temporary Redirect",
00409                 400 => "HTTP/1.1 400 Bad Request",
00410                 401 => "HTTP/1.1 401 Unauthorized",
00411                 402 => "HTTP/1.1 402 Payment Required",
00412                 403 => "HTTP/1.1 403 Forbidden",
00413                 404 => "HTTP/1.1 404 Not Found",
00414                 405 => "HTTP/1.1 405 Method Not Allowed",
00415                 406 => "HTTP/1.1 406 Not Acceptable",
00416                 407 => "HTTP/1.1 407 Proxy Authentication Required",
00417                 408 => "HTTP/1.1 408 Request Time-out",
00418                 409 => "HTTP/1.1 409 Conflict",
00419                 410 => "HTTP/1.1 410 Gone",
00420                 411 => "HTTP/1.1 411 Length Required",
00421                 412 => "HTTP/1.1 412 Precondition Failed",
00422                 413 => "HTTP/1.1 413 Request Entity Too Large",
00423                 414 => "HTTP/1.1 414 Request-URI Too Large",
00424                 415 => "HTTP/1.1 415 Unsupported Media Type",
00425                 416 => "HTTP/1.1 416 Requested range not satisfiable",
00426                 417 => "HTTP/1.1 417 Expectation Failed",
00427                 500 => "HTTP/1.1 500 Internal Server Error",
00428                 501 => "HTTP/1.1 501 Not Implemented",
00429                 502 => "HTTP/1.1 502 Bad Gateway",
00430                 503 => "HTTP/1.1 503 Service Unavailable",
00431                 504 => "HTTP/1.1 504 Gateway Time-out"
00432             );
00433             if (is_string($status)) {
00434                 $codes = array_combine(array_values($codes), array_keys($codes));
00435             }
00436             if (isset($codes[$status])) {
00437                 $code = ife(is_numeric($status), $status, $codes[$status]);
00438                 $msg  = ife(is_string($status),  $status, $codes[$status]);
00439                 $status = "HTTP/1.1 {$code} {$msg}";
00440             } else {
00441                 $status = null;
00442             }
00443         }
00444         if (!empty($status)) {
00445             header($status);
00446         }
00447         header('Location: ' . $url);
00448         if (!empty($status) && ($status >= 300 && $status < 400)) {
00449             header($status);
00450         }
00451     }
00452 /**
00453  * Saves a variable to use inside a template.
00454  *
00455  * @param mixed $one A string or an array of data.
00456  * @param mixed $two Value in case $one is a string (which then works as the key). Unused if $one is an associative array, otherwise serves as the values to $one's keys.
00457  * @return mixed string or array of variables set
00458  * @access public
00459  */
00460     function set($one, $two = null) {
00461         if (is_array($one)) {
00462             if (is_array($two)) {
00463                 return $this->_setArray(array_combine($one, $two));
00464             } else {
00465                 return $this->_setArray($one);
00466             }
00467         } else {
00468             return $this->_setArray(array($one => $two));
00469         }
00470     }
00471 /**
00472  * Internally redirects one action to another
00473  *
00474  * @param string $action The new action to be redirected to
00475  * @param mixed  Any other parameters passed to this method will be passed as
00476  *               parameters to the new action.
00477  * @access public
00478  */
00479     function setAction($action) {
00480         $this->action = $action;
00481         $args = func_get_args();
00482         unset($args[0]);
00483         call_user_func_array(array(&$this, $action), $args);
00484     }
00485 /**
00486  * Returns number of errors in a submitted FORM.
00487  *
00488  * @return int Number of errors
00489  * @access public
00490  */
00491     function validate() {
00492         $args = func_get_args();
00493         $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
00494 
00495         if ($errors === false) {
00496             return 0;
00497         }
00498         return count($errors);
00499     }
00500 /**
00501  * Validates a FORM according to the rules set up in the Model.
00502  *
00503  * @return int Number of errors
00504  * @access public
00505  */
00506     function validateErrors() {
00507         $objects = func_get_args();
00508         if (!count($objects)) {
00509             return false;
00510         }
00511 
00512         $errors = array();
00513         foreach ($objects as $object) {
00514             $errors = array_merge($errors, $this->{$object->name}->invalidFields($object->data));
00515         }
00516         return $this->validationErrors = (count($errors) ? $errors : false);
00517     }
00518 /**
00519  * Gets an instance of the view object and prepares it for rendering the output, then
00520  * asks the view to actualy do the job.
00521  *
00522  * @param string $action
00523  * @param string $layout
00524  * @param string $file
00525  * @return controllers related views
00526  * @access public
00527  */
00528     function render($action = null, $layout = null, $file = null) {
00529         $viewClass = $this->view;
00530         if ($this->view != 'View') {
00531             $viewClass = $this->view . 'View';
00532             loadView($this->view);
00533         }
00534         $this->beforeRender();
00535         $this->__viewClass =& new $viewClass($this);
00536 
00537         if (!empty($this->modelNames)) {
00538             $models = array();
00539             foreach ($this->modelNames as $currentModel) {
00540                 if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model')) {
00541                     $models[] = Inflector::underscore($currentModel);
00542                 }
00543                 if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model') && !empty($this->$currentModel->validationErrors)) {
00544                     $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $this->$currentModel->validationErrors;
00545                 }
00546             }
00547             $models = array_diff(ClassRegistry::keys(), $models);
00548             foreach ($models as $currentModel) {
00549                 if (ClassRegistry::isKeySet($currentModel)) {
00550                     $currentObject =& ClassRegistry::getObject($currentModel);
00551                     if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
00552                         $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors;
00553                     }
00554                 }
00555             }
00556         }
00557         $this->autoRender = false;
00558         return $this->__viewClass->render($action, $layout, $file);
00559     }
00560 /**
00561  * Gets the referring URL of this request
00562  *
00563  * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers
00564  * @param boolean $local If true, restrict referring URLs to local server
00565  * @access public
00566  */
00567     function referer($default = null, $local = false) {
00568         $ref = env('HTTP_REFERER');
00569         $base = FULL_BASE_URL . $this->webroot;
00570 
00571         if ($ref != null && (defined(FULL_BASE_URL) || FULL_BASE_URL)) {
00572             if (strpos($ref, $base) === 0) {
00573                 return substr($ref, strlen($base) - 1);
00574             } elseif (!$local) {
00575                 return $ref;
00576             }
00577         }
00578 
00579         if ($default != null) {
00580             return $default;
00581         } else {
00582             return '/';
00583         }
00584     }
00585 /**
00586  * Sets data for this view. Will set title if the key "title" is in given $data array.
00587  *
00588  * @param array $data Array of
00589  * @access protected
00590  */
00591     function _setArray($data) {
00592         foreach ($data as $name => $value) {
00593             if ($name == 'title') {
00594                 $this->_setTitle($value);
00595             } else {
00596                 $this->viewVars[$name] = $value;
00597             }
00598         }
00599     }
00600 /**
00601  * Set the title element of the page.
00602  *
00603  * @param string $pageTitle Text for the title
00604  * @access private
00605  */
00606     function _setTitle($pageTitle) {
00607         $this->pageTitle = $pageTitle;
00608     }
00609 /**
00610  * Shows a message to the user $time seconds, then redirects to $url if DEBUG == 0. If DEBUG > 0, warnings and SQL output may halt redirection.
00611  * Uses flash.thtml as a layout for the messages
00612  *
00613  * @param string $message Message to display to the user
00614  * @param string $url Relative URL to redirect to after the time expires
00615  * @param int $time seconds to show the message
00616  * @access public
00617  */
00618     function flash($message, $url, $pause = 1) {
00619         $this->autoRender = false;
00620         $this->autoLayout = false;
00621         $this->set('url', $this->base . $url);
00622         $this->set('message', $message);
00623         $this->set('pause', $pause);
00624         $this->set('page_title', $message);
00625 
00626         if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
00627             $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
00628         } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
00629         }
00630         $this->render(null, false, $flash);
00631     }
00632 /**
00633  * Replaced with Controller::flash();
00634  * @deprecated will not be avialable after 1.1.x.x
00635  */
00636     function flashOut($message, $url, $pause = 1) {
00637         trigger_error('(Controller::flashOut()) Deprecated: Use Controller::flash() instead', E_USER_WARNING);
00638         $this->autoRender = false;
00639         $this->autoLayout = false;
00640         $this->set('url', $url);
00641         $this->set('message', $message);
00642         $this->set('pause', $pause);
00643         $this->set('page_title', $message);
00644 
00645         if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
00646             $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
00647         } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
00648         }
00649         $this->render(null, false, $flash);
00650     }
00651 /**
00652  * This function creates a $fieldNames array for the view to use.
00653  *
00654  * @param array $data
00655  * @param boolean $doCreateOptions
00656  * @return field name arrays for the view
00657  * @access public
00658  */
00659     function generateFieldNames($data = null, $doCreateOptions = true) {
00660         $fieldNames = array();
00661         $model = $this->modelClass;
00662         $modelKey = $this->modelKey;
00663         $table = $this->{$model}->table;
00664         $objRegistryModel =& ClassRegistry::getObject($modelKey);
00665 
00666         foreach ($objRegistryModel->_tableInfo->value as $tabl) {
00667             if ($objRegistryModel->isForeignKey($tabl['name'])) {
00668                 if (false !== strpos($tabl['name'], "_id")) {
00669                     $niceName = substr($tabl['name'], 0, strpos($tabl['name'], "_id" ));
00670                 } else {
00671                     $niceName = $niceName = $tabl['name'];
00672                 }
00673                 $fkNames = $this->{$model}->keyToTable[$tabl['name']];
00674                 $fieldNames[$tabl['name']]['table'] = $fkNames[0];
00675                 $fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($niceName);
00676                 $fieldNames[$tabl['name']]['model'] = $fkNames[1];
00677                 $fieldNames[$tabl['name']]['modelKey'] = $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']];
00678                 $fieldNames[$tabl['name']]['controller'] = Inflector::pluralize($this->{$model}->tableToModel[$fkNames[0]]);
00679                 $fieldNames[$tabl['name']]['foreignKey'] = true;
00680 
00681             } elseif ('created' != $tabl['name'] && 'updated' != $tabl['name']) {
00682                 $fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($tabl['name']);
00683             } elseif ('created' == $tabl['name']) {
00684                 $fieldNames[$tabl['name']]['prompt'] = 'Created';
00685             } elseif ('updated' == $tabl['name']) {
00686                 $fieldNames[$tabl['name']]['prompt'] = 'Modified';
00687             }
00688             $fieldNames[$tabl['name']]['tagName'] = $model . '/' . $tabl['name'];
00689             $validationFields = $objRegistryModel->validate;
00690 
00691             if (isset($validationFields[$tabl['name']])) {
00692                 if (VALID_NOT_EMPTY == $validationFields[$tabl['name']]) {
00693                     $fieldNames[$tabl['name']]['required'] = true;
00694                     $fieldNames[$tabl['name']]['errorMsg'] = "Required Field";
00695                 }
00696             }
00697             $lParenPos = strpos($tabl['type'], '(');
00698             $rParenPos = strpos($tabl['type'], ')');
00699 
00700             if (false != $lParenPos) {
00701                 $type = substr($tabl['type'], 0, $lParenPos);
00702                 $fieldLength = substr($tabl['type'], $lParenPos + 1, $rParenPos - $lParenPos - 1);
00703             } else {
00704                 $type = $tabl['type'];
00705             }
00706 
00707             switch($type) {
00708                 case "text":
00709                     $fieldNames[$tabl['name']]['type'] = 'area';
00710                 break;
00711                 case "string":
00712                     if (isset($fieldNames[$tabl['name']]['foreignKey'])) {
00713                         $fieldNames[$tabl['name']]['type'] = 'select';
00714                         $fieldNames[$tabl['name']]['options'] = array();
00715                         $otherModel =& ClassRegistry::getObject(Inflector::underscore($fieldNames[$tabl['name']]['modelKey']));
00716 
00717                         if (is_object($otherModel)) {
00718                             if ($doCreateOptions) {
00719                                 $otherDisplayField = $otherModel->getDisplayField();
00720                                 $otherModel->recursive = 0;
00721                                 $rec = $otherModel->findAll();
00722 
00723                                 foreach ($rec as $pass) {
00724                                     foreach ($pass as $key => $value) {
00725                                         if ($key == $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']] && isset($value[$otherModel->primaryKey]) && isset($value[$otherDisplayField])) {
00726                                                 $fieldNames[$tabl['name']]['options'][$value[$otherModel->primaryKey]] = $value[$otherDisplayField];
00727                                         }
00728                                     }
00729                                 }
00730                             }
00731                             $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
00732                         }
00733                     } else {
00734                         $fieldNames[$tabl['name']]['type'] = 'input';
00735                     }
00736                 break;
00737                 case "boolean":
00738                         $fieldNames[$tabl['name']]['type'] = 'checkbox';
00739                 break;
00740                 case "integer":
00741                 case "float":
00742                     if (strcmp($tabl['name'], $this->$model->primaryKey) == 0) {
00743                         $fieldNames[$tabl['name']]['type'] = 'hidden';
00744                     } elseif (isset($fieldNames[$tabl['name']]['foreignKey'])) {
00745                         $fieldNames[$tabl['name']]['type'] = 'select';
00746                         $fieldNames[$tabl['name']]['options'] = array();
00747                         $otherModel =& ClassRegistry::getObject(Inflector::underscore($fieldNames[$tabl['name']]['modelKey']));
00748 
00749                         if (is_object($otherModel)) {
00750                             if ($doCreateOptions) {
00751                                 $otherDisplayField = $otherModel->getDisplayField();
00752                                 $otherModel->recursive = 0;
00753                                 $rec = $otherModel->findAll();
00754 
00755                                 foreach ($rec as $pass) {
00756                                     foreach ($pass as $key => $value) {
00757                                         if ($key == $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']] && isset($value[$otherModel->primaryKey]) && isset($value[$otherDisplayField])) {
00758                                             $fieldNames[$tabl['name']]['options'][$value[$otherModel->primaryKey]] = $value[$otherDisplayField];
00759                                         }
00760                                     }
00761                                 }
00762                             }
00763                             $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
00764                         }
00765                     } else {
00766                         $fieldNames[$tabl['name']]['type'] = 'input';
00767                     }
00768                 break;
00769                 case "enum":
00770                     $fieldNames[$tabl['name']]['type'] = 'select';
00771                     $fieldNames[$tabl['name']]['options'] = array();
00772                     $enumValues = split(',', $fieldLength);
00773 
00774                     foreach ($enumValues as $enum) {
00775                         $enum = trim($enum, "'");
00776                         $fieldNames[$tabl['name']]['options'][$enum] = $enum;
00777                     }
00778 
00779                     $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
00780                 break;
00781                 case "date":
00782                 case "datetime":
00783                 case "time":
00784                 case "year":
00785                     if (0 != strncmp("created", $tabl['name'], 7) && 0 != strncmp("modified", $tabl['name'], 8)) {
00786                         $fieldNames[$tabl['name']]['type'] = $type;
00787                     }
00788 
00789                     if (isset($data[$model][$tabl['name']])) {
00790                         $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
00791                     } else {
00792                         $fieldNames[$tabl['name']]['selected'] = null;
00793                     }
00794 
00795                 break;
00796                 default:
00797                 break;
00798             }
00799         }
00800 
00801         foreach ($objRegistryModel->hasAndBelongsToMany as $relation => $relData) {
00802             $modelName = $relData['className'];
00803             $manyAssociation = $relation;
00804             $modelKeyM = Inflector::underscore($modelName);
00805             $modelObject =& new $modelName();
00806 
00807             if ($doCreateOptions) {
00808                 $otherDisplayField = $modelObject->getDisplayField();
00809                 $fieldNames[$relation]['model'] = $modelName;
00810                 $fieldNames[$relation]['prompt'] = "Related " . Inflector::humanize(Inflector::pluralize($relation));
00811                 $fieldNames[$relation]['type'] = "selectMultiple";
00812                 $fieldNames[$relation]['tagName'] = $manyAssociation . '/' . $manyAssociation;
00813                 $modelObject->recursive = 0;
00814                 $rec = $modelObject->findAll();
00815 
00816                 foreach ($rec as $pass) {
00817                     foreach ($pass as $key => $value) {
00818                         if ($key == $modelName && isset($value[$modelObject->primaryKey]) && isset($value[$otherDisplayField])) {
00819                             $fieldNames[$relation]['options'][$value[$modelObject->primaryKey]] = $value[$otherDisplayField];
00820                         }
00821                     }
00822                 }
00823 
00824                 if (isset($data[$manyAssociation])) {
00825                     foreach ($data[$manyAssociation] as $key => $row) {
00826                         $fieldNames[$relation]['selected'][$row[$modelObject->primaryKey]] = $row[$modelObject->primaryKey];
00827                     }
00828                 }
00829             }
00830         }
00831         return $fieldNames;
00832     }
00833 /**
00834  * Converts POST'ed model data to a model conditions array, suitable for a find or findAll Model query
00835  *
00836  * @param array $data POST'ed data organized by model and field
00837  * @return array An array of model conditions
00838  * @access public
00839  */
00840     function postConditions($data) {
00841         if (!is_array($data) || empty($data)) {
00842             return null;
00843         }
00844         $conditions = array();
00845 
00846         foreach ($data as $model => $fields) {
00847             foreach ($fields as $field => $value) {
00848                 $conditions[$model . '.' . $field] = $value;
00849             }
00850         }
00851         return $conditions;
00852     }
00853 /**
00854  * Cleans up the date fields of current Model.
00855  *
00856  * @param string $modelName
00857  * @access public
00858  */
00859     function cleanUpFields($modelName = null) {
00860         if ($modelName == null) {
00861             $modelName = $this->modelClass;
00862         }
00863 
00864         foreach ($this->{$modelName}->_tableInfo->value as $field) {
00865             if ('date' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
00866                 $newDate = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
00867                 $newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
00868                 $newDate .= $this->params['data'][$modelName][$field['name'] . '_day'];
00869                 unset($this->params['data'][$modelName][$field['name'] . '_year']);
00870                 unset($this->params['data'][$modelName][$field['name'] . '_month']);
00871                 unset($this->params['data'][$modelName][$field['name'] . '_day']);
00872                 unset($this->params['data'][$modelName][$field['name'] . '_hour']);
00873                 unset($this->params['data'][$modelName][$field['name'] . '_min']);
00874                 unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
00875                 $this->params['data'][$modelName][$field['name']] = $newDate;
00876                 $this->data[$modelName][$field['name']] = $newDate;
00877 
00878             } elseif ('datetime' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
00879                 $hour = $this->params['data'][$modelName][$field['name'] . '_hour'];
00880 
00881                 if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
00882                     $hour = $hour + 12;
00883                 }
00884 
00885                 $newDate  = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
00886                 $newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
00887                 $newDate .= $this->params['data'][$modelName][$field['name'] . '_day'] . ' ';
00888                 $newDate .= $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
00889                 unset($this->params['data'][$modelName][$field['name'] . '_year']);
00890                 unset($this->params['data'][$modelName][$field['name'] . '_month']);
00891                 unset($this->params['data'][$modelName][$field['name'] . '_day']);
00892                 unset($this->params['data'][$modelName][$field['name'] . '_hour']);
00893                 unset($this->params['data'][$modelName][$field['name'] . '_min']);
00894                 unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
00895                 $this->params['data'][$modelName][$field['name']] = $newDate;
00896                 $this->data[$modelName][$field['name']] = $newDate;
00897 
00898             } elseif ('time' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_hour'])) {
00899                 $hour = $this->params['data'][$modelName][$field['name'] . '_hour'];
00900 
00901                 if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
00902                     $hour = $hour + 12;
00903                 }
00904                 if ($hour == 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'am' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
00905                      $hour = '00';
00906                 }
00907 
00908                 $newDate = $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
00909                 unset($this->params['data'][$modelName][$field['name'] . '_hour']);
00910                 unset($this->params['data'][$modelName][$field['name'] . '_min']);
00911                 unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
00912                 $this->params['data'][$modelName][$field['name']] = $newDate;
00913                 $this->data[$modelName][$field['name']] = $newDate;
00914             }
00915         }
00916     }
00917 /**
00918  * Called before the controller action.  Overridden in subclasses.
00919  *
00920  * @access public
00921  */
00922     function beforeFilter() {
00923     }
00924 /**
00925  * Called after the controller action is run, but before the view is rendered.  Overridden in subclasses.
00926  *
00927  * @access public
00928  */
00929     function beforeRender() {
00930     }
00931 /**
00932  * Called after the controller action is run and rendered.  Overridden in subclasses.
00933  *
00934  * @access public
00935  */
00936     function afterFilter() {
00937     }
00938 /**
00939  * This method should be overridden in child classes.
00940  *
00941  * @param string $method name of method called example index, edit, etc.
00942  * @return boolean
00943  * @access protected
00944  */
00945     function _beforeScaffold($method) {
00946         return true;
00947     }
00948 /**
00949  * This method should be overridden in child classes.
00950  *
00951  * @param string $method name of method called either edit or update.
00952  * @return boolean
00953  * @access protected
00954  */
00955     function _afterScaffoldSave($method) {
00956         return true;
00957     }
00958 /**
00959  * This method should be overridden in child classes.
00960  *
00961  * @param string $method name of method called either edit or update.
00962  * @return boolean
00963  * @access protected
00964  */
00965     function _afterScaffoldSaveError($method) {
00966         return true;
00967     }
00968 /**
00969  * This method should be overridden in child classes.
00970  * If not it will render a scaffold error.
00971  * Method MUST return true in child classes
00972  *
00973  * @param string $method name of method called example index, edit, etc.
00974  * @return boolean
00975  * @access protected
00976  */
00977     function _scaffoldError($method) {
00978         return false;
00979     }
00980 /**
00981  * Used to convert HABTM data into an array for selectTag
00982  *
00983  * @param array $data
00984  * @param string $key
00985  * @return array
00986  * @access protected
00987  */
00988     function _selectedArray($data, $key = 'id') {
00989         $array = array();
00990         if (!empty($data)) {
00991             foreach ($data as $var) {
00992                 $array[$var[$key]] = $var[$key];
00993             }
00994         }
00995         return $array;
00996     }
00997 }
00998 ?>