Merge branch '2.x' into 2.next

Conflicts:
	lib/Cake/Test/Case/View/Helper/FlashHelperTest.php
	lib/Cake/VERSION.txt
	lib/Cake/View/Helper/FlashHelper.php
This commit is contained in:
chinpei215 2017-03-25 17:12:28 +09:00
commit 31a1837c1d
32 changed files with 517 additions and 189 deletions

View file

@ -43,7 +43,8 @@ before_script:
- sh -c "if [ '$PHPCS' = '1' ]; then composer global require 'cakephp/cakephp-codesniffer:1.*'; fi" - sh -c "if [ '$PHPCS' = '1' ]; then composer global require 'cakephp/cakephp-codesniffer:1.*'; fi"
- sh -c "if [ '$PHPCS' = '1' ]; then ~/.composer/vendor/bin/phpcs --config-set installed_paths ~/.composer/vendor/cakephp/cakephp-codesniffer; fi" - sh -c "if [ '$PHPCS' = '1' ]; then ~/.composer/vendor/bin/phpcs --config-set installed_paths ~/.composer/vendor/cakephp/cakephp-codesniffer; fi"
- echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.0" ]] ; then print "yes" | pecl install apcu-5.1.3; else print "yes" | pecl install apcu-4.0.11; fi - if [[ ${TRAVIS_PHP_VERSION:0:1} == "7" ]] ; then echo "yes" | pecl install apcu-5.1.3 || true; fi
- if [[ ${TRAVIS_PHP_VERSION:0:1} == "5" ]] ; then echo "yes" | pecl install apcu-4.0.11 || true; fi
- echo -e "extension = apcu.so\napc.enable_cli=1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - echo -e "extension = apcu.so\napc.enable_cli=1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- phpenv rehash - phpenv rehash
- set +H - set +H

View file

