From 1748ac0318889644fd3fb21d7ee9d0d24eb90224 Mon Sep 17 00:00:00 2001 From: phpnut Date: Wed, 1 Feb 2006 13:26:23 +0000 Subject: [PATCH] Merging fixes and enhancements into trunk Revision: [1891] Added patch from Ticket #278 Revision: [1890] Adding patch from Ticket #227 Revision: [1889] Adding fix from Changeset [1631]. This fixes Ticket #319 Revision: [1888] Added fix for Ticket #315 Revision: [1887] Adding patch from Ticket #312 Revision: [1886] Adding fix that was committed in [1304] back. Closing Ticket #77 again Revision: [1885] Fix added for Ticket #306 Added patch from Ticket #318 Added patch from Ticket #322 Revision: [1884] Adding fix to Ticket #332 Revision: [1883] Adding patch from Ticket #330 Revision: [1882] Adding fix for Ticket #170 back to HtmlHelper::selectTag(). Was lost in a previous merge Revision: [1881] Adding fix for Ticket #336 Revision: [1880] Adding fix from Ticket #307 Revision: [1879] Plugins will use their own helpers and components if present Revision: [1878] Basic implementation of plugins within app/plugins working. Revision: [1877] Starting plugin code for multiple apps within one app. Revision: [1876] Added Ticket #345. Revision: [1875] Added check to AcoAction class that would not attempt to load AppModel Class if it is already defined in memory Added fixes for Ticket #317, Ticket #333, Ticket #343, Ticket #337 Revision: [1874] Adding fix for Ticket #340 Revision: [1873] Added themeWeb var to helpers that will be used if a theme class overrides the view class Revision: [1872] Adding $format to timeAgo and relativeTime, for gwoo Revision: [1871] Docstrings changes. One char at a time we map out Cake. Revision: [1870] Docstrings for Session, and corrections to tabbing on datasource. Revision: [1869] Docstrings for the core database classes. Revision: [1868] Adding patch for Ticket #131 Revision: [1867] Allowing ajax link titles to not be escaped Revision: [1866] Changed error class so calls to ErrorHandler::error() in production setting will work. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@1892 3807eeeb-6ff5-0310-8944-8be069107fe0 --- VERSION.txt | 2 +- cake/basics.php | 39 ++++- cake/dispatcher.php | 92 ++++++---- cake/libs/controller/component.php | 6 +- .../components/dbacl/models/aclnode.php | 2 +- .../components/dbacl/models/acoaction.php | 7 +- cake/libs/controller/controller.php | 84 ++++++++- cake/libs/error.php | 23 ++- cake/libs/model/datasources/datasource.php | 59 ++++--- cake/libs/model/datasources/dbo_source.php | 94 +++++----- cake/libs/model/dbo/dbo_mysql.php | 4 + cake/libs/model/dbo/dbo_postgres.php | 21 +-- cake/libs/model/model_php4.php | 64 ++++--- cake/libs/model/model_php5.php | 161 +++++++++++------- cake/libs/router.php | 4 +- cake/libs/session.php | 136 ++++++++------- cake/libs/view/helpers/ajax.php | 6 +- cake/libs/view/helpers/form.php | 13 +- cake/libs/view/helpers/html.php | 13 +- cake/libs/view/helpers/javascript.php | 2 +- cake/libs/view/helpers/text.php | 6 +- cake/libs/view/helpers/time.php | 12 +- .../view/templates/errors/missing_model.thtml | 37 ++++ cake/libs/view/view.php | 45 ++++- 24 files changed, 626 insertions(+), 306 deletions(-) create mode 100644 cake/libs/view/templates/errors/missing_model.thtml diff --git a/VERSION.txt b/VERSION.txt index 3f45fc512..4f77f96b2 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -6,4 +6,4 @@ // +---------------------------------------------------------------------------------------------------+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////// -0.10.8.1865 RC 4 \ No newline at end of file +0.10.8.1892 RC 4 \ No newline at end of file diff --git a/cake/basics.php b/cake/basics.php index 0886a3872..82b45bd5d 100644 --- a/cake/basics.php +++ b/cake/basics.php @@ -195,6 +195,10 @@ function loadController ($name) require_once(CAKE.'app_controller.php'); } } + if($name === null) + { + return; + } if(!class_exists($name.'Controller')) { $name = Inflector::underscore($name); @@ -218,6 +222,32 @@ function loadController ($name) } } +/** + * Loads a loadPluginController. + * + * @param string $plugin Name of plugin + * @param string $controller Name of controller to load + * @return boolean Success + */ +function loadPluginController ($plugin, $controller) +{ + + if(!class_exists($controller.'Controller')) + { + $controller = Inflector::underscore($controller); + $file = APP.'plugins'.DS.$plugin.DS.'controllers'.DS.$controller.'_controller.php'; + if(!file_exists($file)) + { + return false; + } + else + { + require_once($file); + return true; + } + } +} + /** * Returns an array of filenames of PHP files in given directory. * @@ -303,7 +333,14 @@ function vendor($name) $args = func_get_args(); foreach ($args as $arg) { - require_once(VENDORS.$arg.'.php'); + if(file_exists(APP.'vendors'.DS.$arg.'.php')) + { + require_once(APP.'vendors'.DS.$arg.'.php'); + } + else + { + require_once(VENDORS.$arg.'.php'); + } } } diff --git a/cake/dispatcher.php b/cake/dispatcher.php index 1c7b37910..dcbd56284 100644 --- a/cake/dispatcher.php +++ b/cake/dispatcher.php @@ -52,17 +52,20 @@ class Dispatcher extends Object var $base = false; /** - * Base URL * @var string */ var $admin = false; /** - * Base URL * @var string */ var $webservices = null; +/** + * @var string + */ + var $plugin = null; + /** * Constructor. */ @@ -89,6 +92,47 @@ class Dispatcher extends Object $missingView = false; $privateAction = false; + if (empty($params['controller'])) + { + $missingController = true; + } + else + { + $ctrlName = Inflector::camelize($params['controller']); + $ctrlClass = $ctrlName.'Controller'; + + if(!class_exists($ctrlClass)) + { + if (!loadController($ctrlName)) + { + $plugin = $ctrlName; + $pluginName = Inflector::camelize($params['action']); + $pluginClass = $pluginName.'Controller'; + + if (!loadPluginController(Inflector::underscore($ctrlName), $pluginName)) + { + if(preg_match('/([\\.]+)/', $ctrlName)) + { + return $this->cakeError('error404',array(array('url' => strtolower($ctrlName), + 'message' => 'Was not found on this server'))); + exit(); + } + else + { + $missingController = true; + } + } + else + { + $ctrlClass = $pluginClass; + $params = $this->_restructureParams($params); + $this->plugin = Inflector::underscore($ctrlName).DS; + } + + } + } + } + if(defined('CAKE_ADMIN')) { if(isset($params[CAKE_ADMIN])) @@ -108,33 +152,6 @@ class Dispatcher extends Object $this->base = $this->baseUrl(); - if (empty($params['controller'])) - { - $missingController = true; - } - else - { - $ctrlName = Inflector::camelize($params['controller']); - $ctrlClass = $ctrlName.'Controller'; - - if(!class_exists($ctrlClass)) - { - if (!loadController($ctrlName)) - { - if(preg_match('/([\\.]+)/',$ctrlName)) - { - return $this->cakeError('error404',array(array('url' => strtolower($ctrlName), - 'message' => 'Was not found on this server'))); - exit(); - } - else - { - $missingController = true; - } - } - } - } - if ($missingController) { return $this->cakeError('missingController',array(array('className' => Inflector::camelize($params['controller']."Controller"), @@ -175,8 +192,9 @@ class Dispatcher extends Object $controller->action = $params['action']; $controller->data = empty($params['data'])? null: $params['data']; $controller->passed_args = empty($params['pass'])? null: $params['pass']; - $controller->autoLayout = !$params['bare']; + $controller->autoLayout = empty($params['bare'])?$controller->autoLayout:!$params['bare']; $controller->webservices = $params['webservices']; + $controller->plugin = $this->plugin; if(!is_null($controller->webservices)) { @@ -351,5 +369,19 @@ class Dispatcher extends Object } return $base; } + + function _restructureParams($params) + { + $params['controller'] = $params['action']; + if(isset($params['pass'][0])) + { + $params['action'] = $params['pass'][0]; + } + else + { + $params['action'] = null; + } + return $params; + } } ?> \ No newline at end of file diff --git a/cake/libs/controller/component.php b/cake/libs/controller/component.php index f574598a7..400fe21e1 100644 --- a/cake/libs/controller/component.php +++ b/cake/libs/controller/component.php @@ -91,7 +91,11 @@ class Component extends Object { $componentFn = Inflector::underscore($component).'.php'; - if(file_exists(COMPONENTS.$componentFn)) + if(file_exists(APP.'plugins'.DS.$this->controller->plugin.'controllers'.DS.'components'.DS.$componentFn)) + { + $componentFn = APP.'plugins'.DS.$this->controller->plugin.'controllers'.DS.'components'.DS.$componentFn; + } + else if(file_exists(COMPONENTS.$componentFn)) { $componentFn = COMPONENTS.$componentFn; } diff --git a/cake/libs/controller/components/dbacl/models/aclnode.php b/cake/libs/controller/components/dbacl/models/aclnode.php index 1fcd28d97..83a55a82d 100644 --- a/cake/libs/controller/components/dbacl/models/aclnode.php +++ b/cake/libs/controller/components/dbacl/models/aclnode.php @@ -279,7 +279,7 @@ class AclNode extends AppModel $class = Inflector::camelize(strtolower(get_class($this))); $vars['secondary_id'] = (strtolower($class) == 'aro' ? 'user_id' : 'object_id'); $vars['data_name'] = $class; - $vars['table_name'] = $class . 's'; + $vars['table_name'] = strtolower($class) . 's'; $vars['class'] = Inflector::camelize($class); return $vars; } diff --git a/cake/libs/controller/components/dbacl/models/acoaction.php b/cake/libs/controller/components/dbacl/models/acoaction.php index e8627924a..0a11f2a0f 100644 --- a/cake/libs/controller/components/dbacl/models/acoaction.php +++ b/cake/libs/controller/components/dbacl/models/acoaction.php @@ -31,9 +31,10 @@ /** * Short description. */ - -require_once(CAKE.'app_model.php'); - +if(!class_exists(AppModel)) +{ + require_once(CAKE.'app_model.php'); +} /** * Short description for file. * diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 006681e8e..4bf231f44 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -178,6 +178,8 @@ class Controller extends Object */ var $_viewClass = null; + var $plugin = null; + /** * Constructor. * @@ -193,7 +195,6 @@ class Controller extends Object } $this->name = $r[1]; } - $this->viewPath = Inflector::underscore($this->name); $this->modelClass = Inflector::singularize($this->name); $this->modelKey = Inflector::underscore($this->modelClass); @@ -250,7 +251,12 @@ class Controller extends Object $this->{$this->modelClass} =& new $this->modelClass($id); $this->modelNames[] = $this->modelClass; } - elseif ($this->uses) + elseif($this->uses === false) + { + return $this->cakeError('missingModel',array(array('className' => $this->modelClass, + 'webroot' => ''))); + } + if ($this->uses) { $uses = is_array($this->uses)? $this->uses: array($this->uses); @@ -265,7 +271,7 @@ class Controller extends Object } else { - return $this->cakeError('missingTable',array(array('className' => $modelClass, + return $this->cakeError('missingModel',array(array('className' => $modelClass, 'webroot' => ''))); } } @@ -275,9 +281,10 @@ class Controller extends Object /** * Redirects to given $url, after turning off $this->autoRender. * - * @param unknown_type $url + * @param string $url + * @param integer $status */ - function redirect ($url) + function redirect ($url, $status = null) { $this->autoRender = false; if(strpos($url, '/') !== 0) @@ -288,7 +295,64 @@ class Controller extends Object { session_write_close(); } - header ('Location: '.$this->base.$url); + + if ($status != null) + { + $codes = array ( + 100 => "HTTP/1.1 100 Continue", + 101 => "HTTP/1.1 101 Switching Protocols", + 200 => "HTTP/1.1 200 OK", + 201 => "HTTP/1.1 201 Created", + 202 => "HTTP/1.1 202 Accepted", + 203 => "HTTP/1.1 203 Non-Authoritative Information", + 204 => "HTTP/1.1 204 No Content", + 205 => "HTTP/1.1 205 Reset Content", + 206 => "HTTP/1.1 206 Partial Content", + 300 => "HTTP/1.1 300 Multiple Choices", + 301 => "HTTP/1.1 301 Moved Permanently", + 302 => "HTTP/1.1 302 Found", + 303 => "HTTP/1.1 303 See Other", + 304 => "HTTP/1.1 304 Not Modified", + 305 => "HTTP/1.1 305 Use Proxy", + 307 => "HTTP/1.1 307 Temporary Redirect", + 400 => "HTTP/1.1 400 Bad Request", + 401 => "HTTP/1.1 401 Unauthorized", + 402 => "HTTP/1.1 402 Payment Required", + 403 => "HTTP/1.1 403 Forbidden", + 404 => "HTTP/1.1 404 Not Found", + 405 => "HTTP/1.1 405 Method Not Allowed", + 406 => "HTTP/1.1 406 Not Acceptable", + 407 => "HTTP/1.1 407 Proxy Authentication Required", + 408 => "HTTP/1.1 408 Request Time-out", + 409 => "HTTP/1.1 409 Conflict", + 410 => "HTTP/1.1 410 Gone", + 411 => "HTTP/1.1 411 Length Required", + 412 => "HTTP/1.1 412 Precondition Failed", + 413 => "HTTP/1.1 413 Request Entity Too Large", + 414 => "HTTP/1.1 414 Request-URI Too Large", + 415 => "HTTP/1.1 415 Unsupported Media Type", + 416 => "HTTP/1.1 416 Requested range not satisfiable", + 417 => "HTTP/1.1 417 Expectation Failed", + 500 => "HTTP/1.1 500 Internal Server Error", + 501 => "HTTP/1.1 501 Not Implemented", + 502 => "HTTP/1.1 502 Bad Gateway", + 503 => "HTTP/1.1 503 Service Unavailable", + 504 => "HTTP/1.1 504 Gateway Time-out" + ); + if (isset($codes[$status])) + { + header($codes[$status]); + } + } + + if (strpos($url, '://')) + { + header ('Location: '.$url); + } + else + { + header ('Location: '.$this->base.$url); + } } /** @@ -432,9 +496,13 @@ class Controller extends Object foreach ($data as $name => $value) { if ($name == 'title') - $this->_setTitle($value); + { + $this->_setTitle($value); + } else - $this->_viewVars[$name] = $value; + { + $this->_viewVars[$name] = $value; + } } } diff --git a/cake/libs/error.php b/cake/libs/error.php index 50932128d..30064e956 100644 --- a/cake/libs/error.php +++ b/cake/libs/error.php @@ -47,8 +47,12 @@ class ErrorHandler extends Object */ function __construct($method, $messages) { - $this->controller =& new Controller(); - if(DEBUG > 0) + if(!class_exists('AppController')) + { + loadController(null); + } + $this->controller =& new AppController(); + if(DEBUG > 0 || $method == 'error') { call_user_func_array(array(&$this, $method), $messages); } @@ -274,6 +278,21 @@ class ErrorHandler extends Object exit(); } +/** + * Renders the Missing Model class web page. + * + */ + function missingModel($params) + { + extract($params); + $this->controller->webroot = $this->_webroot(); + $this->controller->set(array('model' => $className, + 'title' => 'Missing Model')); + $this->controller->render('../errors/missingModel'); + exit(); + } + + /** * Enter description here... diff --git a/cake/libs/model/datasources/datasource.php b/cake/libs/model/datasources/datasource.php index 950b09521..8d32e2b87 100644 --- a/cake/libs/model/datasources/datasource.php +++ b/cake/libs/model/datasources/datasource.php @@ -2,7 +2,7 @@ /* SVN FILE: $Id$ */ /** - * Short description for file. + * DataSource base class * * Long description for file * @@ -29,7 +29,7 @@ */ /** - * Short description for file. + * DataSource base class * * Long description for file * @@ -76,7 +76,7 @@ class DataSource extends Object /** * String to hold how many rows were affected by the last SQL operation. * - * @var unknown_type + * @var string * @access public */ var $affected = null; @@ -92,7 +92,7 @@ class DataSource extends Object /** * Time the last query took * - * @var unknown_type + * @var int * @access public */ var $took = null; @@ -100,7 +100,7 @@ class DataSource extends Object /** * Enter description here... * - * @var unknown_type + * @var array * @access private */ var $_result = null; @@ -108,7 +108,7 @@ class DataSource extends Object /** * Queries count. * - * @var unknown_type + * @var int * @access private */ var $_queriesCnt = 0; @@ -189,7 +189,7 @@ class DataSource extends Object /** - * Enter description here... + * Constructor. * */ function __construct () @@ -270,7 +270,7 @@ class DataSource extends Object } /** - * Parses conditions array (or just passes it if it's a string) + * To-be-overridden in subclasses. * @return string * */ @@ -280,7 +280,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $name * @return unknown @@ -291,7 +291,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $value * @return unknown @@ -302,10 +302,10 @@ class DataSource extends Object } /** - * Enter description here... + * Returns a Model description (metadata) or null if none found. * - * @param unknown_type $model - * @return unknown + * @param Model $model + * @return mixed */ function describe ($model) { @@ -324,7 +324,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $model * @param unknown_type $fields @@ -337,7 +337,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $model * @param unknown_type $queryData @@ -349,7 +349,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $model * @param unknown_type $fields @@ -362,7 +362,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $model * @param unknown_type $id @@ -376,10 +376,10 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * - * @param unknown_type $fields - * @return unknown + * @param mixed $fields + * @return mixed */ function fields ($fields) { @@ -387,7 +387,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $model * @param unknown_type $fields @@ -405,7 +405,7 @@ class DataSource extends Object * @param unknown_type $data * @param unknown_type $association * @param unknown_type $assocData - * @param unknown_type $model + * @param Model $model * @param unknown_type $linkModel * @param unknown_type $index * @return unknown @@ -444,7 +444,7 @@ class DataSource extends Object } /** - * Enter description here... + * To-be-overridden in subclasses. * * @param unknown_type $model * @param unknown_type $key @@ -456,10 +456,10 @@ class DataSource extends Object } /** - * Enter description here... + * Enter description here... The special {n}, as seen in the Model::generateList method, is taken care of here. * - * @param unknown_type $data - * @param unknown_type $path + * @param array $data + * @param mixed $path * @return unknown */ function getFieldValue ($data, $path) @@ -512,14 +512,17 @@ class DataSource extends Object } return $data; } - +/** + * To-be-overridden in subclasses. + * + */ function buildSchemaQuery($schema) { die("Implement in DBO"); } /** - * Enter description here... + * Closes the current datasource. * */ function __destruct () diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 0a45a4248..f6f1db616 100644 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -47,11 +47,11 @@ uses('model'.DS.'datasources'.DS.'datasource'); class DboSource extends DataSource { /** - * Enter description here... + * Description string for this Database Data Source. * * @var unknown_type */ - var $description = "Database Data Source"; + var $description = "Database Data Source"; /** * Enter description here... * @@ -61,7 +61,7 @@ class DboSource extends DataSource /** * Enter description here... * - * @var unknown_type + * @var array */ var $__assocJoins = null; /** @@ -100,9 +100,9 @@ class DboSource extends DataSource } /** - * Enter description here... + * Convenience method for DboSource::listSources(). * - * @return unknown + * @return array */ function sources () { @@ -238,7 +238,7 @@ class DboSource extends DataSource } /** - * Outputs the contents of the log. + * Outputs the contents of the queries log. * * @param boolean $sorted */ @@ -248,7 +248,7 @@ class DboSource extends DataSource sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC): $this->_queriesLog; - if($this->_queriesCnt >1) + if($this->_queriesCnt > 1) { $text = 'queries'; } @@ -259,9 +259,9 @@ class DboSource extends DataSource print("\n\n"); print("\n"); - foreach($log AS $k=>$i) + foreach($log as $k => $i) { - print("\n"); + print("\n"); } print("
{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms
NrQueryErrorAffectedNum. rowsTook (ms)
".($k+1)."{$i['query']}{$i['error']}{$i['affected']}{$i['numRows']}{$i['took']}
".($k + 1)."{$i['query']}{$i['error']}{$i['affected']}{$i['numRows']}{$i['took']}
\n"); @@ -299,15 +299,15 @@ class DboSource extends DataSource /** * Output information about an SQL query. The SQL statement, number of rows in resultset, - * and execution time in microseconds. If the query fails, and error is output instead. + * and execution time in microseconds. If the query fails, an error is output instead. * - * @param string $sql + * @param string $sql Query to show information on. */ function showQuery($sql) { $error = $this->error; - if (strlen($sql)>200 && !$this->fullDebug) + if (strlen($sql) > 200 && !$this->fullDebug) { $sql = substr($sql, 0, 200) .'[...]'; } @@ -326,10 +326,10 @@ class DboSource extends DataSource /** * Enter description here... * - * @param unknown_type $model + * @param Model $model * @param unknown_type $fields * @param unknown_type $values - * @return unknown + * @return boolean Success */ function create(&$model, $fields = null, $values = null) { @@ -355,9 +355,9 @@ class DboSource extends DataSource /** * Enter description here... * - * @param unknown_type $model - * @param unknown_type $queryData - * @param unknown_type $recursive + * @param Model $model + * @param array $queryData + * @param integer $recursive Number of levels of association * @return unknown */ function read (&$model, $queryData = array(), $recursive = null) @@ -441,15 +441,15 @@ class DboSource extends DataSource /** * Enter description here... * - * @param unknown_type $model + * @param Model $model * @param unknown_type $linkModel - * @param unknown_type $type + * @param string $type Association type * @param unknown_type $association * @param unknown_type $assocData * @param unknown_type $queryData * @param unknown_type $external * @param unknown_type $resultSet - * @param unknown_type $recursive + * @param integer $recursive Number of levels of association */ function queryAssociation(&$model, &$linkModel, $type, $association, $assocData, &$queryData, $external = false, &$resultSet) { @@ -541,7 +541,7 @@ class DboSource extends DataSource /** * Enter description here... * - * @param unknown_type $model + * @param Model $model * @param unknown_type $linkModel * @param unknown_type $type * @param unknown_type $association @@ -755,12 +755,12 @@ class DboSource extends DataSource } /** - * Enter description here... + * Generates and executes an SQL UPDATE statement for given model, fields, and values. * - * @param unknown_type $model - * @param unknown_type $fields - * @param unknown_type $values - * @return unknown + * @param Model $model + * @param array $fields + * @param array $values + * @return array */ function update (&$model, $fields = null, $values = null) { @@ -778,11 +778,11 @@ class DboSource extends DataSource } /** - * Enter description here... + * Generates and executes an SQL DELETE statement for given id on given model. * - * @param unknown_type $model - * @param unknown_type $id - * @return unknown + * @param Model $model + * @param mixed $id Primary key id number to remove. + * @return boolean Success */ function delete (&$model, $id = null) { @@ -807,12 +807,12 @@ class DboSource extends DataSource } /** - * Enter description here... + * Returns a key formatted like a string Model.fieldname(i.e. Post.title, or Country.name) * * @param unknown_type $model * @param unknown_type $key * @param unknown_type $assoc - * @return unknown + * @return string */ function resolveKey($model, $key, $assoc = null) { @@ -840,9 +840,9 @@ class DboSource extends DataSource } /** - * Enter description here... + * Private helper method to remove query metadata in given data array. * - * @param unknown_type $data + * @param array $data */ function __scrubQueryData(&$data) { @@ -869,12 +869,12 @@ class DboSource extends DataSource } /** - * Enter description here... + * Generates the fields list of an SQL query. * - * @param unknown_type $model - * @param unknown_type $alias - * @param unknown_type $fields - * @return unknown + * @param Model $model + * @param string $alias Alias tablename + * @param mixed $fields + * @return array */ function fields (&$model, $alias, $fields) { @@ -927,10 +927,10 @@ class DboSource extends DataSource } /** - * Parses conditions array (or just passes it if it's a string) + * Creates a WHERE clause by parsing given conditions data. * - * @param unknown_type $conditions - * @return string + * @param mixed $conditions Array or string of conditions + * @return string SQL fragment */ function conditions ($conditions) { @@ -994,7 +994,7 @@ class DboSource extends DataSource } /** - * Enter description here... + * To be overridden in subclasses. * */ function limit () @@ -1002,11 +1002,11 @@ class DboSource extends DataSource } /** - * Enter description here... + * Returns an ORDER BY clause as a string. * - * @param unknown_type $key - * @param unknown_type $dir - * @return unknown + * @param string $key Field reference, as a key (i.e. Post.title) + * @param string $dir Direction (ASC or DESC) + * @return string ORDER BY clause */ function order ($key, $dir = '') { diff --git a/cake/libs/model/dbo/dbo_mysql.php b/cake/libs/model/dbo/dbo_mysql.php index 0c464c394..0d227ee85 100644 --- a/cake/libs/model/dbo/dbo_mysql.php +++ b/cake/libs/model/dbo/dbo_mysql.php @@ -273,6 +273,10 @@ class DboMysql extends DboSource { return $parent; } + if ($data === null) + { + return 'NULL'; + } if (ini_get('magic_quotes_gpc') == 1) { $data = stripslashes($data); diff --git a/cake/libs/model/dbo/dbo_postgres.php b/cake/libs/model/dbo/dbo_postgres.php index 34a506213..7f23591e8 100644 --- a/cake/libs/model/dbo/dbo_postgres.php +++ b/cake/libs/model/dbo/dbo_postgres.php @@ -111,7 +111,7 @@ class DboPostgres extends DboSource * @param string $sql SQL statement * @return resource Result resource identifier */ - function __execute ($sql) + function _execute ($sql) { return pg_query($this->connection, $sql); } @@ -171,15 +171,16 @@ class DboPostgres extends DboSource { return null; } - else - { - $tables = array(); - foreach ($result as $item) - { - $tables[] = $item['name']; - } - return $tables; - } + else + { + $tables = array(); + $tables[] = $result['name']; + while ($row = $this->fetchRow()) + { + $tables[] = $row['name']; + } + return $tables; + } } /** diff --git a/cake/libs/model/model_php4.php b/cake/libs/model/model_php4.php index 834df9e3f..5d3cf546f 100644 --- a/cake/libs/model/model_php4.php +++ b/cake/libs/model/model_php4.php @@ -659,7 +659,7 @@ class Model extends Object $id = $this->id[0]; } - if ($this->id) + if ($this->id !== null && $this->id !== false) { $field = $this->db->name($this->name).'.'.$this->db->name($this->primaryKey); return $this->find($field . ' = ' . $this->db->value($id), $fields); @@ -720,6 +720,19 @@ class Model extends Object return $this->save(array($this->name => array($name => $value)), $validate); } + function countdim($array) + { + if (is_array(reset($array))) + { + $return = $this->countdim(reset($array)) + 1; + } + else + { + $return = 1; + } + return $return; + } + /** * Saves model data to the database. * @@ -733,8 +746,16 @@ class Model extends Object { if ($data) { - $this->set($data); + if ($this->countdim($data) == 1) + { + $this->set(array($this->name => $data)); + } + else + { + $this->set($data); + } } + if($this->beforeSave()) { if ($validate && !$this->validates()) @@ -1100,26 +1121,25 @@ class Model extends Object */ function __doThread ($data, $root) { - $out = array(); - - for ($ii=0; $ii__doThread($data, $data[$ii]['id']); - } - else - { - $tmp['children'] = null; - } - $out[] = $tmp; - } - } - - return $out; + $out = array(); + $sizeOf = sizeof($data); + for ($ii=0; $ii < $sizeOf; $ii++) + { + if ($data[$ii][$this->name]['parent_id'] == $root) + { + $tmp = $data[$ii]; + if (isset($data[$ii][$this->name][$this->primaryKey])) + { + $tmp['children'] = $this->__doThread($data, $data[$ii][$this->name][$this->primaryKey]); + } + else + { + $tmp['children'] = null; + } + $out[] = $tmp; + } + } + return $out; } /** diff --git a/cake/libs/model/model_php5.php b/cake/libs/model/model_php5.php index 131a61e05..1208f9f54 100644 --- a/cake/libs/model/model_php5.php +++ b/cake/libs/model/model_php5.php @@ -77,7 +77,7 @@ class Model extends Object var $parent = false; /** - * Custom database table name + * Custom database table name. * * @var string * @access public @@ -85,7 +85,7 @@ class Model extends Object var $useTable = null; /** - * Custom display field name + * Custom display field name. Display fields are used by Scaffold, in SELECT boxes' OPTION elements. * * @var string * @access public @@ -147,7 +147,7 @@ class Model extends Object var $validationErrors = null; /** - * Prefix for tables in model. + * Database table prefix for tables in model. * * @var string */ @@ -161,7 +161,7 @@ class Model extends Object var $name = null; /** - * Name of the model. + * Name of the current model. * * @var string */ @@ -182,7 +182,7 @@ class Model extends Object var $modelToTable = array(); /** - * List of Foreign Key names to table used tables. Used for associations. + * List of Foreign Key names to used tables. Used for associations. * * @var array */ @@ -203,7 +203,7 @@ class Model extends Object var $logTransactions = false; /** - * Whether or not to enable transactions for this model (i.e. begin/commit/rollback) + * Whether or not to enable transactions for this model (i.e. BEGIN/COMMIT/ROLLBACK) * * @var boolean */ @@ -238,7 +238,7 @@ class Model extends Object var $hasAndBelongsToMany = array(); /** - * recursive assoication depth + * Depth of recursive association * * @var int */ @@ -290,8 +290,8 @@ class Model extends Object * Constructor. Binds the Model's database table to the object. * * @param integer $id - * @param string $table Database table to use. - * @param unknown_type $ds DataSource connection object. + * @param string $table Name of database table to use. + * @param DataSource $ds DataSource connection object. */ function __construct ($id=false, $table=null, $ds=null) { @@ -369,7 +369,7 @@ class Model extends Object * and custom RPC calls for remote data sources. * * @param unknown_type $method - * @param unknown_type $params + * @param array $params * @return unknown * @access protected */ @@ -424,6 +424,7 @@ class Model extends Object * @param string $assoc * @param string $className Class name * @param string $type Type of assocation + * @todo Is the third parameter in use at the moment? It is not referred to in the method OJ, 30. jan 2006 * @access private */ function __constructLinkedModel($assoc, $className, $type) @@ -444,11 +445,11 @@ class Model extends Object } /** - * Build array-based association from string + * Build array-based association from string. * * @param string $type "Belongs", "One", "Many", "ManyTo" * @param string $assoc - * @param string $model + * @todo Is the second parameter in use at the moment? It is not referred to in the method OJ, 30. jan 2006 * @access private */ function __generateAssociation ($type, $assoc) @@ -583,10 +584,9 @@ class Model extends Object } /** - * Returns true if given field name exists in this Model's database table. - * Starts by loading the metadata into the private property table_info if that is not already set. + * Returns true if this Model has given field in its database table. * - * @param string $name Name of table to look in + * @param string $name Name of field to look for * @return boolean */ function hasField ($name) @@ -603,9 +603,9 @@ class Model extends Object } /** - * Initializes the model for writing a new record + * Initializes the model for writing a new record. * - * @return boolean True on success + * @return boolean True */ function create () { @@ -625,7 +625,7 @@ class Model extends Object } /** - * Deprecated + * Deprecated. Use query() instead. * */ function findBySql ($sql) @@ -655,7 +655,7 @@ class Model extends Object $id = $this->id[0]; } - if ($this->id) + if ($this->id !== null && $this->id !== false) { $field = $this->db->name($this->name).'.'.$this->db->name($this->primaryKey); return $this->find($field . ' = ' . $this->db->value($id), $fields); @@ -670,8 +670,8 @@ class Model extends Object * Returns contents of a field in a query matching given conditions. * * @param string $name Name of field to get - * @param string $conditions SQL conditions (defaults to NULL) - * @param string $order (defaults to NULL) + * @param array $conditions SQL conditions (defaults to NULL) + * @param string $order SQL ORDER BY fragment * @return field contents */ function field ($name, $conditions = null, $order = null) @@ -716,11 +716,31 @@ class Model extends Object return $this->save(array($this->name => array($name => $value)), $validate); } +/** + * Enter description here... + * + * @param unknown_type $array + * @return unknown + */ + function countdim($array) + { + if (is_array(reset($array))) + { + $return = $this->countdim(reset($array)) + 1; + } + else + { + $return = 1; + } + return $return; + } + /** * Saves model data to the database. + * By default, validation occurs before save. * * @param array $data Data to save. - * @param boolean $validate + * @param boolean $validate If set, validation will be done before the save * @param array $fields * @return boolean success * @todo Implement $fields param as a whitelist of allowable fields @@ -729,7 +749,14 @@ class Model extends Object { if ($data) { - $this->set($data); + if ($this->countdim($data) == 1) + { + $this->set(array($this->name => $data)); + } + else + { + $this->set($data); + } } if($this->beforeSave()) { @@ -917,7 +944,7 @@ class Model extends Object /** * Removes record for given id. If no id is given, the current id is used. Returns true on success. * - * @param mixed $id Id of database record to delete + * @param mixed $id Id of record to delete * @return boolean True on success */ function del ($id = null) @@ -962,6 +989,7 @@ class Model extends Object /** * Returns true if a record that meets given conditions exists * + * @param array $conditions SQL conditions array * @return boolean True if such a record exists */ function hasAny ($conditions = null) @@ -971,11 +999,13 @@ class Model extends Object /** * Return a single row as a resultset array. + * By using the $recursive parameter, the call can access further "levels of association" than + * the ones this model is directly associated to. * - * @param string $conditions SQL conditions + * @param array $conditions SQL conditions array * @param mixed $fields Either a single string of a field name, or an array of field names * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC") - * @param int $recursize The number of levels deep to fetch associated records + * @param int $recursive The number of levels deep to fetch associated records * @return array Array of records */ function find ($conditions = null, $fields = null, $order = null, $recursive = null) @@ -990,13 +1020,15 @@ class Model extends Object /** * Returns a resultset array with specified fields from database matching given conditions. + * By using the $recursive parameter, the call can access further "levels of association" than + * the ones this model is directly associated to. * * @param mixed $conditions SQL conditions as a string or as an array('field'=>'value',...) * @param mixed $fields Either a single string of a field name, or an array of field names * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC") - * @param int $limit SQL LIMIT clause, for calculating items per page - * @param int $page Page number - * @param int $recursize The number of levels deep to fetch associated records + * @param int $limit SQL LIMIT clause, for calculating items per page. + * @param int $page Page number, for accessing paged data + * @param int $recursive The number of levels deep to fetch associated records * @return array Array of records */ function findAll ($conditions = null, $fields = null, $order = null, $limit = 50, $page = 1, $recursive = null) @@ -1029,7 +1061,7 @@ class Model extends Object } /** - * Runs a direct query against the bound DataSource, and returns the result + * Runs a direct query against the bound DataSource, and returns the result. * * @param string $data Query data * @return array @@ -1057,9 +1089,10 @@ class Model extends Object /** * Returns number of rows matching given SQL condition. * - * @param string $conditions SQL conditions (WHERE clause conditions) + * @param array $conditions SQL conditions array for findAll * @param int $recursize The number of levels deep to fetch associated records * @return int Number of matching rows + * @see Model::findAll */ function findCount ($conditions = null, $recursive = 0) { @@ -1073,12 +1106,12 @@ class Model extends Object /** * Special findAll variation for tables joined to themselves. - * The table needs fields id and parent_id to work. + * The table needs the fields id and parent_id to work. * * @param array $conditions Conditions for the findAll() call * @param array $fields Fields for the findAll() call * @param string $sort SQL ORDER BY statement - * @return unknown + * @return array * @todo Perhaps create a Component with this logic */ function findAllThreaded ($conditions=null, $fields=null, $sort=null) @@ -1093,29 +1126,29 @@ class Model extends Object * @param string $root NULL or id for root node of operation * @return array * @access private + * @see findAllThreaded */ function __doThread ($data, $root) { - $out = array(); - - for ($ii=0; $ii__doThread($data, $data[$ii]['id']); - } - else - { - $tmp['children'] = null; - } - $out[] = $tmp; - } - } - - return $out; + $out = array(); + $sizeOf = sizeof($data); + for ($ii=0; $ii < $sizeOf; $ii++) + { + if ($data[$ii][$this->name]['parent_id'] == $root) + { + $tmp = $data[$ii]; + if (isset($data[$ii][$this->name][$this->primaryKey])) + { + $tmp['children'] = $this->__doThread($data, $data[$ii][$this->name][$this->primaryKey]); + } + else + { + $tmp['children'] = null; + } + $out[] = $tmp; + } + } + return $out; } /** @@ -1123,7 +1156,7 @@ class Model extends Object * which is useful when creating paged lists. * * @param string $conditions SQL conditions for matching rows - * @param unknown_type $field + * @param string $field Field name (parameter for findAll) * @param unknown_type $value * @return array Array with keys "prev" and "next" that holds the id's */ @@ -1148,7 +1181,7 @@ class Model extends Object } /** - * Returns a resultset for given SQL statement. + * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method. * * @param string $sql SQL statement * @return array Resultset @@ -1160,7 +1193,7 @@ class Model extends Object } /** - * Returns true if all fields pass validation. + * Returns true if all fields pass validation, otherwise false. * * @param array $data POST data * @return boolean True if there are no errors @@ -1223,7 +1256,7 @@ class Model extends Object } /** - * This function determines whether or not a string is a foreign key + * Returns true if given field name is a foreign key in this Model. * * @param string $field Returns true if the input string ends in "_id" * @return True if the field is a foreign key listed in the belongsTo array. @@ -1253,7 +1286,7 @@ class Model extends Object } /** - * Returns a resultset array with specified fields from database matching given conditions. + * Returns a resultset array with specified fields from database matching given conditions. Method can be used to generate option lists for SELECT elements. * * @param mixed $conditions SQL conditions as a string or as an array('field'=>'value',...) * @param mixed $fields Either a single string of a field name, or an array of field names @@ -1282,7 +1315,7 @@ class Model extends Object } /** - * Escapes the field name and prepends the model name + * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules. * * @param unknown_type $field * @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`). @@ -1319,7 +1352,7 @@ class Model extends Object } /** - * Gets the ID of the last record this Model inserted + * Returns the ID of the last record this Model inserted * * @return mixed */ @@ -1329,7 +1362,7 @@ class Model extends Object } /** - * Gets the ID of the last record this Model inserted + * Returns the ID of the last record this Model inserted * * @return mixed */ @@ -1339,7 +1372,7 @@ class Model extends Object } /** - * Gets the number of rows returned from the last query + * Returns the number of rows returned from the last query * * @return int */ @@ -1350,7 +1383,7 @@ class Model extends Object } /** - * Gets the number of rows affected by the last query + * Returns the number of rows affected by the last query * * @return int */ @@ -1391,7 +1424,7 @@ class Model extends Object } /** - * After find callback + * After find callback. Can be used to modify any results returned by find and findAll. * * @param mixed $results The results of the find operation * @return mixed Result of the find operation diff --git a/cake/libs/router.php b/cake/libs/router.php index 3d3a247c3..89b82f064 100644 --- a/cake/libs/router.php +++ b/cake/libs/router.php @@ -127,7 +127,7 @@ class Router extends Object { $default_route = array ( '/:controller/:action/* (default)', - '/^(?:\/(?:([a-zA-Z0-9_\\-\\.]+)(?:\\/([a-zA-Z0-9_\\-\\.]+)(?:\\/(.*))?)?))[\\/]*$/', + '/^(?:\/(?:([a-zA-Z0-9_\\-\\.]+)(?:\\/([a-zA-Z0-9_\\-\\.]+)(?:[\\/\\?](.*))?)?))[\\/]*$/', array('controller', 'action'), array()); @@ -139,7 +139,7 @@ class Router extends Object { $this->routes[] = array ( '/:'.$admin.'/:controller/:action/* (default)', - '/^(?:\/(?:('.$admin.')(?:\\/([a-zA-Z0-9_\\-\\.]+)(?:\\/([a-zA-Z0-9_\\-\\.]+)(?:\/(.*))?)?)?))[\/]*$/', + '/^(?:\/(?:('.$admin.')(?:\\/([a-zA-Z0-9_\\-\\.]+)(?:\\/([a-zA-Z0-9_\\-\\.]+)(?:[\\/\\?](.*))?)?)?))[\/]*$/', array($admin, 'controller', 'action'), array()); diff --git a/cake/libs/session.php b/cake/libs/session.php index 1877c553a..644c79976 100644 --- a/cake/libs/session.php +++ b/cake/libs/session.php @@ -2,9 +2,9 @@ /* SVN FILE: $Id$ */ /** - * Short description for file. + * Session class for Cake. * - * Long description for file + * Cake abstracts the handling of sessions. There are several convenient methods to access session information. This class is the implementation of those methods. They are mostly used by the Session Component. * * PHP versions 4 and 5 * @@ -29,9 +29,9 @@ */ /** - * Short description for file. + * Session class for Cake. * - * Long description for file + * Cake abstracts the handling of sessions. There are several convenient methods to access session information. This class is the implementation of those methods. They are mostly used by the Session Component. * * @package cake * @subpackage cake.cake.libs @@ -40,63 +40,64 @@ class CakeSession extends Object { /** - * Enter description here... + * True if the Session is still valid * - * @var unknown_type + * @var boolean */ var $valid = false; /** - * Enter description here... + * Error messages for this session * - * @var unknown_type + * @var array */ var $error = false; /** - * Enter description here... + * User agent string * - * @var unknown_type + * @var string */ var $userAgent = false; /** - * Enter description here... + * Path to where the session is active. * - * @var unknown_type + * @var string */ var $path = false; /** - * Enter description here... + * Error number of last occurred error * - * @var unknown_type + * @var integer */ var $lastError = null; /** * Enter description here... * * @var unknown_type + * @todo Is this still in use? OJ 30 jan 2006 */ var $sessionId = null; /** - * Enter description here... + * CAKE_SECURITY setting, "high", "medium", or "low". * - * @var unknown_type + * @var string */ var $security = null; /** - * Enter description here... + * Start time for this session. * - * @var unknown_type + * @var integer */ var $time = false; /** - * Enter description here... + * Time when this session becomes invalid. * - * @var unknown_type + * @var integer */ var $sessionTime = false; /** - * Enter description here... + * Constructor. * - * @return unknown + * @param string $base The base path for the Session */ function __construct($base = null) { @@ -128,16 +129,21 @@ class CakeSession extends Object $this->time = time(); $this->sessionTime = $this->time + (Security::inactiveMins() * CAKE_SESSION_TIMEOUT); $this->security = CAKE_SECURITY; - $this->_initSession(); - $this->_begin(); + + if (!isset($_SESSION)) + { + $this->_initSession(); + $this->_begin(); + + } parent::__construct(); } /** - * Enter description here... + * Returns true if given variable is set in session. * - * @param unknown_type $name - * @return unknown + * @param string $name Variable name to check for + * @return boolean True if variable is there */ function checkSessionVar($name) { @@ -146,10 +152,10 @@ class CakeSession extends Object } /** - * Enter description here... + * Removes a variable from session. * - * @param unknown_type $name - * @return unknown + * @param string $name Session variable to remove + * @return boolean Success */ function delSessionVar($name) { @@ -164,10 +170,10 @@ class CakeSession extends Object } /** - * Enter description here... + * Return error description for given error number. * - * @param unknown_type $errorNumber - * @return unknown + * @param int $errorNumber + * @return string Error as string */ function getError($errorNumber) { @@ -182,9 +188,9 @@ class CakeSession extends Object } /** - * Enter description here... + * Returns last occurred error as a string, if any. * - * @return unknown + * @return mixed Error description as a string, or false. */ function getLastError() { @@ -199,9 +205,9 @@ class CakeSession extends Object } /** - * Enter description here... + * Returns true if session is valid. * - * @return unknown + * @return boolean */ function isValid() { @@ -209,9 +215,9 @@ class CakeSession extends Object } /** - * Enter description here... + * Returns given session variable, or all of them, if no parameters given. * - * @param unknown_type $name + * @param mixed $name * @return unknown */ function readSessionVar($name = null) @@ -227,14 +233,14 @@ class CakeSession extends Object return $result; } $this->_setError(2, "$name doesn't exist"); - return false; + $return = null; + return $return; } /** - * Enter description here... + * Returns all session variables. * - * @param unknown_type $name - * @return unknown + * @return mixed Full $_SESSION array, or false on error. */ function returnSessionVars() { @@ -248,10 +254,10 @@ class CakeSession extends Object } /** - * Enter description here... + * Writes value to given session variable name. * - * @param unknown_type $name - * @param unknown_type $value + * @param mixed $name + * @param string $value */ function writeSessionVar($name, $value) { @@ -261,7 +267,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Begins a session. * * @access private */ @@ -273,7 +279,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Enter description here... To be implemented. * * @access private */ @@ -286,7 +292,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Enter description here... To be implemented. * * @access private */ @@ -298,7 +304,7 @@ class CakeSession extends Object die(); } /** - * Enter description here... + * Private helper method to destroy invalid sessions. * * @access private */ @@ -320,7 +326,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Enter description here... To be implemented. * * @access private */ @@ -333,7 +339,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Private helper method to initialize a session, based on Cake core settings. * * @access private */ @@ -415,7 +421,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Private helper method to create a new session. P3P headers are also sent. * * @access private * @@ -450,7 +456,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Enter description here... To be implemented. * * @access private * @@ -464,7 +470,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Enter description here... To be implemented. * * @access private * @@ -478,7 +484,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Private helper method to restart a session. * * * @access private @@ -506,9 +512,9 @@ class CakeSession extends Object } /** - * Enter description here... + * Restarts this session. * - * @access private + * @access public * */ function renew() @@ -517,10 +523,10 @@ class CakeSession extends Object } /** - * Enter description here... + * Private helper method to extract variable names. * - * @param unknown_type $name - * @return unknown + * @param mixed $name Variable names as array or string. + * @return string * @access private */ function _sessionVarNames($name) @@ -548,10 +554,10 @@ class CakeSession extends Object } /** - * Enter description here... + * Private helper method to set an internal error message. * - * @param unknown_type $errorNumber - * @param unknown_type $errorMessage + * @param int $errorNumber Number of the error + * @param string $errorMessage Description of the error * @access private */ function _setError($errorNumber, $errorMessage) @@ -566,7 +572,7 @@ class CakeSession extends Object } /** - * Enter description here... + * Enter description here... To be implemented. * * @access private */ diff --git a/cake/libs/view/helpers/ajax.php b/cake/libs/view/helpers/ajax.php index 760fe32b0..480fbf4ee 100644 --- a/cake/libs/view/helpers/ajax.php +++ b/cake/libs/view/helpers/ajax.php @@ -145,7 +145,7 @@ class AjaxHelper extends Helper * @param array $options Options for JavaScript function * @return string HTML code for link to remote action */ - function link($title, $href = null, $options = array(), $confirm = null) + function link($title, $href = null, $options = array(), $confirm = null, $escapeTitle = true) { if (!isset($href)) { @@ -176,7 +176,7 @@ class AjaxHelper extends Helper else { $htmlOptions['onclick'] = $this->remoteFunction($options) . '; return false;'; - return $this->Html->link($title, $href, $htmlOptions); + return $this->Html->link($title, $href, $htmlOptions, null, $escapeTitle); } } @@ -194,7 +194,7 @@ class AjaxHelper extends Helper } else { - $html_options['onclick'] = $this->remoteFunction($options); + $html_options['onclick'] = $this->remoteFunction($options) . "; return false;"; return $this->Html->link($title, $href, $html_options); } } diff --git a/cake/libs/view/helpers/form.php b/cake/libs/view/helpers/form.php index 8d241912c..9c9048262 100644 --- a/cake/libs/view/helpers/form.php +++ b/cake/libs/view/helpers/form.php @@ -140,8 +140,10 @@ class FormHelper extends Helper */ function generateInputDiv($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null ) { - $htmlOptions['id'] = strtolower(str_replace('/', '_',$tagName));; - $str = $this->Html->inputTag( $tagName, $size, $htmlOptions ); + $htmlOptions['id'] = strtolower(str_replace('/', '_',$tagName)); + $htmlAttributes = $htmlOptions; + $htmlAttributes['size'] = $size; + $str = $this->Html->input( $tagName, $htmlAttributes); $strLabel = $this->labelTag( $tagName, $prompt ); $divClass = "optional"; @@ -289,8 +291,11 @@ class FormHelper extends Helper */ function generateAreaDiv($tagName, $prompt, $required=false, $errorMsg=null, $cols=60, $rows=10, $htmlOptions=null ) { - $htmlOptions['id'] = strtolower(str_replace('/', '_',$tagName));; - $str = $this->Html->areaTag( $tagName, $cols, $rows, $htmlOptions ); + $htmlOptions['id'] = strtolower(str_replace('/', '_',$tagName)); + $htmlAttributes = $htmlOptions; + $htmlAttributes['cols'] = $cols; + $htmlAttributes['rows'] = $rows; + $str = $this->Html->textarea( $tagName, $htmlAttributes); $strLabel = $this->labelTag( $tagName, $prompt ); $divClass = "optional"; diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index 065c4c376..bcfd020d4 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -335,7 +335,7 @@ class HtmlHelper extends Helper */ function css($path, $rel = 'stylesheet', $htmlAttributes = null, $return = false) { - $url = "{$this->webroot}".(COMPRESS_CSS? 'c': '').CSS_URL.$path.".css"; + $url = "{$this->webroot}".(COMPRESS_CSS? 'c': '').CSS_URL.$this->themeWeb.$path.".css"; return $this->output(sprintf($this->tags['css'], $rel, $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return); } @@ -420,7 +420,14 @@ class HtmlHelper extends Helper function image($path, $htmlAttributes = null, $return = false) { - $url = $this->webroot.IMAGES_URL.$path; + if (strpos($path, '://')) + { + $url = $path; + } + else + { + $url = $this->webroot.IMAGES_URL.$this->themeWeb.$path; + } return $this->output(sprintf($this->tags['image'], $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return); } @@ -1019,7 +1026,7 @@ class HtmlHelper extends Helper foreach ($option_elements as $name=>$title) { $options_here = $optionAttr; - if (!empty($selected) && ($selected == $name)) + if (($selected !== null) && ($selected == $name)) { $options_here['selected'] = 'selected'; } else if ( is_array($selected) && array_key_exists($name, $selected) ) diff --git a/cake/libs/view/helpers/javascript.php b/cake/libs/view/helpers/javascript.php index c758ed4d9..3c60154bd 100644 --- a/cake/libs/view/helpers/javascript.php +++ b/cake/libs/view/helpers/javascript.php @@ -63,7 +63,7 @@ class JavascriptHelper extends Helper function link($url) { if(strpos($url, ".") === false) $url .= ".js"; - return sprintf($this->tags['javascriptlink'], $this->webroot . JS_URL . $url); + return sprintf($this->tags['javascriptlink'], $this->webroot.JS_URL.$this->themeWeb.$url); } /** diff --git a/cake/libs/view/helpers/text.php b/cake/libs/view/helpers/text.php index d27343ea3..7fc7df9a2 100644 --- a/cake/libs/view/helpers/text.php +++ b/cake/libs/view/helpers/text.php @@ -115,7 +115,7 @@ class TextHelper extends Helper '#((?:http|https|ftp|nntp)://[^ ]+)#', create_function( '$matches', - '$Html = new HtmlHelper(); return $Html->linkOut($matches[0], $matches[0],' . $options . ');' + '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->linkOut($matches[0], $matches[0],' . $options . ');' ), $text ); @@ -123,7 +123,7 @@ class TextHelper extends Helper '#(?linkOut($matches[0], "http://" . $matches[0],' . $options . ');' + '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->linkOut($matches[0], "http://" . $matches[0],' . $options . ');' ), $text ); @@ -149,7 +149,7 @@ class TextHelper extends Helper '#([_A-Za-z0-9+-+]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#', create_function( '$matches', - '$Html = new HtmlHelper(); return $Html->linkEmail($matches[0], $matches[0],' . $options . ');' + '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->linkEmail($matches[0], $matches[0],' . $options . ');' ), $text ); diff --git a/cake/libs/view/helpers/time.php b/cake/libs/view/helpers/time.php index 0d6fc9581..bae33c4cd 100644 --- a/cake/libs/view/helpers/time.php +++ b/cake/libs/view/helpers/time.php @@ -287,11 +287,13 @@ class TimeHelper extends Helper * like 'Posted ' before the function output. * * @param string $date_string Datetime string or Unix timestamp + * @param string $format Default format if timestamp is used + * @param string $backwards False if $date_string is in the past, true if in the future * @param boolean $return Whether this method should return a value * or output it. This overrides AUTO_OUTPUT. * @return string Relative time string. */ - function timeAgoInWords ($datetime_string, $return = false, $backwards = false) + function timeAgoInWords ($datetime_string, $format = 'j/n/y', $backwards = false, $return = false) { $datetime = $this->fromString($datetime_string); @@ -319,7 +321,7 @@ class TimeHelper extends Helper if ($months>0) { // over a month old, just show date (mm/dd/yyyy format) - $relative_date = 'on '.date("j/n/Y", $in_seconds); + $relative_date = 'on '.date($format, $in_seconds); $old = true; } else @@ -373,17 +375,17 @@ class TimeHelper extends Helper * or output it. This overrides AUTO_OUTPUT. * @return string Relative time string. */ - function relativeTime ($datetime_string, $return = false) + function relativeTime ($datetime_string, $format = 'j/n/y', $return = false) { $date = strtotime($datetime_string); if(strtotime("now") > $date) { - $ret = $this->timeAgoInWords($datetime_string); + $ret = $this->timeAgoInWords($datetime_string, $format, false); } else { - $ret = $this->timeAgoInWords($datetime_string, $return, true); + $ret = $this->timeAgoInWords($datetime_string, $format, true); } return $this->output($ret, $return); diff --git a/cake/libs/view/templates/errors/missing_model.thtml b/cake/libs/view/templates/errors/missing_model.thtml new file mode 100644 index 000000000..7881bb083 --- /dev/null +++ b/cake/libs/view/templates/errors/missing_model.thtml @@ -0,0 +1,37 @@ + + * Copyright (c) 2006, Cake Software Foundation, Inc. + * 1785 E. Sahara Avenue, Suite 490-204 + * Las Vegas, Nevada 89104 + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright (c) 2006, Cake Software Foundation, Inc. + * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project + * @package cake + * @subpackage cake.cake.libs.view.templates.errors + * @since CakePHP v 0.10.0.1076 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/mit-license.php The MIT License + */ +?> +

Missing Model

+ +

No class found for the model

+ +

Notice: this error is being rendered by the +app/views/errors/missing_model.thtml view file, a user-customizable error page. +

\ No newline at end of file diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index d472abf39..14877d9d3 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -194,6 +194,20 @@ class View extends Object */ var $subDir = null; +/** + * Enter description here... + * + * @var array + */ + var $themeWeb = null; + +/** + * Enter description here... + * + * @var array + */ + var $plugin = null; + /** * Constructor * @@ -220,6 +234,7 @@ class View extends Object $this->data =& $this->controller->data; $this->displayFields =& $this->controller->displayFields; $this->webservices =& $this->controller->webservices; + $this->plugin =& $this->controller->plugin; parent::__construct(); } @@ -260,6 +275,11 @@ class View extends Object $viewFileName = $this->_getViewFileName($action); } + if(!is_null($this->plugin) && is_null($file)) + { + return $this->pluginView($action, $layout); + } + if (!is_file($viewFileName)) { if (strtolower(get_class($this)) == 'template') @@ -632,7 +652,12 @@ class View extends Object if(!class_exists($helperCn)) { $helperFn = Inflector::underscore($helper).'.php'; - if(file_exists(HELPERS.$helperFn)) + + if(file_exists(APP.'plugins'.DS.$this->plugin.'views'.DS.'helpers'.DS.$helperFn)) + { + $helperFn = APP.'plugins'.DS.$this->plugin.'views'.DS.'helpers'.DS.$helperFn; + } + else if(file_exists(HELPERS.$helperFn)) { $helperFn = HELPERS.$helperFn; } @@ -664,6 +689,7 @@ class View extends Object ${$camelBackedHelper}->params = $this->params; ${$camelBackedHelper}->action = $this->action; ${$camelBackedHelper}->data = $this->data; + ${$camelBackedHelper}->themeWeb = $this->themeWeb; ${$camelBackedHelper}->tags = $tags; if(!empty($this->validationErrors)) @@ -686,6 +712,21 @@ class View extends Object } return $loaded; } -} + function pluginView($action, $layout) + { + $viewFileName = APP.'plugins'.DS.$this->plugin.'views'.DS.$this->viewPath.DS.$action.$this->ext; + if(file_exists($viewFileName)) + { + $this->render($action, $layout, $viewFileName); + } + else + { + return $this->cakeError('missingView', + array(array('className' => $this->controller->name, + 'action' => $action, + 'file' => $viewFileName))); + } + } +} ?> \ No newline at end of file