diff --git a/app/config/acl.ini.php b/app/config/acl.ini.php index 84fce6d91..0907fbd4d 100644 --- a/app/config/acl.ini.php +++ b/app/config/acl.ini.php @@ -1,7 +1,7 @@ ; ; SVN FILE: $Id$ ;/** -; * Short description for file. +; * ACL configuration ; * ; * ; * PHP versions 4 and 5 diff --git a/app/config/routes.php b/app/config/routes.php index 3fca7f1bd..a186e49b4 100644 --- a/app/config/routes.php +++ b/app/config/routes.php @@ -1,6 +1,6 @@ dispatch(); } - if (Configure::read() > 0) { - echo ""; - } diff --git a/cake/VERSION.txt b/cake/VERSION.txt index 4276a6cf6..5f08ec3dc 100644 --- a/cake/VERSION.txt +++ b/cake/VERSION.txt @@ -18,5 +18,5 @@ // @license MIT License (http://www.opensource.org/licenses/mit-license.php) // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -1.3.0 +1.3.2 diff --git a/cake/config/config.php b/cake/config/config.php index d01327da1..65dd5a77c 100644 --- a/cake/config/config.php +++ b/cake/config/config.php @@ -17,4 +17,4 @@ * @since CakePHP(tm) v 1.1.11.4062 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -return $config['Cake.version'] = '1.3.0'; +return $config['Cake.version'] = '1.3.2'; diff --git a/cake/config/paths.php b/cake/config/paths.php index f15d3a4f2..a6e5c7c5c 100644 --- a/cake/config/paths.php +++ b/cake/config/paths.php @@ -1,6 +1,6 @@ __paths as $path) { $Folder = new Folder($path); $files = $Folder->findRecursive('.*\.(php|ctp|thtml|inc|tpl)', true); - $this->__files += $files; + $this->__files = array_merge($this->__files, $files); } } } diff --git a/cake/console/libs/tasks/template.php b/cake/console/libs/tasks/template.php index 875eb9bf7..7a93c0f48 100644 --- a/cake/console/libs/tasks/template.php +++ b/cake/console/libs/tasks/template.php @@ -54,7 +54,8 @@ class TemplateTask extends Shell { protected function _findThemes() { $paths = App::path('shells'); $core = array_pop($paths); - $core = preg_replace('#libs' . DS . '$#', '', $core); + $separator = DS === '/' ? '/' : '\\\\'; + $core = preg_replace('#libs' . $separator . '$#', '', $core); $paths[] = $core; $Folder =& new Folder($core . 'templates' . DS . 'default'); $contents = $Folder->read(); diff --git a/cake/console/templates/skel/app_controller.php b/cake/console/templates/skel/app_controller.php index a1f50257d..c9f09fca0 100644 --- a/cake/console/templates/skel/app_controller.php +++ b/cake/console/templates/skel/app_controller.php @@ -1,6 +1,6 @@ ; SVN FILE: $Id$ ;/** -; * Short description for file. +; * ACL Configuration ; * ; * ; * PHP versions 4 and 5 diff --git a/cake/console/templates/skel/config/routes.php b/cake/console/templates/skel/config/routes.php index 696c49a87..9e4a28c14 100644 --- a/cake/console/templates/skel/config/routes.php +++ b/cake/console/templates/skel/config/routes.php @@ -1,6 +1,6 @@ dispatch(); } - if (Configure::read() > 0) { - echo ""; - } diff --git a/cake/dispatcher.php b/cake/dispatcher.php index 819b3aa96..5fb872c64 100644 --- a/cake/dispatcher.php +++ b/cake/dispatcher.php @@ -161,7 +161,7 @@ class Dispatcher extends Object { } else { $controller->data = null; } - if (array_key_exists('return', $this->params) && $this->params['return'] == 1) { + if (isset($this->params['return']) && $this->params['return'] == 1) { $controller->autoRender = false; } if (!empty($this->params['bare'])) { diff --git a/cake/libs/cache/file.php b/cake/libs/cache/file.php index 9f6ea8a97..69d9bf5fb 100644 --- a/cake/libs/cache/file.php +++ b/cake/libs/cache/file.php @@ -210,7 +210,11 @@ class FileEngine extends CacheEngine { $now = time(); $threshold = $now - $this->settings['duration']; } + $prefixLength = strlen($this->settings['prefix']); while (($entry = $dir->read()) !== false) { + if (substr($entry, 0, $prefixLength) !== $this->settings['prefix']) { + continue; + } if ($this->_setKey($entry) === false) { continue; } diff --git a/cake/libs/cake_log.php b/cake/libs/cake_log.php index 6511781b4..a119373c3 100644 --- a/cake/libs/cake_log.php +++ b/cake/libs/cake_log.php @@ -95,7 +95,7 @@ class CakeLog { * * For an explaination of these parameters, see CakeLog::write() * - * @param string $key The keyname for this logger, used to revmoe the logger later. + * @param string $key The keyname for this logger, used to remove the logger later. * @param array $config Array of configuration information for the logger * @return boolean success of configuration. * @throws Exception diff --git a/cake/libs/cake_session.php b/cake/libs/cake_session.php index f3a6d31fe..7bac0a34f 100644 --- a/cake/libs/cake_session.php +++ b/cake/libs/cake_session.php @@ -114,14 +114,6 @@ class CakeSession extends Object { */ public $id = null; -/** - * Session Started - * - * @var boolean - * @access protected - */ - protected $_started = false; - /** * Hostname * @@ -136,7 +128,7 @@ class CakeSession extends Object { * @var ineteger * @access public */ - var $timeout = null; + public $timeout = null; /** * Constructor. @@ -214,7 +206,7 @@ class CakeSession extends Object { session_write_close(); } $this->__initSession(); - $this->_started = $this->__startSession(); + $this->__startSession(); return $this->started(); } @@ -225,7 +217,7 @@ class CakeSession extends Object { * @return boolean True if session has been started. */ function started() { - if (isset($_SESSION) && $this->_started) { + if (isset($_SESSION) && session_id()) { return true; } return false; @@ -456,29 +448,13 @@ class CakeSession extends Object { */ function __initSession() { $iniSet = function_exists('ini_set'); - if ($iniSet && env('HTTPS')) { ini_set('session.cookie_secure', 1); } - - switch ($this->security) { - case 'high': - $this->cookieLifeTime = Configure::read('Session.timeout') * Security::inactiveMins(); - if ($iniSet) { - ini_set('session.referer_check', $this->host); - } - break; - case 'medium': - $this->cookieLifeTime = Configure::read('Session.timeout') * Security::inactiveMins(); - if ($iniSet) { - ini_set('session.referer_check', $this->host); - } - break; - case 'low': - default: - $this->cookieLifeTime = Configure::read('Session.timeout') * Security::inactiveMins(); - break; + if ($iniSet && ($this->security === 'high' || $this->security === 'medium')) { + ini_set('session.referer_check', $this->host); } + $this->cookieLifeTime = Configure::read('Session.timeout') * Security::inactiveMins(); switch (Configure::read('Session.save')) { case 'cake': @@ -781,5 +757,5 @@ class CakeSession extends Object { $return = $model->deleteAll(array($model->alias . ".expires <" => $expires), false, false); return $return; - } + } } diff --git a/cake/libs/controller/app_controller.php b/cake/libs/controller/app_controller.php index e2a8302c5..073c6405e 100644 --- a/cake/libs/controller/app_controller.php +++ b/cake/libs/controller/app_controller.php @@ -1,6 +1,6 @@ array( 'controller' => Inflector::underscore(Inflector::pluralize($model)), 'action' => 'login', - 'plugin' => $plugin, + 'plugin' => Inflector::underscore($plugin), ), 'sessionKey' => 'Auth.' . $model, 'logoutRedirect' => $this->loginAction, diff --git a/cake/libs/controller/components/cookie.php b/cake/libs/controller/components/cookie.php index b3ace3264..0629f2f27 100644 --- a/cake/libs/controller/components/cookie.php +++ b/cake/libs/controller/components/cookie.php @@ -1,6 +1,6 @@ 25, 'host' => 'localhost', 'timeout' => 30 - ); + public $smtpOptions = array(); /** * Placeholder for any errors that might happen with the @@ -355,7 +353,11 @@ class EmailComponent extends Object{ } } - $message = $this->_wrap($content); + if ($this->sendAs === 'text') { + $message = $this->_wrap($content); + } else { + $message = $this->_wrap($content, 998); + } if ($this->template === null) { $message = $this->_formatMessage($message); @@ -674,10 +676,11 @@ class EmailComponent extends Object{ * Wrap the message using EmailComponent::$lineLength * * @param string $message Message to wrap + * @param integer $lineLength Max length of line * @return array Wrapped message - * @access private + * @access protected */ - function _wrap($message) { + function _wrap($message, $lineLength = null) { $message = $this->_strip($message, true); $message = str_replace(array("\r\n","\r"), "\n", $message); $lines = explode("\n", $message); @@ -688,11 +691,15 @@ class EmailComponent extends Object{ $this->lineLength = $this->_lineLength; } + if (!$lineLength) { + $lineLength = $this->lineLength; + } + foreach ($lines as $line) { if (substr($line, 0, 1) == '.') { $line = '.' . $line; } - $formatted = array_merge($formatted, explode("\n", wordwrap($line, $this->lineLength, "\n", true))); + $formatted = array_merge($formatted, explode("\n", wordwrap($line, $lineLength, "\n", true))); } $formatted[] = ''; return $formatted; @@ -785,7 +792,14 @@ class EmailComponent extends Object{ function _smtp() { App::import('Core', array('CakeSocket')); - $this->__smtpConnection =& new CakeSocket(array_merge(array('protocol'=>'smtp'), $this->smtpOptions)); + $defaults = array( + 'host' => 'localhost', + 'port' => 25, + 'protocol' => 'smtp', + 'timeout' => 30 + ); + $this->smtpOptions = array_merge($defaults, $this->smtpOptions); + $this->__smtpConnection =& new CakeSocket($this->smtpOptions); if (!$this->__smtpConnection->connect()) { $this->smtpError = $this->__smtpConnection->lastError(); @@ -804,7 +818,7 @@ class EmailComponent extends Object{ $host = 'localhost'; } - if (!$this->_smtpSend("HELO {$host}", '250')) { + if (!$this->_smtpSend("EHLO {$host}", '250') && !$this->_smtpSend("HELO {$host}", '250')) { return false; } @@ -864,22 +878,34 @@ class EmailComponent extends Object{ } /** - * Private method for sending data to SMTP connection + * Protected method for sending data to SMTP connection * * @param string $data data to be sent to SMTP server * @param mixed $checkCode code to check for in server response, false to skip * @return bool Success - * @access private + * @access protected */ function _smtpSend($data, $checkCode = '250') { if (!is_null($data)) { $this->__smtpConnection->write($data . "\r\n"); } - if ($checkCode !== false) { - $response = $this->__smtpConnection->read(); + while ($checkCode !== false) { + $response = ''; + $startTime = time(); + while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->smtpOptions['timeout'])) { + $response .= $this->__smtpConnection->read(); + } + if (substr($response, -2) !== "\r\n") { + $this->smtpError = 'timeout'; + return false; + } + $response = end(explode("\r\n", rtrim($response, "\r\n"))); - if (preg_match('/^(' . $checkCode . ')/', $response, $code)) { - return $code[0]; + if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) { + if ($code[2] === '-') { + continue; + } + return $code[1]; } $this->smtpError = $response; return false; diff --git a/cake/libs/controller/components/request_handler.php b/cake/libs/controller/components/request_handler.php index 1edd08028..922831dd6 100644 --- a/cake/libs/controller/components/request_handler.php +++ b/cake/libs/controller/components/request_handler.php @@ -276,7 +276,7 @@ class RequestHandlerComponent extends Object { $msg = $statusCode[$code]; $controller->header("HTTP/1.1 {$code} {$msg}"); } - echo $this->requestAction($url, array('return')); + echo $this->requestAction($url, array('return', 'bare' => false)); $this->_stop(); } diff --git a/cake/libs/controller/components/security.php b/cake/libs/controller/components/security.php index 83360b49a..efb1d35db 100644 --- a/cake/libs/controller/components/security.php +++ b/cake/libs/controller/components/security.php @@ -1,6 +1,6 @@ {$object->alias}->set($object->data); - $errors = array_merge($errors, $this->{$object->alias}->invalidFields()); + if (isset($this->{$object->alias})) { + $object =& $this->{$object->alias}; + } + $object->set($object->data); + $errors = array_merge($errors, $object->invalidFields()); } return $this->validationErrors = (!empty($errors) ? $errors : false); diff --git a/cake/libs/controller/scaffold.php b/cake/libs/controller/scaffold.php index 2902cc4d8..46b79024b 100644 --- a/cake/libs/controller/scaffold.php +++ b/cake/libs/controller/scaffold.php @@ -542,11 +542,17 @@ if (!class_exists('ThemeView')) { App::import('View', 'Theme'); } +/** + * ScaffoldView provides specific view file loading features for scaffolded views. + * + * @package cake.libs.view + */ class ScaffoldView extends ThemeView { /** - * Override _getViewFileName + * Override _getViewFileName Appends special scaffolding views in. * + * @param string $name name of the view file to get. * @return string action */ protected function _getViewFileName($name = null) { diff --git a/cake/libs/file.php b/cake/libs/file.php index 90ac671bd..0337b8d3e 100644 --- a/cake/libs/file.php +++ b/cake/libs/file.php @@ -178,7 +178,6 @@ class File { while (!feof($this->handle)) { $data .= fgets($this->handle, 4096); } - $data = trim($data); if ($this->lock !== null) { flock($this->handle, LOCK_UN); @@ -186,7 +185,7 @@ class File { if ($bytes === false) { $this->close(); } - return $data; + return trim($data); } /** diff --git a/cake/libs/http_socket.php b/cake/libs/http_socket.php index 64117565c..0dda375db 100644 --- a/cake/libs/http_socket.php +++ b/cake/libs/http_socket.php @@ -957,7 +957,7 @@ class HttpSocket extends CakeSocket { foreach ($cookies as $name => $cookie) { $header[] = $name.'='.$this->_escapeToken($cookie['value'], array(';')); } - $header = $this->_buildHeader(array('Cookie' => $header), 'pragmatic'); + $header = $this->_buildHeader(array('Cookie' => implode('; ', $header)), 'pragmatic'); return $header; } diff --git a/cake/libs/i18n.php b/cake/libs/i18n.php index 7c31be2c9..dc29a6efe 100644 --- a/cake/libs/i18n.php +++ b/cake/libs/i18n.php @@ -1,6 +1,6 @@ '\1', '/(o)es$/i' => '\1', '/ouses$/' => 'ouse', - '/uses$/' => 'us', + '/([^a])uses$/' => '\1us', '/([m|l])ice$/i' => '\1ouse', '/(x|ch|ss|sh)es$/i' => '\1', '/(m)ovies$/i' => '\1\2ovie', @@ -367,7 +367,10 @@ class Inflector { } else { $_this->{$var}[$rule] = array_merge($pattern, $_this->{$var}[$rule]); } - unset($rules[$rule], $_this->{$var}['cache' . ucfirst($rule)], $_this->{$var}['merged'][$rule]); + unset($rules[$rule], $_this->{$var}['cache' . ucfirst($rule)]); + if (isset($_this->{$var}['merged'][$rule])) { + unset($_this->{$var}['merged'][$rule]); + } if ($type === 'plural') { $_this->_pluralized = $_this->_tableize = array(); } elseif ($type === 'singular') { diff --git a/cake/libs/l10n.php b/cake/libs/l10n.php index 0dfe8446e..08cde2707 100644 --- a/cake/libs/l10n.php +++ b/cake/libs/l10n.php @@ -1,6 +1,6 @@ AssocName, field3), or null for unbind all original translations + * @param object $model instance of model + * @param mixed $fields string with field, or array(field1, field2=>AssocName, field3), or null for + * unbind all original translations * @return bool */ function unbindTranslation(&$model, $fields = null) { diff --git a/cake/libs/model/cake_schema.php b/cake/libs/model/cake_schema.php index 43dede8e7..7033d219c 100644 --- a/cake/libs/model/cake_schema.php +++ b/cake/libs/model/cake_schema.php @@ -241,7 +241,6 @@ class CakeSchema extends Object { if (is_object($Object) && $Object->useTable !== false) { $Object->setDataSource($connection); $table = $db->fullTableName($Object, false); - if (in_array($table, $currentTables)) { $key = array_search($table, $currentTables); if (empty($tables[$table])) { @@ -258,7 +257,7 @@ class CakeSchema extends Object { if (is_object($Object->$class)) { $withTable = $db->fullTableName($Object->$class, false); if (in_array($withTable, $currentTables)) { - $key = array_search($table, $currentTables); + $key = array_search($withTable, $currentTables); $tables[$withTable] = $this->__columns($Object->$class); $tables[$withTable]['indexes'] = $db->index($Object->$class); $tables[$withTable]['tableParameters'] = $db->readTableParameters($withTable); @@ -444,7 +443,7 @@ class CakeSchema extends Object { $tables = array(); foreach ($new as $table => $fields) { if ($table == 'missing') { - break; + continue; } if (!array_key_exists($table, $old)) { $tables[$table]['add'] = $fields; diff --git a/cake/libs/model/connection_manager.php b/cake/libs/model/connection_manager.php index b4e5bde4a..3247742c4 100644 --- a/cake/libs/model/connection_manager.php +++ b/cake/libs/model/connection_manager.php @@ -272,9 +272,12 @@ class ConnectionManager extends Object { if ($plugin) { $filename = Inflector::underscore($classname); } else { - $filename = $config['datasource'] . '_source'; - $classname = Inflector::camelize(strtolower($filename)); + $filename = Inflector::underscore($config['datasource']); } + if (substr($filename, -7) != '_source') { + $filename .= '_source'; + } + $classname = Inflector::camelize(strtolower($filename)); } return compact('filename', 'classname', 'parent', 'plugin'); } diff --git a/cake/libs/model/datasources/datasource.php b/cake/libs/model/datasources/datasource.php index f260f01bf..6a85f99d4 100644 --- a/cake/libs/model/datasources/datasource.php +++ b/cake/libs/model/datasources/datasource.php @@ -91,7 +91,7 @@ class DataSource extends Object { public $endQuote = null; /** - * Enter description here... + * Result * * @var array * @access protected diff --git a/cake/libs/model/datasources/dbo/dbo_mssql.php b/cake/libs/model/datasources/dbo/dbo_mssql.php index 5f309592c..a19108a23 100644 --- a/cake/libs/model/datasources/dbo/dbo_mssql.php +++ b/cake/libs/model/datasources/dbo/dbo_mssql.php @@ -19,7 +19,7 @@ */ /** - * Short description for class. + * MS SQL layer for DBO * * Long description for class * diff --git a/cake/libs/model/datasources/dbo/dbo_mysql.php b/cake/libs/model/datasources/dbo/dbo_mysql.php index bbe5a8da4..abb42ba39 100644 --- a/cake/libs/model/datasources/dbo/dbo_mysql.php +++ b/cake/libs/model/datasources/dbo/dbo_mysql.php @@ -507,9 +507,9 @@ class DboMysqlBase extends DboSource { class DboMysql extends DboMysqlBase { /** - * Enter description here... + * Datasource description * - * @var unknown_type + * @var string */ public $description = "MySQL DBO Driver"; @@ -727,7 +727,7 @@ class DboMysql extends DboMysqlBase { while ($j < $numFields) { $column = mysql_fetch_field($results, $j); - if (!empty($column->table) && strpos($column->name, '__') === false) { + if (!empty($column->table) && strpos($column->name, $this->virtualFieldSeparator) === false) { $this->map[$index++] = array($column->table, $column->name); } else { $this->map[$index++] = array(0, $column->name); diff --git a/cake/libs/model/datasources/dbo/dbo_mysqli.php b/cake/libs/model/datasources/dbo/dbo_mysqli.php index bace2a61a..1bed94980 100644 --- a/cake/libs/model/datasources/dbo/dbo_mysqli.php +++ b/cake/libs/model/datasources/dbo/dbo_mysqli.php @@ -30,9 +30,9 @@ App::import('Datasource', 'DboMysql'); class DboMysqli extends DboMysqlBase { /** - * Enter description here... + * Datasource Description * - * @var unknown_type + * @var string */ public $description = "Mysqli DBO Driver"; diff --git a/cake/libs/model/datasources/dbo/dbo_oracle.php b/cake/libs/model/datasources/dbo/dbo_oracle.php index b5954af62..708c74250 100644 --- a/cake/libs/model/datasources/dbo/dbo_oracle.php +++ b/cake/libs/model/datasources/dbo/dbo_oracle.php @@ -19,7 +19,7 @@ */ /** - * Short description for class. + * Oracle layer for DBO. * * Long description for class * @@ -29,17 +29,17 @@ class DboOracle extends DboSource { /** - * Enter description here... + * Configuration options * - * @var unknown_type + * @var array * @access public */ public $config = array(); /** - * Enter description here... + * Alias * - * @var unknown_type + * @var string */ public $alias = ''; @@ -56,9 +56,9 @@ class DboOracle extends DboSource { private $__transactionStarted = false; /** - * Enter description here... + * Column definitions * - * @var unknown_type + * @var array * @access public */ public $columns = array( @@ -77,25 +77,25 @@ class DboOracle extends DboSource { 'inet' => array('name' => 'inet')); /** - * Enter description here... + * Connection object * - * @var unknown_type + * @var mixed * @access protected */ public $connection; /** - * Enter description here... + * Query limit * - * @var unknown_type + * @var int * @access protected */ protected $_limit = -1; /** - * Enter description here... + * Query offset * - * @var unknown_type + * @var int * @access protected */ protected $_offset = 0; @@ -109,25 +109,25 @@ class DboOracle extends DboSource { protected $_map; /** - * Enter description here... + * Current Row * - * @var unknown_type + * @var mixed * @access protected */ protected $_currentRow; /** - * Enter description here... + * Number of rows * - * @var unknown_type + * @var int * @access protected */ protected $_numRows; /** - * Enter description here... + * Query results * - * @var unknown_type + * @var mixed * @access protected */ protected $_results; @@ -372,9 +372,10 @@ class DboOracle extends DboSource { } /** - * Enter description here... + * Fetch result row * - * @return unknown + * @return array + * @access public */ public function fetchRow() { if ($this->_currentRow >= $this->_numRows) { @@ -435,10 +436,11 @@ class DboOracle extends DboSource { } /** - * Enter description here... + * Create trigger * - * @param unknown_type $table - * @return unknown + * @param string $table + * @return mixed + * @access public */ public function createTrigger($table) { $sql = "CREATE OR REPLACE TRIGGER pk_$table" . "_trigger BEFORE INSERT ON $table FOR EACH ROW BEGIN SELECT pk_$table.NEXTVAL INTO :NEW.ID FROM DUAL; END;"; diff --git a/cake/libs/model/datasources/dbo/dbo_sqlite.php b/cake/libs/model/datasources/dbo/dbo_sqlite.php index 5b15c248b..c3e5c766a 100644 --- a/cake/libs/model/datasources/dbo/dbo_sqlite.php +++ b/cake/libs/model/datasources/dbo/dbo_sqlite.php @@ -29,9 +29,9 @@ class DboSqlite extends DboSource { /** - * Enter description here... + * Datasource Description * - * @var unknown_type + * @var string */ public $description = "SQLite DBO Driver"; diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index eb3baab7c..c38a27270 100755 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -1,6 +1,6 @@ 'ROLLBACK' ); +/** + * Separator string for virtualField composition + * + * @var string + */ + public $virtualFieldSeparator = '__'; + /** * List of table engine specific parameters used on table creating * @@ -422,10 +429,10 @@ class DboSource extends DataSource { public function fetchVirtualField(&$result) { if (isset($result[0]) && is_array($result[0])) { foreach ($result[0] as $field => $value) { - if (strpos($field, '__') === false) { + if (strpos($field, $this->virtualFieldSeparator) === false) { continue; } - list($alias, $virtual) = explode('__', $field); + list($alias, $virtual) = explode($this->virtualFieldSeparator, $field); if (!ClassRegistry::isKeySet($alias)) { return; @@ -898,6 +905,7 @@ class DboSource extends DataSource { } if (!empty($ins)) { + $ins = array_unique($ins); $fetch = $this->fetchAssociated($model, $query, $ins); } @@ -929,10 +937,10 @@ class DboSource extends DataSource { } } if (!empty($ins)) { + $ins = array_unique($ins); if (count($ins) > 1) { $query = str_replace('{$__cakeID__$}', '(' .implode(', ', $ins) .')', $query); $query = str_replace('= (', 'IN (', $query); - $query = str_replace('= (', 'IN (', $query); } else { $query = str_replace('{$__cakeID__$}',$ins[0], $query); } @@ -1033,7 +1041,6 @@ class DboSource extends DataSource { $query = str_replace('{$__cakeID__$}', implode(', ', $ids), $query); if (count($ids) > 1) { $query = str_replace('= (', 'IN (', $query); - $query = str_replace('= (', 'IN (', $query); } return $this->fetchAll($query, $model->cacheQueries, $model->alias); } @@ -1865,7 +1872,7 @@ class DboSource extends DataSource { protected function _constructVirtualFields(&$model, $alias, $fields) { $virtual = array(); foreach ($fields as $field) { - $virtualField = $this->name("{$alias}__{$field}"); + $virtualField = $this->name($alias . $this->virtualFieldSeparator . $field); $expression = $this->__quoteFields($model->getVirtualField($field)); $virtual[] = '(' .$expression . ") {$this->alias} {$virtualField}"; } @@ -2132,7 +2139,7 @@ class DboSource extends DataSource { } } elseif (is_array($value) && !empty($value) && !$valueInsert) { $keys = array_keys($value); - if (array_keys($value) === array_values(array_keys($value))) { + if ($keys === array_values($keys)) { $count = count($value); if ($count === 1) { $data = $this->__quoteFields($key) . ' = ('; @@ -2362,6 +2369,9 @@ class DboSource extends DataSource { } } continue; + } elseif (is_object($key) && isset($key->type) && $key->type === 'expression') { + $result[] = $key->value; + continue; } if (preg_match('/\\x20(ASC|DESC).*/i', $key, $_dir)) { @@ -2369,17 +2379,17 @@ class DboSource extends DataSource { $key = preg_replace('/\\x20(ASC|DESC).*/i', '', $key); } + $key = trim($key); + + if (is_object($model) && $model->isVirtualField($key)) { + $key = '(' . $this->__quoteFields($model->getVirtualField($key)) . ')'; + } + if (strpos($key, '.')) { $key = preg_replace_callback('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', array(&$this, '__quoteMatchedField'), $key); } - - $key = trim($key); - if (!preg_match('/\s/', $key) && !strpos($key,'.')) { - if (is_object($model) && $model->isVirtualField($key)) { - $key = '('.$this->__quoteFields($model->getVirtualField($key)).')'; - } else { - $key = $this->name($key); - } + if (!preg_match('/\s/', $key) && !strpos($key, '.')) { + $key = $this->name($key); } $key .= ' ' . trim($dir); $result[] = $key; diff --git a/cake/libs/model/db_acl.php b/cake/libs/model/db_acl.php index 876ec6199..8324d6ede 100644 --- a/cake/libs/model/db_acl.php +++ b/cake/libs/model/db_acl.php @@ -26,7 +26,7 @@ App::import('Model', 'App'); /** - * Short description for file. + * ACL Node * * * @package cake diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index a3708856c..6ef8c5d4e 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -1602,7 +1602,6 @@ class Model extends Object { case ($options['validate'] === 'first'): $options['validate'] = true; $return = array(); - continue; break; default: if ($options['atomic']) { @@ -1616,6 +1615,10 @@ class Model extends Object { break; } } + if ($options['atomic'] && !$validates) { + $db->rollback($this); + return false; + } return $return; } $associations = $this->getAssociated(); diff --git a/cake/libs/model/model_behavior.php b/cake/libs/model/model_behavior.php index 1e4e75de7..17b353be7 100644 --- a/cake/libs/model/model_behavior.php +++ b/cake/libs/model/model_behavior.php @@ -80,7 +80,8 @@ class ModelBehavior extends Object { * * @param object $model Model using this behavior * @param array $queryData Data used to execute this query, i.e. conditions, order, etc. - * @return boolean True if the operation should continue, false if it should abort + * @return mixed False if the operation should abort. An array will replace the value of $query. + * @access public */ public function beforeFind(&$model, $query) { } @@ -90,7 +91,8 @@ class ModelBehavior extends Object { * @param object $model Model using this behavior * @param mixed $results The results of the find operation * @param boolean $primary Whether this model is being queried directly (vs. being queried as an association) - * @return mixed Result of the find operation + * @return mixed An array value will replace the value of $results - any other value will be ignored. + * @access public */ public function afterFind(&$model, $results, $primary) { } @@ -98,7 +100,8 @@ class ModelBehavior extends Object { * Before validate callback * * @param object $model Model using this behavior - * @return boolean True if validate operation should continue, false to abort + * @return mixed False if the operation should abort. Any other result will continue. + * @access public */ public function beforeValidate(&$model) { } @@ -106,7 +109,8 @@ class ModelBehavior extends Object { * Before save callback * * @param object $model Model using this behavior - * @return boolean True if the operation should continue, false if it should abort + * @return mixed False if the operation should abort. Any other result will continue. + * @access public */ public function beforeSave(&$model) { } @@ -123,7 +127,8 @@ class ModelBehavior extends Object { * * @param object $model Model using this behavior * @param boolean $cascade If true records that depend on this record will also be deleted - * @return boolean True if the operation should continue, false if it should abort + * @return mixed False if the operation should abort. Any other result will continue. + * @access public */ public function beforeDelete(&$model, $cascade = true) { } @@ -167,7 +172,7 @@ class ModelBehavior extends Object { case 5: return $this->{$method}($model, $params[0], $params[1], $params[2], $params[3], $params[4]); default: - array_unshift($params, $model); + $params = array_merge(array(&$model), $params); return call_user_func_array(array(&$this, $method), $params); break; } @@ -467,7 +472,6 @@ class BehaviorCollection extends Object { if (empty($this->_attached)) { return true; } - $_params = $params; $options = array_merge(array('break' => false, 'breakOn' => array(null, false), 'modParams' => false), $options); $count = count($this->_attached); diff --git a/cake/libs/security.php b/cake/libs/security.php index fdcc95911..7041eb68c 100644 --- a/cake/libs/security.php +++ b/cake/libs/security.php @@ -1,6 +1,6 @@ fields = array(); if (isset($this->params['_Token']) && !empty($this->params['_Token'])) { $append .= $this->hidden('_Token.key', array( 'value' => $this->params['_Token']['key'], 'id' => 'Token' . mt_rand()) @@ -680,9 +681,10 @@ class FormHelper extends AppHelper { * - `after` - Content to place after the label + input. * - `between` - Content to place between the label + input. * - `format` - format template for element order. Any element that is not in the array, will not be in the output. - * Default input format order: array('before', 'label', 'between', 'input', 'after', 'error') - * Default checkbox format order: array('before', 'input', 'between', 'label', 'after', 'error') - * Hidden input will not be formatted + * - Default input format order: array('before', 'label', 'between', 'input', 'after', 'error') + * - Default checkbox format order: array('before', 'input', 'between', 'label', 'after', 'error') + * - Hidden input will not be formatted + * - Radio buttons cannot have the order of input and label elements controlled with these settings. * * @param string $fieldName This should be "Modelname.fieldname" * @param array $options Each type of input takes different options. @@ -735,7 +737,7 @@ class FormHelper extends AppHelper { $options['type'] = 'hidden'; } } - if (preg_match('/_id$/', $fieldKey)) { + if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') { $options['type'] = 'select'; } diff --git a/cake/libs/view/helpers/number.php b/cake/libs/view/helpers/number.php index 4bb8f48ca..557d39398 100644 --- a/cake/libs/view/helpers/number.php +++ b/cake/libs/view/helpers/number.php @@ -69,7 +69,7 @@ class NumberHelper extends AppHelper { * * @param float $number A floating point number. * @param integer $precision The precision of the returned number. - * @return float Enter description here... + * @return float Formatted float. * @access public * @link http://book.cakephp.org/view/1454/precision */ diff --git a/cake/libs/view/helpers/text.php b/cake/libs/view/helpers/text.php index 327a403e3..f8d79b1ba 100644 --- a/cake/libs/view/helpers/text.php +++ b/cake/libs/view/helpers/text.php @@ -123,7 +123,7 @@ class TextHelper extends AppHelper { '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], $matches[0],' . $options . ');'), $text); return preg_replace_callback('#(?)(?tags = $Html->loadConfig(); return $Html->link($matches[0], "http://" . strtolower($matches[0]),' . $options . ');'), $text); + create_function('$matches', '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], "http://" . $matches[0],' . $options . ');'), $text); } /** diff --git a/cake/libs/view/pages/home.ctp b/cake/libs/view/pages/home.ctp index ef52db4d3..97c1dfecd 100644 --- a/cake/libs/view/pages/home.ctp +++ b/cake/libs/view/pages/home.ctp @@ -21,7 +21,7 @@ if (Configure::read() == 0): endif; ?>
- + 0): Debugger::checkSecurityKeys(); @@ -106,7 +106,7 @@ You can also add some CSS styles for your pages at: APP/webroot/css.');
Html->link(
- sprintf('%s%s', __('new'), __('CakePHP 1.3 Docs')),
+ sprintf('%s%s', __('new', true), __('CakePHP 1.3 Docs', true)),
'http://book.cakephp.org/view/875/x1-3-Collection',
array('target' => '_blank', 'escape' => false)
);
diff --git a/cake/libs/view/theme.php b/cake/libs/view/theme.php
index f161e2685..22a06f050 100644
--- a/cake/libs/view/theme.php
+++ b/cake/libs/view/theme.php
@@ -35,7 +35,8 @@ class ThemeView extends View {
/**
* Constructor for ThemeView sets $this->theme.
*
- * @param Controller $controller
+ * @param Controller $controller Controller object to be rendered.
+ * @param boolean $register Should the view be registered in the registry.
*/
function __construct(&$controller, $register = true) {
parent::__construct($controller, $register);
@@ -45,7 +46,7 @@ class ThemeView extends View {
/**
* Return all possible paths to find view files in order
*
- * @param string $plugin
+ * @param string $plugin The name of the plugin views are being found for.
* @param boolean $cached Set to true to force dir scan.
* @return array paths
* @access protected
diff --git a/cake/tests/cases/console/libs/tasks/extract.test.php b/cake/tests/cases/console/libs/tasks/extract.test.php
index 28d91c932..d5a6eaa96 100644
--- a/cake/tests/cases/console/libs/tasks/extract.test.php
+++ b/cake/tests/cases/console/libs/tasks/extract.test.php
@@ -152,4 +152,33 @@ class ExtractTaskTest extends CakeTestCase {
$Folder = new Folder($path);
$Folder->delete();
}
+ function getTests() {
+ return array('start', 'startCase', 'testExtractMultiplePaths', 'endCase', 'end');
+ }
+
+/**
+ * test extract can read more than one path.
+ *
+ * @return void
+ */
+ function testExtractMultiplePaths() {
+ $path = TMP . 'tests' . DS . 'extract_task_test';
+ new Folder($path . DS . 'locale', true);
+
+ $this->Task->interactive = false;
+
+ $this->Task->params['paths'] =
+ TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'pages,' .
+ TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'posts';
+
+ $this->Task->params['output'] = $path . DS;
+ $this->Task->Dispatch->expectNever('stderr');
+ $this->Task->Dispatch->expectNever('_stop');
+ $this->Task->execute();
+
+ $result = file_get_contents($path . DS . 'default.pot');
+
+ $pattern = '/msgid "Add User"/';
+ $this->assertPattern($pattern, $result);
+ }
}
diff --git a/cake/tests/cases/console/libs/tasks/model.test.php b/cake/tests/cases/console/libs/tasks/model.test.php
index 54af5ea98..8375d88df 100644
--- a/cake/tests/cases/console/libs/tasks/model.test.php
+++ b/cake/tests/cases/console/libs/tasks/model.test.php
@@ -627,8 +627,7 @@ array(
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
STRINGEND;
-
- $this->assertPattern('/' . preg_quote($expected, '/') . '/', $result);
+ $this->assertPattern('/' . preg_quote(str_replace("\r\n", "\n", $expected), '/') . '/', $result);
}
/**
diff --git a/cake/tests/cases/libs/cache/file.test.php b/cake/tests/cases/libs/cache/file.test.php
index 4f9abcc49..7ad0f156c 100644
--- a/cake/tests/cases/libs/cache/file.test.php
+++ b/cake/tests/cases/libs/cache/file.test.php
@@ -273,6 +273,34 @@ class FileEngineTest extends CakeTestCase {
Cache::config('default', array('engine' => 'File', 'path' => CACHE));
}
+/**
+ * test that clear() doesn't wipe files not in the current engine's prefix.
+ *
+ * @return void
+ */
+ function testClearWithPrefixes() {
+ $FileOne =& new FileEngine();
+ $FileOne->init(array(
+ 'prefix' => 'prefix_one_',
+ 'duration' => DAY
+ ));
+ $FileTwo =& new FileEngine();
+ $FileTwo->init(array(
+ 'prefix' => 'prefix_two_',
+ 'duration' => DAY
+ ));
+
+ $data1 = $data2 = $expected = 'content to cache';
+ $FileOne->write('key_one', $data1, DAY);
+ $FileTwo->write('key_two', $data2, DAY);
+
+ $this->assertEqual($FileOne->read('key_one'), $expected);
+ $this->assertEqual($FileTwo->read('key_two'), $expected);
+
+ $FileOne->clear(false);
+ $this->assertEqual($FileTwo->read('key_two'), $expected, 'secondary config was cleared by accident.');
+ }
+
/**
* testKeyPath method
*
diff --git a/cake/tests/cases/libs/cake_session.test.php b/cake/tests/cases/libs/cake_session.test.php
index 485f32a49..3b8910667 100644
--- a/cake/tests/cases/libs/cake_session.test.php
+++ b/cake/tests/cases/libs/cake_session.test.php
@@ -175,6 +175,10 @@ class CakeSessionTest extends CakeTestCase {
$_SESSION = null;
$this->assertFalse($this->Session->started());
$this->assertTrue($this->Session->start());
+
+ $session = new CakeSession(null, false);
+ $this->assertTrue($session->started());
+ unset($session);
}
/**
diff --git a/cake/tests/cases/libs/cake_test_fixture.test.php b/cake/tests/cases/libs/cake_test_fixture.test.php
index 72021f9bd..bff2c8e0c 100644
--- a/cake/tests/cases/libs/cake_test_fixture.test.php
+++ b/cake/tests/cases/libs/cake_test_fixture.test.php
@@ -114,6 +114,14 @@ class FixtureImportTestModel extends Model {
public $useTable = 'fixture_tests';
public $useDbConfig = 'test_suite';
}
+
+class FixturePrefixTest extends Model {
+ public $name = 'FixturePrefix';
+ public $useTable = '_tests';
+ public $tablePrefix = 'fixture';
+ public $useDbConfig = 'test_suite';
+}
+
Mock::generate('DboSource', 'FixtureMockDboSource');
/**
@@ -162,7 +170,14 @@ class CakeTestFixtureTest extends CakeTestCase {
$Fixture->primaryKey = 'my_random_key';
$Fixture->init();
$this->assertEqual($Fixture->primaryKey, 'my_random_key');
+ }
+/**
+ * test that init() correctly sets the fixture table when the connection or model have prefixes defined.
+ *
+ * @return void
+ */
+ function testInitDbPrefix() {
$this->_initDb();
$Source =& new CakeTestFixtureTestFixture();
$Source->create($this->db);
@@ -194,6 +209,30 @@ class CakeTestFixtureTest extends CakeTestCase {
$Source->drop($this->db);
}
+/**
+ * test init with a model that has a tablePrefix declared.
+ *
+ * @return void
+ */
+ function testInitModelTablePrefix() {
+ $this->_initDb();
+ $Source =& new CakeTestFixtureTestFixture();
+ $Source->create($this->db);
+ $Source->insert($this->db);
+
+ $Fixture =& new CakeTestFixtureImportFixture();
+ unset($Fixture->table);
+ $Fixture->fields = $Fixture->records = null;
+ $Fixture->import = array('model' => 'FixturePrefixTest', 'connection' => 'test_suite', 'records' => false);
+ $Fixture->init();
+ $this->assertEqual($Fixture->table, 'fixture_tests');
+
+ $keys = array_flip(ClassRegistry::keys());
+ $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys));
+
+ $Source->drop($this->db);
+ }
+
/**
* testImport
*
diff --git a/cake/tests/cases/libs/controller/components/auth.test.php b/cake/tests/cases/libs/controller/components/auth.test.php
index c28912b1b..311e8d634 100644
--- a/cake/tests/cases/libs/controller/components/auth.test.php
+++ b/cake/tests/cases/libs/controller/components/auth.test.php
@@ -1431,6 +1431,16 @@ class AuthTest extends CakeTestCase {
$this->assertEqual($user, $expected);
$sessionKey = $this->Controller->Auth->sessionKey;
$this->assertEqual('Auth.TestPluginAuthUser', $sessionKey);
+
+ $this->Controller->Auth->loginAction = null;
+ $this->Controller->Auth->__setDefaults();
+ $loginAction = $this->Controller->Auth->loginAction;
+ $expected = array(
+ 'controller' => 'test_plugin_auth_users',
+ 'action' => 'login',
+ 'plugin' => 'test_plugin'
+ );
+ $this->assertEqual($loginAction, $expected);
// Reverting changes
Cache::delete('object_map', '_cake_core_');
@@ -1456,7 +1466,7 @@ class AuthTest extends CakeTestCase {
$Dispatcher =& new Dispatcher();
$Dispatcher->dispatch('/ajax_auth/add', array('return' => 1));
$result = ob_get_clean();
- $this->assertEqual("Ajax!\nthis is the test element", $result);
+ $this->assertEqual("Ajax!\nthis is the test element", str_replace("\r\n", "\n", $result));
unset($_SERVER['HTTP_X_REQUESTED_WITH']);
}
diff --git a/cake/tests/cases/libs/controller/components/email.test.php b/cake/tests/cases/libs/controller/components/email.test.php
index 11eadb119..914df2c7d 100755
--- a/cake/tests/cases/libs/controller/components/email.test.php
+++ b/cake/tests/cases/libs/controller/components/email.test.php
@@ -109,6 +109,16 @@ class EmailTestComponent extends EmailComponent {
return $this->__message;
}
+/**
+ * Convenience getter for testing.
+ *
+ * @access protected
+ * @return string
+ */
+ function _getMessage() {
+ return $this->__message;
+ }
+
/**
* Convenience method for testing.
*
@@ -234,6 +244,30 @@ class EmailComponentTest extends CakeTestCase {
return str_replace(array("\r\n", "\r"), "\n", $string);
}
+/**
+ * testSmtpConfig method
+ *
+ * @access public
+ * @return void
+ */
+ function testSmtpConfig() {
+ $this->Controller->EmailTest->delivery = 'smtp';
+ $this->Controller->EmailTest->smtpOptions = array();
+ $this->Controller->EmailTest->send('anything');
+ $config = array(
+ 'host' => 'localhost',
+ 'port' => 25,
+ 'protocol' => 'smtp',
+ 'timeout' => 30
+ );
+ $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions);
+
+ $this->Controller->EmailTest->smtpOptions = array('port' => 80);
+ $this->Controller->EmailTest->send('anything');
+ $config['port'] = 80;
+ $this->assertEqual($config, $this->Controller->EmailTest->smtpOptions);
+ }
+
/**
* testBadSmtpSend method
*
@@ -295,6 +329,62 @@ TEMPDOC;
$this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect));
}
+/**
+ * testSmtpEhlo method
+ *
+ * @access public
+ * @return void
+ */
+ function testSmtpEhlo() {
+ if (!$this->skipIf(!@fsockopen('localhost', 25), '%s No SMTP server running on localhost')) {
+ return;
+ }
+
+ $connection =& new CakeSocket(array('protocol'=>'smtp', 'host' => 'localhost', 'port' => 25));
+ $this->Controller->EmailTest->setConnectionSocket($connection);
+ $this->Controller->EmailTest->smtpOptions['timeout'] = 10;
+ $this->assertTrue($connection->connect());
+ $this->assertTrue($this->Controller->EmailTest->smtpSend(null, '220') !== false);
+ $this->skipIf($this->Controller->EmailTest->smtpSend('EHLO locahost', '250') === false, '%s do not support EHLO.');
+ $connection->disconnect();
+
+ $this->Controller->EmailTest->to = 'postmaster@localhost';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake SMTP test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+
+ $this->Controller->EmailTest->delivery = 'smtp';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+
+ $this->Controller->EmailTest->_debug = true;
+ $this->Controller->EmailTest->sendAs = 'text';
+ $expect = <<