@ -37,7 +37,7 @@ Help us keep CakePHP open and inclusive. Please read and follow our [Code of Con
* Core test cases should continue to pass. You can run tests locally or enable * Core test cases should continue to pass. You can run tests locally or enable
[travis-ci](https://travis-ci.org/) for your fork, so all tests and codesniffs [travis-ci](https://travis-ci.org/) for your fork, so all tests and codesniffs
will be executed. will be executed.
* Your work should apply the [CakePHP coding standards](http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html). * Your work should apply the [CakePHP coding standards](https://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html).
## Which branch to base the work ## Which branch to base the work
@ -54,7 +54,7 @@ Help us keep CakePHP open and inclusive. Please read and follow our [Code of Con
## Test cases and codesniffer ## Test cases and codesniffer
CakePHP tests requires [PHPUnit](http://www.phpunit.de/manual/current/en/installation.html) CakePHP tests requires [PHPUnit](https://phpunit.de/manual/current/en/installation.html)
3.7, version 4 is not compatible. To run the test cases locally use the following command: 3.7, version 4 is not compatible. To run the test cases locally use the following command:
./lib/Cake/Console/cake test core AllTests --stderr ./lib/Cake/Console/cake test core AllTests --stderr
@ -69,11 +69,11 @@ for the sniff and phpcs.
## Reporting a Security Issue ## Reporting a Security Issue
If you've found a security related issue in CakePHP, please don't open an issue in GitHub. Instead contact us at security@cakephp.org. For more information on how we handle security issues, [see the CakePHP Security Issue Process](http://book.cakephp.org/2.0/en/contributing/tickets.html#reporting-security-issues). If you've found a security related issue in CakePHP, please don't open an issue in GitHub. Instead contact us at security@cakephp.org. For more information on how we handle security issues, [see the CakePHP Security Issue Process](https://book.cakephp.org/2.0/en/contributing/tickets.html#reporting-security-issues).
# Additional Resources # Additional Resources
* [CakePHP coding standards](http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html) * [CakePHP coding standards](https://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html)
* [Existing issues](https://github.com/cakephp/cakephp/issues) * [Existing issues](https://github.com/cakephp/cakephp/issues)
* [Development Roadmaps](https://github.com/cakephp/cakephp/wiki#roadmaps) * [Development Roadmaps](https://github.com/cakephp/cakephp/wiki#roadmaps)
* [General GitHub documentation](https://help.github.com/) * [General GitHub documentation](https://help.github.com/)

View file

@ -2,8 +2,8 @@
[![Latest Stable Version](https://poser.pugx.org/cakephp/cakephp/v/stable.svg)](https://packagist.org/packages/cakephp/cakephp) [![Latest Stable Version](https://poser.pugx.org/cakephp/cakephp/v/stable.svg)](https://packagist.org/packages/cakephp/cakephp)
[![License](https://poser.pugx.org/cakephp/cakephp/license.svg)](https://packagist.org/packages/cakephp/cakephp) [![License](https://poser.pugx.org/cakephp/cakephp/license.svg)](https://packagist.org/packages/cakephp/cakephp)
[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp) [![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](https://travis-ci.org/cakephp/cakephp)
[![Code consistency](http://squizlabs.github.io/PHP_CodeSniffer/analysis/cakephp/cakephp/grade.svg)](http://squizlabs.github.io/PHP_CodeSniffer/analysis/cakephp/cakephp/) [![Code consistency](https://squizlabs.github.io/PHP_CodeSniffer/analysis/cakephp/cakephp/grade.svg)](https://squizlabs.github.io/PHP_CodeSniffer/analysis/cakephp/cakephp/)
CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC. CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.
Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility. Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.
@ -11,28 +11,28 @@ Our primary goal is to provide a structured framework that enables PHP users at
## Some Handy Links ## Some Handy Links
[CakePHP](http://www.cakephp.org) - The rapid development PHP framework [CakePHP](https://cakephp.org) - The rapid development PHP framework
[CookBook](http://book.cakephp.org) - THE CakePHP user documentation; start learning here! [CookBook](https://book.cakephp.org) - THE CakePHP user documentation; start learning here!
[API](http://api.cakephp.org) - A reference to CakePHP's classes [API](https://api.cakephp.org) - A reference to CakePHP's classes
[Plugins](http://plugins.cakephp.org/) - A repository of extensions to the framework [Plugins](https://plugins.cakephp.org) - A repository of extensions to the framework
[The Bakery](http://bakery.cakephp.org) - Tips, tutorials and articles [The Bakery](https://bakery.cakephp.org) - Tips, tutorials and articles
[Community Center](http://community.cakephp.org) - A source for everything community related [Community Center](https://community.cakephp.org) - A source for everything community related
[Training](http://training.cakephp.org) - Join a live session and get skilled with the framework [Training](https://training.cakephp.org) - Join a live session and get skilled with the framework
[CakeFest](http://cakefest.org) - Don't miss our annual CakePHP conference [CakeFest](https://cakefest.org) - Don't miss our annual CakePHP conference
[Cake Software Foundation](http://cakefoundation.org) - Promoting development related to CakePHP [Cake Software Foundation](https://cakefoundation.org) - Promoting development related to CakePHP
## Get Support! ## Get Support!
[#cakephp](http://webchat.freenode.net/?channels=#cakephp) on irc.freenode.net - Come chat with us, we have cake [#cakephp](https://webchat.freenode.net/?channels=#cakephp) on irc.freenode.net - Come chat with us, we have cake
[Google Group](https://groups.google.com/group/cake-php) - Community mailing list and forum [Google Group](https://groups.google.com/group/cake-php) - Community mailing list and forum
@ -45,4 +45,4 @@ Our primary goal is to provide a structured framework that enables PHP users at
[CONTRIBUTING.md](CONTRIBUTING.md) - Quick pointers for contributing to the CakePHP project [CONTRIBUTING.md](CONTRIBUTING.md) - Quick pointers for contributing to the CakePHP project
[CookBook "Contributing" Section (2.x)](http://book.cakephp.org/2.0/en/contributing.html) [(3.0)](http://book.cakephp.org/3.0/en/contributing.html) - Version-specific details about contributing to the project [CookBook "Contributing" Section (2.x)](https://book.cakephp.org/2.0/en/contributing.html) [(3.x)](https://book.cakephp.org/3.0/en/contributing.html) - Version-specific details about contributing to the project

View file

@ -40,7 +40,7 @@ class PagesController extends AppController {
/** /**
* Displays a view * Displays a view
* *
* @return void * @return \Cake\Network\Response|null
* @throws ForbiddenException When a directory traversal attempt. * @throws ForbiddenException When a directory traversal attempt.
* @throws NotFoundException When the view file could not be found * @throws NotFoundException When the view file could not be found
* or MissingViewException in debug mode. * or MissingViewException in debug mode.

View file

@ -3,7 +3,7 @@
"description": "CakePHP Application skeleton", "description": "CakePHP Application skeleton",
"type": "library", "type": "library",
"keywords": ["application", "cakephp"], "keywords": ["application", "cakephp"],
"homepage": "http://cakephp.org", "homepage": "https://cakephp.org",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@ -13,17 +13,17 @@
], ],
"support": { "support": {
"issues": "https://github.com/cakephp/cakephp/issues", "issues": "https://github.com/cakephp/cakephp/issues",
"forum": "http://stackoverflow.com/tags/cakephp", "forum": "https://stackoverflow.com/tags/cakephp",
"irc": "irc://irc.freenode.org/cakephp", "irc": "irc://irc.freenode.org/cakephp",
"source": "https://github.com/cakephp/cakephp" "source": "https://github.com/cakephp/cakephp"
}, },
"require": { "require": {
"php": ">=5.3.0", "php": ">=5.3.0",
"ext-mcrypt": "*" "ext-mcrypt": "*",
"cakephp/cakephp": "~2.9"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "3.7.*", "phpunit/phpunit": "3.7.*"
"cakephp/cakephp": "~2.9"
}, },
"suggest": { "suggest": {
"cakephp/cakephp-codesniffer": "Easily check code formatting against the CakePHP coding standards." "cakephp/cakephp-codesniffer": "Easily check code formatting against the CakePHP coding standards."

View file

@ -82,7 +82,7 @@ if (!defined('WWW_ROOT')) {
// For the built-in server // For the built-in server
if (PHP_SAPI === 'cli-server') { if (PHP_SAPI === 'cli-server') {
if ($_SERVER['REQUEST_URI'] !== '/' && file_exists(WWW_ROOT . $_SERVER['PHP_SELF'])) { if ($_SERVER['PHP_SELF'] !== '/' . basename(__FILE__) && file_exists(WWW_ROOT . $_SERVER['PHP_SELF'])) {
return false; return false;
} }
$_SERVER['PHP_SELF'] = '/' . basename(__FILE__); $_SERVER['PHP_SELF'] = '/' . basename(__FILE__);

View file

@ -3,7 +3,7 @@
"description": "The CakePHP framework", "description": "The CakePHP framework",
"type": "library", "type": "library",
"keywords": ["framework"], "keywords": ["framework"],
"homepage": "http://cakephp.org", "homepage": "https://cakephp.org",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@ -13,7 +13,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/cakephp/cakephp/issues", "issues": "https://github.com/cakephp/cakephp/issues",
"forum": "http://stackoverflow.com/tags/cakephp", "forum": "https://stackoverflow.com/tags/cakephp",
"irc": "irc://irc.freenode.org/cakephp", "irc": "irc://irc.freenode.org/cakephp",
"source": "https://github.com/cakephp/cakephp" "source": "https://github.com/cakephp/cakephp"
}, },

View file

@ -64,7 +64,7 @@ class TaskCollection extends ObjectCollection {
* *
* @param string $task Task name to load * @param string $task Task name to load
* @param array $settings Settings for the task. * @param array $settings Settings for the task.
* @return Task A task object, Either the existing loaded task or a new one. * @return AppShell A task object, Either the existing loaded task or a new one.
* @throws MissingTaskException when the task could not be found * @throws MissingTaskException when the task could not be found
*/ */
public function load($task, $settings = array()) { public function load($task, $settings = array()) {

View file

@ -645,6 +645,7 @@ class AuthComponent extends Component {
foreach ($this->_authenticateObjects as $auth) { foreach ($this->_authenticateObjects as $auth) {
$auth->logout($user); $auth->logout($user);
} }
static::$_user = array();
$this->Session->delete(static::$sessionKey); $this->Session->delete(static::$sessionKey);
$this->Session->delete('Auth.redirect'); $this->Session->delete('Auth.redirect');
$this->Session->renew(); $this->Session->renew();

View file

@ -309,6 +309,7 @@ class L10n {
'ro-ro' => array('language' => 'Romanian (Romania)', 'locale' => 'ro_ro', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ro-ro' => array('language' => 'Romanian (Romania)', 'locale' => 'ro_ro', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ru' => array('language' => 'Russian', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ru' => array('language' => 'Russian', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ru-mo' => array('language' => 'Russian (Moldavia)', 'locale' => 'ru_mo', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ru-mo' => array('language' => 'Russian (Moldavia)', 'locale' => 'ru_mo', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ru-ru' => array('language' => 'Russian (Russia)', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sb' => array('language' => 'Sorbian', 'locale' => 'wen', 'localeFallback' => 'wen', 'charset' => 'utf-8', 'direction' => 'ltr'), 'sb' => array('language' => 'Sorbian', 'locale' => 'wen', 'localeFallback' => 'wen', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sk' => array('language' => 'Slovak', 'locale' => 'slk', 'localeFallback' => 'slk', 'charset' => 'utf-8', 'direction' => 'ltr'), 'sk' => array('language' => 'Slovak', 'locale' => 'slk', 'localeFallback' => 'slk', 'charset' => 'utf-8', 'direction' => 'ltr'),
'sl' => array('language' => 'Slovenian', 'locale' => 'slv', 'localeFallback' => 'slv', 'charset' => 'utf-8', 'direction' => 'ltr'), 'sl' => array('language' => 'Slovenian', 'locale' => 'slv', 'localeFallback' => 'slv', 'charset' => 'utf-8', 'direction' => 'ltr'),

View file

@ -223,7 +223,7 @@ class CakeRequest implements ArrayAccess {
unset($query[$unsetUrl]); unset($query[$unsetUrl]);
unset($query[$this->base . $unsetUrl]); unset($query[$this->base . $unsetUrl]);
if (strpos($this->url, '?') !== false) { if (strpos($this->url, '?') !== false) {
list(, $querystr) = explode('?', $this->url); list($this->url, $querystr) = explode('?', $this->url);
parse_str($querystr, $queryArgs); parse_str($querystr, $queryArgs);
$query += $queryArgs; $query += $queryArgs;
} }
@ -1006,7 +1006,7 @@ class CakeRequest implements ArrayAccess {
* @param string $callback A decoding callback that will convert the string data to another * @param string $callback A decoding callback that will convert the string data to another
* representation. Leave empty to access the raw input data. You can also * representation. Leave empty to access the raw input data. You can also
* supply additional parameters for the decoding callback using var args, see above. * supply additional parameters for the decoding callback using var args, see above.
* @return The decoded/processed request data. * @return mixed The decoded/processed request data.
*/ */
public function input($callback = null) { public function input($callback = null) {
$input = $this->_readInput(); $input = $this->_readInput();

View file

@ -806,8 +806,8 @@ class CakeResponse {
/** /**
* Sets the correct headers to instruct the client to cache the response. * Sets the correct headers to instruct the client to cache the response.
* *
* @param string $since a valid time since the response text has not been modified * @param string|int $since a valid time since the response text has not been modified
* @param string $time a valid time for cache expiry * @param string|int $time a valid time for cache expiry
* @return void * @return void
*/ */
public function cache($since, $time = '+1 day') { public function cache($since, $time = '+1 day') {
@ -1067,7 +1067,7 @@ class CakeResponse {
* Returns a DateTime object initialized at the $time param and using UTC * Returns a DateTime object initialized at the $time param and using UTC
* as timezone * as timezone
* *
* @param string|DateTime $time Valid time string or unix timestamp or DateTime object. * @param DateTime|int|string $time Valid time string or unix timestamp or DateTime object.
* @return DateTime * @return DateTime
*/ */
protected function _getUTCDate($time = null) { protected function _getUTCDate($time = null) {

View file

@ -72,12 +72,12 @@ class MailTransport extends AbstractTransport {
//@codingStandardsIgnoreStart //@codingStandardsIgnoreStart
if (!@mail($to, $subject, $message, $headers)) { if (!@mail($to, $subject, $message, $headers)) {
$error = error_get_last(); $error = error_get_last();
$msg = 'Could not send email: ' . isset($error['message']) ? $error['message'] : 'unknown'; $msg = 'Could not send email: ' . (isset($error['message']) ? $error['message'] : 'unknown');
throw new SocketException($msg); throw new SocketException($msg);
} }
} elseif (!@mail($to, $subject, $message, $headers, $params)) { } elseif (!@mail($to, $subject, $message, $headers, $params)) {
$error = error_get_last(); $error = error_get_last();
$msg = 'Could not send email: ' . isset($error['message']) ? $error['message'] : 'unknown'; $msg = 'Could not send email: ' . (isset($error['message']) ? $error['message'] : 'unknown');
//@codingStandardsIgnoreEnd //@codingStandardsIgnoreEnd
throw new SocketException($msg); throw new SocketException($msg);
} }

View file

@ -352,7 +352,11 @@ class SmtpTransport extends AbstractTransport {
$response = ''; $response = '';
$startTime = time(); $startTime = time();
while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->_config['timeout'])) { while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->_config['timeout'])) {
$response .= $this->_socket->read(); $bytes = $this->_socket->read();
if ($bytes === false || $bytes === null) {
break;
}
$response .= $bytes;
} }
if (substr($response, -2) !== "\r\n") { if (substr($response, -2) !== "\r\n") {
throw new SocketException(__d('cake_dev', 'SMTP timeout.')); throw new SocketException(__d('cake_dev', 'SMTP timeout.'));

View file

@ -1087,6 +1087,40 @@ class Router {
return $out; return $out;
} }
/**
* Reverses a parsed parameter array into an array.
*
* Works similarly to Router::url(), but since parsed URL's contain additional
* 'pass' and 'named' as well as 'url.url' keys. Those keys need to be specially
* handled in order to reverse a params array into a string URL.
*
* This will strip out 'autoRender', 'bare', 'requested', and 'return' param names as those
* are used for CakePHP internals and should not normally be part of an output URL.
*
* @param CakeRequest|array $params The params array or CakeRequest object that needs to be reversed.
* @return array The URL array ready to be used for redirect or HTML link.
*/
public static function reverseToArray($params) {
if ($params instanceof CakeRequest) {
$url = $params->query;
$params = $params->params;
} else {
$url = $params['url'];
}
$pass = isset($params['pass']) ? $params['pass'] : array();
$named = isset($params['named']) ? $params['named'] : array();
unset(
$params['pass'], $params['named'], $params['paging'], $params['models'], $params['url'], $url['url'],
$params['autoRender'], $params['bare'], $params['requested'], $params['return'],
$params['_Token']
);
$params = array_merge($params, $pass, $named);
if (!empty($url)) {
$params['?'] = $url;
}
return $params;
}
/** /**
* Reverses a parsed parameter array into a string. * Reverses a parsed parameter array into a string.
* *
@ -1103,24 +1137,7 @@ class Router {
* @return string The string that is the reversed result of the array * @return string The string that is the reversed result of the array
*/ */
public static function reverse($params, $full = false) { public static function reverse($params, $full = false) {
if ($params instanceof CakeRequest) { $params = Router::reverseToArray($params, $full);
$url = $params->query;
$params = $params->params;
} else {
$url = $params['url'];
}
$pass = isset($params['pass']) ? $params['pass'] : array();
$named = isset($params['named']) ? $params['named'] : array();
unset(
$params['pass'], $params['named'], $params['paging'], $params['models'], $params['url'], $url['url'],
$params['autoRender'], $params['bare'], $params['requested'], $params['return'],
$params['_Token']
);
$params = array_merge($params, $pass, $named);
if (!empty($url)) {
$params['?'] = $url;
}
return Router::url($params, $full); return Router::url($params, $full);
} }

View file

@ -315,7 +315,7 @@ class ModelTaskTest extends CakeTestCase {
$this->Task->initValidations(); $this->Task->initValidations();
$this->Task->interactive = true; $this->Task->interactive = true;
$this->Task->expects($this->any())->method('in') $this->Task->expects($this->any())->method('in')
->will($this->onConsecutiveCalls('24', 'y', '18', 'n')); ->will($this->onConsecutiveCalls('26', 'y', '18', 'n'));
$result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false)); $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
$expected = array('notBlank' => 'notBlank', 'maxLength' => 'maxLength'); $expected = array('notBlank' => 'notBlank', 'maxLength' => 'maxLength');
@ -333,7 +333,7 @@ class ModelTaskTest extends CakeTestCase {
$this->Task->interactive = true; $this->Task->interactive = true;
$this->Task->expects($this->any())->method('in') $this->Task->expects($this->any())->method('in')
->will($this->onConsecutiveCalls('999999', '24', 'n')); ->will($this->onConsecutiveCalls('999999', '26', 'n'));
$this->Task->expects($this->at(10))->method('out') $this->Task->expects($this->at(10))->method('out')
->with($this->stringContains('make a valid')); ->with($this->stringContains('make a valid'));
@ -368,7 +368,7 @@ class ModelTaskTest extends CakeTestCase {
$this->Task->initValidations(); $this->Task->initValidations();
$this->Task->interactive = true; $this->Task->interactive = true;
$this->Task->expects($this->any())->method('in') $this->Task->expects($this->any())->method('in')
->will($this->onConsecutiveCalls('24', 'y', 's')); ->will($this->onConsecutiveCalls('26', 'y', 's'));
$result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false)); $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
$expected = array('notBlank' => 'notBlank', '_skipFields' => true); $expected = array('notBlank' => 'notBlank', '_skipFields' => true);
@ -384,7 +384,7 @@ class ModelTaskTest extends CakeTestCase {
$this->Task->initValidations(); $this->Task->initValidations();
$this->Task->interactive = true; $this->Task->interactive = true;
$this->Task->expects($this->any())->method('in') $this->Task->expects($this->any())->method('in')
->will($this->onConsecutiveCalls('24', 's')); ->will($this->onConsecutiveCalls('26', 's'));
$result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false)); $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
$expected = array('notBlank' => 'notBlank', '_skipFields' => true); $expected = array('notBlank' => 'notBlank', '_skipFields' => true);
@ -400,7 +400,7 @@ class ModelTaskTest extends CakeTestCase {
public function testInteractiveDoValidationWithSkipping() { public function testInteractiveDoValidationWithSkipping() {
$this->Task->expects($this->any()) $this->Task->expects($this->any())
->method('in') ->method('in')
->will($this->onConsecutiveCalls('35', '24', 'n', '10', 's')); ->will($this->onConsecutiveCalls('37', '26', 'n', '10', 's'));
$this->Task->interactive = true; $this->Task->interactive = true;
$Model = $this->getMock('Model'); $Model = $this->getMock('Model');
$Model->primaryKey = 'id'; $Model->primaryKey = 'id';

View file

@ -1428,6 +1428,23 @@ class AuthComponentTest extends CakeTestCase {
$this->assertNull($this->Auth->Session->read('Auth.redirect')); $this->assertNull($this->Auth->Session->read('Auth.redirect'));
} }
/**
* test that logout removes the active user data as well for stateless auth
*
* @return void
*/
public function testLogoutRemoveUser() {
$oldKey = AuthComponent::$sessionKey;
AuthComponent::$sessionKey = false;
$this->Auth->login(array('id' => 1, 'username' => 'mariano'));
$this->assertSame('mariano', $this->Auth->user('username'));
$this->Auth->logout();
AuthComponent::$sessionKey = $oldKey;
$this->assertNull($this->Auth->user('username'));
}
/** /**
* Logout should trigger a logout method on authentication objects. * Logout should trigger a logout method on authentication objects.
* *

View file

@ -86,7 +86,7 @@ class RequestActionController extends Controller {
* @return string $this->here. * @return string $this->here.
*/ */
public function return_here() { public function return_here() {
return $this->here; return $this->request->here();
} }
/** /**
@ -483,6 +483,17 @@ class ObjectTest extends CakeTestCase {
$this->assertNull(Router::getRequest(), 'requests were not popped off the stack, this will break url generation'); $this->assertNull(Router::getRequest(), 'requests were not popped off the stack, this will break url generation');
} }
/**
* Test that here() is calculated correctly in requestAction
*
* @return void
*/
public function testRequestActionHere() {
$url = '/request_action/return_here?key=value';
$result = $this->object->requestAction($url);
$this->assertStringEndsWith($url, $result);
}
/** /**
* test requestAction() and plugins. * test requestAction() and plugins.
* *

View file

@ -6987,6 +6987,34 @@ class ModelReadTest extends BaseModelTest {
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }
/**
* test find('list') method
*
* @return void
*/
public function testFindListZeroValue() {
$this->loadFixtures('Article');
$model = new Article();
$model->displayField = 'title';
$model->save(array(
'title' => 'Zeroth Article',
'user_id' => 0,
'published' => 'Y'
));
$result = $model->find('list', array(
'fields' => array('title', 'user_id')
));
$expected = array(
'Zeroth Article' => 0,
'First Article' => 1,
'Second Article' => 3,
'Third Article' => 1,
);
$this->assertEquals($expected, $result);
}
/** /**
* Test that find(list) works with array conditions that have only one element. * Test that find(list) works with array conditions that have only one element.
* *

View file

@ -193,7 +193,8 @@ class CakeRequestTest extends CakeTestCase {
$request = new CakeRequest('some/path?one=something&two=else'); $request = new CakeRequest('some/path?one=something&two=else');
$expected = array('one' => 'something', 'two' => 'else'); $expected = array('one' => 'something', 'two' => 'else');
$this->assertEquals($expected, $request->query); $this->assertEquals($expected, $request->query);
$this->assertEquals('some/path?one=something&two=else', $request->url); $this->assertEquals('some/path', $request->url);
$this->assertStringEndsWith('/some/path?one=something&two=else', $request->here());
} }
/** /**

View file

@ -83,11 +83,13 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testConnectEhlo() { public function testConnectEhlo() {
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true)); $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->any())
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n")); ->method('read')
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n"); ->will($this->onConsecutiveCalls(
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false)); "220 Welcome message\r\n",
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n")); "250 Accepted\r\n"
));
$this->socket->expects($this->once())->method('write')->with("EHLO localhost\r\n");
$this->SmtpTransport->connect(); $this->SmtpTransport->connect();
} }
@ -99,18 +101,14 @@ class SmtpTransportTest extends CakeTestCase {
public function testConnectEhloTls() { public function testConnectEhloTls() {
$this->SmtpTransport->config(array('tls' => true)); $this->SmtpTransport->config(array('tls' => true));
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true)); $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n")); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n"); $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 Accepted\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n")); $this->socket->expects($this->at(4))->method('write')->with("STARTTLS\r\n");
$this->socket->expects($this->at(5))->method('write')->with("STARTTLS\r\n"); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("220 Server ready\r\n"));
$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(6))->method('enableCrypto')->with('tls')->will($this->returnValue(true));
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("220 Server ready\r\n")); $this->socket->expects($this->at(7))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(8))->method('enableCrypto')->with('tls')->will($this->returnValue(true)); $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250 Accepted\r\n"));
$this->socket->expects($this->at(9))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 Accepted\r\n"));
$this->SmtpTransport->connect(); $this->SmtpTransport->connect();
} }
@ -124,14 +122,11 @@ class SmtpTransportTest extends CakeTestCase {
public function testConnectEhloTlsOnNonTlsServer() { public function testConnectEhloTlsOnNonTlsServer() {
$this->SmtpTransport->config(array('tls' => true)); $this->SmtpTransport->config(array('tls' => true));
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true)); $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n")); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n"); $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 Accepted\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n")); $this->socket->expects($this->at(4))->method('write')->with("STARTTLS\r\n");
$this->socket->expects($this->at(5))->method('write')->with("STARTTLS\r\n"); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n"));
$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n"));
$this->SmtpTransport->connect(); $this->SmtpTransport->connect();
} }
@ -145,14 +140,11 @@ class SmtpTransportTest extends CakeTestCase {
public function testConnectEhloNoTlsOnRequiredTlsServer() { public function testConnectEhloNoTlsOnRequiredTlsServer() {
$this->SmtpTransport->config(array('tls' => false, 'username' => 'user', 'password' => 'pass')); $this->SmtpTransport->config(array('tls' => false, 'username' => 'user', 'password' => 'pass'));
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true)); $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n")); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n"); $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 Accepted\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n")); $this->socket->expects($this->at(4))->method('write')->with("AUTH LOGIN\r\n");
$this->socket->expects($this->at(5))->method('write')->with("AUTH LOGIN\r\n"); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("504 5.7.4 Unrecognized authentication type\r\n"));
$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("504 5.7.4 Unrecognized authentication type\r\n"));
$this->SmtpTransport->connect(); $this->SmtpTransport->connect();
$this->SmtpTransport->auth(); $this->SmtpTransport->auth();
} }
@ -164,14 +156,11 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testConnectHelo() { public function testConnectHelo() {
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true)); $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n")); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n"); $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("200 Not Accepted\r\n")); $this->socket->expects($this->at(4))->method('write')->with("HELO localhost\r\n");
$this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n"); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 Accepted\r\n"));
$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250 Accepted\r\n"));
$this->SmtpTransport->connect(); $this->SmtpTransport->connect();
} }
@ -184,14 +173,11 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testConnectFail() { public function testConnectFail() {
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true)); $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n")); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n"); $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("200 Not Accepted\r\n")); $this->socket->expects($this->at(4))->method('write')->with("HELO localhost\r\n");
$this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n"); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
$this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
$this->SmtpTransport->connect(); $this->SmtpTransport->connect();
} }
@ -202,14 +188,11 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testAuth() { public function testAuth() {
$this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("334 Login\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n")); $this->socket->expects($this->at(2))->method('write')->with("bWFyaw==\r\n");
$this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n"); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("334 Pass\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(4))->method('write')->with("c3Rvcnk=\r\n");
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("334 Pass\r\n")); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("235 OK\r\n"));
$this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n");
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(8))->method('read')->will($this->returnValue("235 OK\r\n"));
$this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
$this->SmtpTransport->auth(); $this->SmtpTransport->auth();
} }
@ -223,8 +206,7 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testAuthNotRecognized() { public function testAuthNotRecognized() {
$this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("500 5.3.3 Unrecognized command\r\n"));
$this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
$this->SmtpTransport->auth(); $this->SmtpTransport->auth();
} }
@ -238,8 +220,8 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testAuthNotImplemented() { public function testAuthNotImplemented() {
$this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("502 5.3.3 Command not implemented\r\n")); ->will($this->returnValue("502 5.3.3 Command not implemented\r\n"));
$this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
$this->SmtpTransport->auth(); $this->SmtpTransport->auth();
} }
@ -253,8 +235,8 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testAuthBadSequence() { public function testAuthBadSequence() {
$this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("503 5.5.1 Already authenticated\r\n")); ->will($this->returnValue("503 5.5.1 Already authenticated\r\n"));
$this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
$this->SmtpTransport->auth(); $this->SmtpTransport->auth();
} }
@ -268,11 +250,9 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testAuthBadUsername() { public function testAuthBadUsername() {
$this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("334 Login\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n")); $this->socket->expects($this->at(2))->method('write')->with("bWFyaw==\r\n");
$this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n"); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n"));
$this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
$this->SmtpTransport->auth(); $this->SmtpTransport->auth();
} }
@ -286,14 +266,11 @@ class SmtpTransportTest extends CakeTestCase {
*/ */
public function testAuthBadPassword() { public function testAuthBadPassword() {
$this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n"); $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("334 Login\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n")); $this->socket->expects($this->at(2))->method('write')->with("bWFyaw==\r\n");
$this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n"); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("334 Pass\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(4))->method('write')->with("c3Rvcnk=\r\n");
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("334 Pass\r\n")); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n"));
$this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n");
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(8))->method('read')->will($this->returnValue("535 5.7.8 Authentication failed\r\n"));
$this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story')); $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
$this->SmtpTransport->auth(); $this->SmtpTransport->auth();
} }
@ -323,20 +300,15 @@ class SmtpTransportTest extends CakeTestCase {
$email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso')); $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
$this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n"); $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n")); $this->socket->expects($this->at(2))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
$this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n"); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(4))->method('write')->with("RCPT TO:<mark@cakephp.org>\r\n");
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n")); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(6))->method('write')->with("RCPT TO:<mark@cakephp.org>\r\n"); $this->socket->expects($this->at(6))->method('write')->with("RCPT TO:<juan@cakephp.org>\r\n");
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250 OK\r\n")); $this->socket->expects($this->at(8))->method('write')->with("RCPT TO:<phpnut@cakephp.org>\r\n");
$this->socket->expects($this->at(9))->method('write')->with("RCPT TO:<juan@cakephp.org>\r\n"); $this->socket->expects($this->at(9))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(12))->method('write')->with("RCPT TO:<phpnut@cakephp.org>\r\n");
$this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(14))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->sendRcpt($email); $this->SmtpTransport->sendRcpt($email);
} }
@ -353,11 +325,9 @@ class SmtpTransportTest extends CakeTestCase {
$email->returnPath('pleasereply@cakephp.org', 'CakePHP Return'); $email->returnPath('pleasereply@cakephp.org', 'CakePHP Return');
$this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<pleasereply@cakephp.org>\r\n"); $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<pleasereply@cakephp.org>\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n")); $this->socket->expects($this->at(2))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
$this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n"); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->sendRcpt($email); $this->SmtpTransport->sendRcpt($email);
} }
@ -398,11 +368,9 @@ class SmtpTransportTest extends CakeTestCase {
$data .= "\r\n\r\n.\r\n"; $data .= "\r\n\r\n.\r\n";
$this->socket->expects($this->at(0))->method('write')->with("DATA\r\n"); $this->socket->expects($this->at(0))->method('write')->with("DATA\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("354 OK\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("354 OK\r\n")); $this->socket->expects($this->at(2))->method('write')->with($data);
$this->socket->expects($this->at(3))->method('write')->with($data); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->sendData($email); $this->SmtpTransport->sendData($email);
} }
@ -443,20 +411,18 @@ class SmtpTransportTest extends CakeTestCase {
$this->assertEmpty($this->SmtpTransport->getLastResponse()); $this->assertEmpty($this->SmtpTransport->getLastResponse());
$this->socket->expects($this->any())->method('connect')->will($this->returnValue(true)); $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
$this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n")); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
$this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n"); $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
$this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250-PIPELINING\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250-PIPELINING\r\n")); $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250-SIZE 102400000\r\n"));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250-SIZE 102400000\r\n")); $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250-VRFY\r\n"));
$this->socket->expects($this->at(6))->method('read')->will($this->returnValue("250-VRFY\r\n")); $this->socket->expects($this->at(6))->method('read')->will($this->returnValue("250-ETRN\r\n"));
$this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250-ETRN\r\n")); $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250-STARTTLS\r\n"));
$this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250-STARTTLS\r\n")); $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250-AUTH PLAIN LOGIN\r\n"));
$this->socket->expects($this->at(9))->method('read')->will($this->returnValue("250-AUTH PLAIN LOGIN\r\n")); $this->socket->expects($this->at(9))->method('read')->will($this->returnValue("250-AUTH=PLAIN LOGIN\r\n"));
$this->socket->expects($this->at(10))->method('read')->will($this->returnValue("250-AUTH=PLAIN LOGIN\r\n")); $this->socket->expects($this->at(10))->method('read')->will($this->returnValue("250-ENHANCEDSTATUSCODES\r\n"));
$this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250-ENHANCEDSTATUSCODES\r\n")); $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250-8BITMIME\r\n"));
$this->socket->expects($this->at(12))->method('read')->will($this->returnValue("250-8BITMIME\r\n")); $this->socket->expects($this->at(12))->method('read')->will($this->returnValue("250 DSN\r\n"));
$this->socket->expects($this->at(13))->method('read')->will($this->returnValue("250 DSN\r\n"));
$this->SmtpTransport->connect(); $this->SmtpTransport->connect();
$expected = array( $expected = array(
@ -479,11 +445,9 @@ class SmtpTransportTest extends CakeTestCase {
$email->to('cake@cakephp.org', 'CakePHP'); $email->to('cake@cakephp.org', 'CakePHP');
$this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n"); $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
$this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false)); $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n")); $this->socket->expects($this->at(2))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
$this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n"); $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->sendRcpt($email); $this->SmtpTransport->sendRcpt($email);

View file

@ -2464,9 +2464,8 @@ class RouterTest extends CakeTestCase {
* *
* @return void * @return void
*/ */
public function testRouterReverse() { public function testReverseToken() {
Router::$initialized = true; Router::$initialized = true;
$params = array( $params = array(
'controller' => 'posts', 'controller' => 'posts',
'action' => 'view', 'action' => 'view',
@ -2481,17 +2480,21 @@ class RouterTest extends CakeTestCase {
); );
$result = Router::reverse($params); $result = Router::reverse($params);
$this->assertEquals('/posts/view/1', $result); $this->assertEquals('/posts/view/1', $result);
}
public function testReverseNamed() {
$params = array( $params = array(
'controller' => 'posts', 'controller' => 'posts',
'action' => 'index', 'action' => 'index',
'pass' => array(1), 'pass' => array(1),
'named' => array('page' => 1, 'sort' => 'Article.title', 'direction' => 'desc'), 'named' => array('page' => 1, 'sort' => 'Article.title', 'direction' => 'desc'),
'url' => array() 'url' => array(),
); );
$result = Router::reverse($params); $result = Router::reverse($params);
$this->assertEquals('/posts/index/1/page:1/sort:Article.title/direction:desc', $result); $this->assertEquals('/posts/index/1/page:1/sort:Article.title/direction:desc', $result);
}
public function testReverseLocalized() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}')); Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$params = array( $params = array(
'lang' => 'eng', 'lang' => 'eng',
@ -2499,11 +2502,14 @@ class RouterTest extends CakeTestCase {
'action' => 'view', 'action' => 'view',
'pass' => array(1), 'pass' => array(1),
'named' => array(), 'named' => array(),
'url' => array('url' => 'eng/posts/view/1') 'url' => array('url' => 'eng/posts/view/1'),
); );
$result = Router::reverse($params); $result = Router::reverse($params);
$this->assertEquals('/eng/posts/view/1', $result); $this->assertEquals('/eng/posts/view/1', $result);
}
public function testReverseArrayQuery() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$params = array( $params = array(
'lang' => 'eng', 'lang' => 'eng',
'controller' => 'posts', 'controller' => 'posts',
@ -2512,11 +2518,14 @@ class RouterTest extends CakeTestCase {
'named' => array(), 'named' => array(),
'url' => array('url' => 'eng/posts/view/1', 'foo' => 'bar', 'baz' => 'quu'), 'url' => array('url' => 'eng/posts/view/1', 'foo' => 'bar', 'baz' => 'quu'),
'paging' => array(), 'paging' => array(),
'models' => array() 'models' => array(),
); );
$result = Router::reverse($params); $result = Router::reverse($params);
$this->assertEquals('/eng/posts/view/1?foo=bar&baz=quu', $result); $this->assertEquals('/eng/posts/view/1?foo=bar&baz=quu', $result);
}
public function testReverseCakeRequestQuery() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$request = new CakeRequest('/eng/posts/view/1'); $request = new CakeRequest('/eng/posts/view/1');
$request->addParams(array( $request->addParams(array(
'lang' => 'eng', 'lang' => 'eng',
@ -2529,19 +2538,64 @@ class RouterTest extends CakeTestCase {
$result = Router::reverse($request); $result = Router::reverse($request);
$expected = '/eng/posts/view/1?test=value'; $expected = '/eng/posts/view/1?test=value';
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
}
public function testReverseFull() {
Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
$params = array( $params = array(
'lang' => 'eng', 'lang' => 'eng',
'controller' => 'posts', 'controller' => 'posts',
'action' => 'view', 'action' => 'view',
'pass' => array(1), 'pass' => array(1),
'named' => array(), 'named' => array(),
'url' => array('url' => 'eng/posts/view/1') 'url' => array('url' => 'eng/posts/view/1'),
); );
$result = Router::reverse($params, true); $result = Router::reverse($params, true);
$this->assertRegExp('/^http(s)?:\/\//', $result); $this->assertRegExp('/^http(s)?:\/\//', $result);
} }
public function testReverseToArrayNamed() {
$params = array(
'controller' => 'posts',
'action' => 'index',
'pass' => array(123),
'named' => array('page' => 123, 'sort' => 'Article.title', 'direction' => 'desc'),
'url' => array(),
);
$result = Router::reverseToArray($params);
$expected = array(
'controller' => 'posts',
'action' => 'index',
123,
'page' => 123,
'sort' => 'Article.title',
'direction' => 'desc',
);
$this->assertEquals($expected, $result);
}
public function testReverseToArrayCakeRequestQuery() {
$request = new CakeRequest('/posts/view/123');
$request->addParams(array(
'controller' => 'posts',
'action' => 'view',
'pass' => array(123),
'named' => array(),
));
$request->query = array('url' => 'eng/posts/view/123', 'test' => 'value');
$result = Router::reverseToArray($request);
$expected = array(
'plugin' => null,
'controller' => 'posts',
'action' => 'view',
123,
'?' => array(
'test' => 'value',
),
);
$this->assertEquals($expected, $result);
}
/** /**
* Test that extensions work with Router::reverse() * Test that extensions work with Router::reverse()
* *

View file

@ -236,10 +236,13 @@ class HashTest extends CakeTestCase {
*/ */
public function testGetEmptyKey() { public function testGetEmptyKey() {
$data = array( $data = array(
'' => 'some value' true => 'true value',
false => 'false value',
'' => 'some value',
); );
$result = Hash::get($data, ''); $this->assertSame($data[''], Hash::get($data, ''));
$this->assertSame($data[''], $result); $this->assertSame($data[false], Hash::get($data, false));
$this->assertSame($data[true], Hash::get($data, true));
} }
/** /**
@ -249,7 +252,7 @@ class HashTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testGetInvalidPath() { public function testGetInvalidPath() {
Hash::get(array('one' => 'two'), true); Hash::get(array('one' => 'two'), new StdClass());
} }
/** /**
@ -652,8 +655,21 @@ class HashTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testFilter() { public function testFilter() {
$result = Hash::filter(array('0', false, true, 0, array('one thing', 'I can tell you', 'is you got to be', false))); $result = Hash::filter(array(
$expected = array('0', 2 => true, 3 => 0, 4 => array('one thing', 'I can tell you', 'is you got to be')); '0',
false,
true,
0,
0.0,
array('one thing', 'I can tell you', 'is you got to be', false)
));
$expected = array(
'0',
2 => true,
3 => 0,
4 => 0.0,
5 => array('one thing', 'I can tell you', 'is you got to be')
);
$this->assertSame($expected, $result); $this->assertSame($expected, $result);
$result = Hash::filter(array(1, array(false))); $result = Hash::filter(array(1, array(false)));

View file

@ -1825,6 +1825,20 @@ class ValidationTest extends CakeTestCase {
$this->assertFalse(Validation::maxLength('ÆΔΩЖÇ', 3)); $this->assertFalse(Validation::maxLength('ÆΔΩЖÇ', 3));
} }
/**
* maxLengthBytes method
*
* @return void
*/
public function testMaxLengthBytes() {
$this->assertTrue(Validation::maxLengthBytes('ab', 3));
$this->assertTrue(Validation::maxLengthBytes('abc', 3));
$this->assertTrue(Validation::maxLengthBytes('ÆΔΩЖÇ', 10));
$this->assertTrue(Validation::maxLengthBytes('ÆΔΩЖÇ', 11));
$this->assertFalse(Validation::maxLengthBytes('abcd', 3));
$this->assertFalse(Validation::maxLengthBytes('ÆΔΩЖÇ', 9));
}
/** /**
* testMinLength method * testMinLength method
* *
@ -1839,6 +1853,20 @@ class ValidationTest extends CakeTestCase {
$this->assertTrue(Validation::minLength('ÆΔΩЖÇ', 2)); $this->assertTrue(Validation::minLength('ÆΔΩЖÇ', 2));
} }
/**
* minLengthBytes method
*
* @return void
*/
public function testMinLengthBytes() {
$this->assertFalse(Validation::minLengthBytes('ab', 3));
$this->assertFalse(Validation::minLengthBytes('ÆΔΩЖÇ', 11));
$this->assertTrue(Validation::minLengthBytes('abc', 3));
$this->assertTrue(Validation::minLengthBytes('abcd', 3));
$this->assertTrue(Validation::minLengthBytes('ÆΔΩЖÇ', 10));
$this->assertTrue(Validation::minLengthBytes('ÆΔΩЖÇ', 9));
}
/** /**
* testUrl method * testUrl method
* *

View file

@ -167,6 +167,18 @@ class XmlTest extends CakeTestCase {
$this->assertNotRegExp('/encoding/', $obj->saveXML()); $this->assertNotRegExp('/encoding/', $obj->saveXML());
} }
/**
* test build() method with huge option
*
* @return void
*/
public function testBuildHuge() {
$xml = '<tag>value</tag>';
$obj = Xml::build($xml, array('parseHuge' => true));
$this->assertEquals('tag', $obj->getName());
$this->assertEquals('value', (string)$obj);
}
/** /**
* Test that the readFile option disables local file parsing. * Test that the readFile option disables local file parsing.
* *

View file

@ -88,6 +88,14 @@ class FlashHelperTest extends CakeTestCase {
'element' => 'flash_classy', 'element' => 'flash_classy',
'params' => array() 'params' => array()
) )
),
'default' => array(
array(
'key' => 'default',
'message' => 'Default',
'element' => 'default',
'params' => array()
)
) )
) )
)); ));
@ -166,4 +174,13 @@ class FlashHelperTest extends CakeTestCase {
$expected = 'this is the plugin element'; $expected = 'this is the plugin element';
$this->assertContains($expected, $result); $this->assertContains($expected, $result);
} }
/**
* Test that the default element fallbacks to the Flash/default element.
*/
public function testFlashFallback() {
$result = $this->Flash->render('default');
$expected = '<div class="message">Default</div>';
$this->assertContains($expected, $result);
}
} }

View file

@ -5291,6 +5291,60 @@ class FormHelperTest extends CakeTestCase {
$this->assertTags($result, $expected); $this->assertTags($result, $expected);
} }
/**
* test that select() with numeric label of optiongroup.
*
* @return void
*/
public function testSelectOptionGroupWithNumericLabel() {
$options = array(
1 => array(
1 => '1Foo',
2 => '2Bar',
3 => '3Baz',
4 => '1',
5 => '2',
6 => '3',
7 => 1,
8 => 2,
9 => 3,
),
2 => array(
11 => '1Foo',
12 => '2Bar',
13 => '3Baz',
14 => '1',
15 => '2',
16 => '3',
17 => 1,
18 => 2,
19 => 3,
),
);
$result = $this->Form->select('Model.field', $options, array('empty' => false));
$expected = array(
'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
array('optgroup' => array('label' => '1')),
array('option' => array('value' => '1')), '1Foo', '/option',
array('option' => array('value' => '2')), '2Bar', '/option',
array('option' => array('value' => '3')), '3Baz', '/option',
array('option' => array('value' => '6')), '3', '/option',
array('option' => array('value' => '9')), '3', '/option',
'/optgroup',
array('optgroup' => array('label' => '2')),
array('option' => array('value' => '11')), '1Foo', '/option',
array('option' => array('value' => '12')), '2Bar', '/option',
array('option' => array('value' => '13')), '3Baz', '/option',
array('option' => array('value' => '14')), '1', '/option',
array('option' => array('value' => '16')), '3', '/option',
array('option' => array('value' => '17')), '1', '/option',
array('option' => array('value' => '19')), '3', '/option',
'/optgroup',
'/select'
);
$this->assertTags($result, $expected);
}
/** /**
* test that select() with optiongroups listens to the escape param. * test that select() with optiongroups listens to the escape param.
* *
@ -11029,4 +11083,72 @@ class FormHelperTest extends CakeTestCase {
$this->assertAttributeEquals($here, '_lastAction', $this->Form, "_lastAction shouldn't be empty."); $this->assertAttributeEquals($here, '_lastAction', $this->Form, "_lastAction shouldn't be empty.");
} }
/**
* Tests the 'errorClass' option when error is returned.
*
* @return void
*/
public function testInputErrorClass() {
$Contact = ClassRegistry::getObject('Contact');
$Contact->validationErrors['field'] = array('Badness!');
$result = $this->Form->input('Contact.field', array(
'type' => 'text',
'div' => array('errorClass' => 'has-error')
));
$expected = array(
'div' => array('class' => 'input text has-error'),
'label' => array('for' => 'ContactField'),
'Field',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][field]',
'id' => 'ContactField', 'class' => 'form-error'
),
array('div' => array('class' => 'error-message')),
'Badness!',
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.field', array(
'type' => 'text',
'error' => array('attributes' => array('class' => 'error'))
));
$expected = array(
'div' => array('class' => 'input text error'),
'label' => array('for' => 'ContactField'),
'Field',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][field]',
'id' => 'ContactField', 'class' => 'form-error'
),
array('div' => array('class' => 'error')),
'Badness!',
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('Contact.field', array(
'type' => 'text',
'div' => array('errorClass' => 'has-error'),
'error' => array('attributes' => array('class' => 'form-control-feedback'))
));
$expected = array(
'div' => array('class' => 'input text has-error'),
'label' => array('for' => 'ContactField'),
'Field',
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][field]',
'id' => 'ContactField', 'class' => 'form-error'
),
array('div' => array('class' => 'form-control-feedback')),
'Badness!',
'/div'
);
$this->assertTags($result, $expected);
}
} }

View file

@ -48,11 +48,13 @@ class Hash {
} }
if (is_string($path) || is_numeric($path)) { if (is_string($path) || is_numeric($path)) {
$parts = explode('.', $path); $parts = explode('.', $path);
} elseif (is_bool($path) || $path === null) {
$parts = array($path);
} else { } else {
if (!is_array($path)) { if (!is_array($path)) {
throw new InvalidArgumentException(__d('cake_dev', throw new InvalidArgumentException(__d('cake_dev',
'Invalid Parameter %s, should be dot separated path or array.', 'Invalid path parameter: %s, should be dot separated path or array.',
$path var_export($path, true)
)); ));
} }
$parts = $path; $parts = $path;
@ -571,7 +573,7 @@ class Hash {
* @return bool * @return bool
*/ */
protected static function _filter($var) { protected static function _filter($var) {
if ($var === 0 || $var === '0' || !empty($var)) { if ($var === 0 || $var === 0.0 || $var === '0' || !empty($var)) {
return true; return true;
} }
return false; return false;

View file

@ -539,7 +539,7 @@ class Validation {
} }
/** /**
* Checks whether the length of a string is greater or equal to a minimal length. * Checks whether the length of a string (in characters) is greater or equal to a minimal length.
* *
* @param string $check The string to test * @param string $check The string to test
* @param int $min The minimal string length * @param int $min The minimal string length
@ -550,7 +550,7 @@ class Validation {
} }
/** /**
* Checks whether the length of a string is smaller or equal to a maximal length.. * Checks whether the length of a string (in characters) is smaller or equal to a maximal length..
* *
* @param string $check The string to test * @param string $check The string to test
* @param int $max The maximal string length * @param int $max The maximal string length
@ -560,6 +560,28 @@ class Validation {
return mb_strlen($check) <= $max; return mb_strlen($check) <= $max;
} }
/**
* Checks whether the length of a string (in bytes) is greater or equal to a minimal length.
*
* @param string $check The string to test
* @param int $min The minimal string length
* @return bool Success
*/
public static function minLengthBytes($check, $min) {
return strlen($check) >= $min;
}
/**
* Checks whether the length of a string (in bytes) is smaller or equal to a maximal length..
*
* @param string $check The string to test
* @param int $max The maximal string length
* @return bool Success
*/
public static function maxLengthBytes($check, $max) {
return strlen($check) <= $max;
}
/** /**
* Checks that a value is a monetary amount. * Checks that a value is a monetary amount.
* *

View file

@ -80,7 +80,9 @@ class Xml {
* - `readFile` Set to false to disable file reading. This is important to disable when * - `readFile` Set to false to disable file reading. This is important to disable when
* putting user data into Xml::build(). If enabled local & remote files will be read if they exist. * putting user data into Xml::build(). If enabled local & remote files will be read if they exist.
* Defaults to true for backwards compatibility reasons. * Defaults to true for backwards compatibility reasons.
* - If using array as input, you can pass `options` from Xml::fromArray. * - `parseHuge` Enable the `LIBXML_PARSEHUGE`
*
* If using array as input, you can pass `options` from Xml::fromArray.
* *
* @param string|array $input XML string, a path to a file, a URL or an array * @param string|array $input XML string, a path to a file, a URL or an array
* @param array $options The options to use * @param array $options The options to use
@ -94,7 +96,8 @@ class Xml {
$defaults = array( $defaults = array(
'return' => 'simplexml', 'return' => 'simplexml',
'loadEntities' => false, 'loadEntities' => false,
'readFile' => true 'readFile' => true,
'parseHuge' => true
); );
$options += $defaults; $options += $defaults;
@ -135,6 +138,10 @@ class Xml {
if ($hasDisable && !$options['loadEntities']) { if ($hasDisable && !$options['loadEntities']) {
libxml_disable_entity_loader(true); libxml_disable_entity_loader(true);
} }
$flags = LIBXML_NOCDATA;
if (!empty($options['parseHuge'])) {
$flags |= LIBXML_PARSEHUGE;
}
try { try {
if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') { if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
$xml = new SimpleXMLElement($input, LIBXML_NOCDATA); $xml = new SimpleXMLElement($input, LIBXML_NOCDATA);

View file

@ -88,6 +88,9 @@ class FlashHelper extends AppHelper {
foreach ($flash as $message) { foreach ($flash as $message) {
$message['key'] = $key; $message['key'] = $key;
$message = $options + $message; $message = $options + $message;
if ($message['element'] === 'default') {
$message['element'] = 'Flash/default';
}
$out .= $this->_View->element($message['element'], $message); $out .= $this->_View->element($message['element'], $message);
} }

View file

@ -1089,7 +1089,7 @@ class FormHelper extends AppHelper {
if ($type !== 'hidden' && $error !== false) { if ($type !== 'hidden' && $error !== false) {
$errMsg = $this->error($fieldName, $error); $errMsg = $this->error($fieldName, $error);
if ($errMsg) { if ($errMsg) {
$divOptions = $this->addClass($divOptions, 'error'); $divOptions = $this->addClass($divOptions, Hash::get($divOptions, 'errorClass', 'error'));
if ($errorMessage) { if ($errorMessage) {
$out['error'] = $errMsg; $out['error'] = $errMsg;
} }
@ -1109,7 +1109,7 @@ class FormHelper extends AppHelper {
if (!empty($divOptions['tag'])) { if (!empty($divOptions['tag'])) {
$tag = $divOptions['tag']; $tag = $divOptions['tag'];
unset($divOptions['tag']); unset($divOptions['tag'], $divOptions['errorClass']);
$output = $this->Html->tag($tag, $output, $divOptions); $output = $this->Html->tag($tag, $output, $divOptions);
} }
return $output; return $output;
@ -2860,7 +2860,7 @@ class FormHelper extends AppHelper {
} else { } else {
$select[] = $this->Html->useTag('optiongroupend'); $select[] = $this->Html->useTag('optiongroupend');
} }
$parents[] = $name; $parents[] = (string)$name;
} }
$select = array_merge($select, $this->_selectOptions( $select = array_merge($select, $this->_selectOptions(
$title, $parents, $showParents, $attributes $title, $parents, $showParents, $attributes