From b85d03dce2eddec6c193a8e5eb627cdb1d83b91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renan=20Gon=C3=A7alves?= Date: Mon, 13 May 2013 14:17:35 +0300 Subject: [PATCH 01/18] Showing build status for 2.4 branch. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 611729f0874..413ef4f8d86 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,6 @@ Get Support! [Lighthouse](http://cakephp.lighthouseapp.com/) - Got issues? Please tell us! -[![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=2.4)](http://travis-ci.org/cakephp/cakephp) ![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif) From 4d434ec9f3b51ece238ddf2434b3d22979fe7c51 Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 13 May 2013 23:51:32 +0530 Subject: [PATCH 02/18] Fix CS errors --- lib/Cake/Model/Model.php | 2 +- lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 035a062ef52..0615e102a4e 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -1075,7 +1075,7 @@ protected function _generateAssociation($type, $assocKey) { case 'joinTable': $tables = array($this->table, $this->{$class}->table); - sort ($tables); + sort($tables); $data = $tables[0] . '_' . $tables[1]; break; diff --git a/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php b/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php index 3ab84af6382..2d3c4c8097f 100644 --- a/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php @@ -520,7 +520,7 @@ protected function _debug($printTreesToo = false) { foreach ($permissions as $key => $values) { array_unshift($values, $key); $values = array_map(array(&$this, '_pad'), $values); - $permissions[$key] = implode (' ', $values); + $permissions[$key] = implode(' ', $values); } $permissions = array_map(array(&$this, '_pad'), $permissions); array_unshift($permissions, 'Current Permissions :'); From c1b2ca581c7282685743d68e6a4fb0ec94e2686f Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 13 May 2013 20:53:37 -0400 Subject: [PATCH 03/18] Use terser assertions. --- lib/Cake/Test/Case/View/Helper/FormHelperTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 3f6e2645894..138d361cf03 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -1464,13 +1464,11 @@ public function testTagIsInvalid() { $this->Form->setEntity('Contact.1.email'); $result = $this->Form->tagIsInvalid(); - $expected = false; - $this->assertSame($expected, $result); + $this->assertFalse($result); $this->Form->setEntity('Contact.0.name'); $result = $this->Form->tagIsInvalid(); - $expected = false; - $this->assertSame($expected, $result); + $this->assertFalse($result); } /** From bd3428e45659078e29938cf20198ff7e6ef0869e Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 13 May 2013 21:07:43 -0400 Subject: [PATCH 04/18] Remove Asset.x Configure values. Having Asset.timestamp on can fail tests accidentally. --- lib/Cake/Test/Case/View/Helper/FormHelperTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 138d361cf03..2ac5333154e 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -536,6 +536,7 @@ public function setUp() { parent::setUp(); Configure::write('App.base', ''); + Configure::delete('Asset'); $this->Controller = new ContactTestController(); $this->View = new View($this->Controller); From f7d106a38642363ef8a61bf7e479260bfe7662c0 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 13 May 2013 21:08:19 -0400 Subject: [PATCH 05/18] Fix FormHelper::tagIsInvalid with saveMany forms. When saving multiple records validation errors were not correctly shown. Fudge the entity path so it matches the validation errors set in the models. Fixes #3828 --- .../Test/Case/View/Helper/FormHelperTest.php | 41 ++++++++++++++++++- lib/Cake/View/Helper/FormHelper.php | 7 ++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 2ac5333154e..78ed898d0d1 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -1456,11 +1456,10 @@ public function testUnlockFieldRemovingFromFields() { */ public function testTagIsInvalid() { $Contact = ClassRegistry::getObject('Contact'); - $Contact->validationErrors[0]['email'] = array('Please provide an email'); + $Contact->validationErrors[0]['email'] = $expected = array('Please provide an email'); $this->Form->setEntity('Contact.0.email'); $result = $this->Form->tagIsInvalid(); - $expected = array('Please provide an email'); $this->assertEquals($expected, $result); $this->Form->setEntity('Contact.1.email'); @@ -1472,6 +1471,26 @@ public function testTagIsInvalid() { $this->assertFalse($result); } +/** + * Test tagIsInvalid with validation errors from a saveMany + * + * @return void + */ + public function testTagIsInvalidSaveMany() { + $Contact = ClassRegistry::getObject('Contact'); + $Contact->validationErrors[0]['email'] = $expected = array('Please provide an email'); + + $this->Form->create('Contact'); + + $this->Form->setEntity('0.email'); + $result = $this->Form->tagIsInvalid(); + $this->assertEquals($expected, $result); + + $this->Form->setEntity('0.Contact.email'); + $result = $this->Form->tagIsInvalid(); + $this->assertEquals($expected, $result); + } + /** * Test validation errors. * @@ -8486,6 +8505,24 @@ public function testMultiRecordFormValidationErrors() { $this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div')); } +/** + * test the correct display of multi-record form validation errors. + * + * @return void + */ + public function testSaveManyRecordFormValidationErrors() { + $this->Form->create('ValidateUser'); + $ValidateUser = ClassRegistry::getObject('ValidateUser'); + $ValidateUser->validationErrors[0]['ValidateItem']['name'] = array('Error in field name'); + + $result = $this->Form->error('0.ValidateUser.ValidateItem.name'); + $this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field name', '/div')); + + $ValidateUser->validationErrors[0]['city'] = array('Error in field city'); + $result = $this->Form->error('ValidateUser.0.city'); + $this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div')); + } + /** * tests the ability to change the order of the form input placeholder "input", "label", "before", "between", "after", "error" * diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index ad331a8d76a..db577155ad4 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -272,6 +272,13 @@ protected function _isRequiredField($validationRules) { public function tagIsInvalid() { $entity = $this->entity(); $model = array_shift($entity); + + // 0.Model.field. Fudge entity path + if (empty($model) || is_numeric($model)) { + array_splice($entity, 1, 0, $model); + $model = array_shift($entity); + } + $errors = array(); if (!empty($entity) && isset($this->validationErrors[$model])) { $errors = $this->validationErrors[$model]; From 0822578813d66dfde5fde5a6e988f87f017fc2c9 Mon Sep 17 00:00:00 2001 From: euromark Date: Tue, 14 May 2013 10:17:57 +0200 Subject: [PATCH 06/18] $this->modelClass needs to be correct prior to the components init() call if the component itself accesses the model, lazyloading would try to load the wrong model otherwise --- lib/Cake/Controller/Controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Controller.php b/lib/Cake/Controller/Controller.php index 834a30ad112..9100dc5441f 100644 --- a/lib/Cake/Controller/Controller.php +++ b/lib/Cake/Controller/Controller.php @@ -632,11 +632,11 @@ public function implementedEvents() { */ public function constructClasses() { $this->_mergeControllerVars(); - $this->Components->init($this); if ($this->uses) { $this->uses = (array)$this->uses; list(, $this->modelClass) = pluginSplit(current($this->uses)); } + $this->Components->init($this); return true; } From 9fd2af96a87c079483b01ce26cad180015bdb9c9 Mon Sep 17 00:00:00 2001 From: euromark Date: Tue, 14 May 2013 10:38:10 +0200 Subject: [PATCH 07/18] add test case --- .../Test/Case/Controller/ControllerTest.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/Cake/Test/Case/Controller/ControllerTest.php b/lib/Cake/Test/Case/Controller/ControllerTest.php index 74b1d31c025..5d34363bdff 100644 --- a/lib/Cake/Test/Case/Controller/ControllerTest.php +++ b/lib/Cake/Test/Case/Controller/ControllerTest.php @@ -360,6 +360,13 @@ public function beforeRender(Controller $controller) { class Test2Component extends TestComponent { + public $model; + + public function __construct(ComponentCollection $collection, $settings) { + $this->controller = $collection->getController(); + $this->model = $this->controller->modelClass; + } + public function beforeRender(Controller $controller) { return false; } @@ -526,6 +533,22 @@ public function testConstructClasses() { $this->assertTrue(is_a($Controller->TestPluginPost, 'TestPluginPost')); } +/** + * testConstructClassesWithComponents method + * + * @return void + */ + public function testConstructClassesWithComponents() { + $Controller = new TestPluginController(new CakeRequest(), new CakeResponse()); + $Controller->uses = array('NameTest'); + $Controller->components[] = 'Test2'; + + $Controller->constructClasses(); + $this->assertEquals('NameTest', $Controller->Test2->model); + $this->assertEquals('Name', $Controller->NameTest->name); + $this->assertEquals('Name', $Controller->NameTest->alias); + } + /** * testAliasName method * From 018e5d0659fbac893dd49b1a5314f1293f300e30 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 14 May 2013 23:21:38 +0200 Subject: [PATCH 08/18] Adding Sylog as a logging engine --- lib/Cake/Log/Engine/SyslogLog.php | 158 ++++++++++++++++++ .../Test/Case/Log/Engine/SyslogLogTest.php | 95 +++++++++++ 2 files changed, 253 insertions(+) create mode 100644 lib/Cake/Log/Engine/SyslogLog.php create mode 100644 lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php diff --git a/lib/Cake/Log/Engine/SyslogLog.php b/lib/Cake/Log/Engine/SyslogLog.php new file mode 100644 index 00000000000..673aff71a00 --- /dev/null +++ b/lib/Cake/Log/Engine/SyslogLog.php @@ -0,0 +1,158 @@ + 'SyslogLog', + * 'types' => array('emergency', 'alert', 'critical', 'error'), + * 'format' => "%s: My-App - %s", + * 'prefix' => 'Web Server 01' + * )); + * }}} + * + * @var array + */ + protected $_defaults = array( + 'format' => '%s: %s', + 'flag' => LOG_ODELAY, + 'prefix' => '', + 'facility' => LOG_USER + ); + +/** + * + * Used to map the string names back to their LOG_* constants + * + * @var array + */ + protected $_priorityMap = array( + 'emergency' => LOG_EMERG, + 'alert' => LOG_ALERT, + 'critical' => LOG_CRIT, + 'error' => LOG_ERR, + 'warning' => LOG_WARNING, + 'notice' => LOG_NOTICE, + 'info' => LOG_INFO, + 'debug' => LOG_DEBUG + ); + +/** + * Whether the logger connection is open or not + * + * @var boolean + */ + protected $_open = false; + +/** + * Make sure the configuration contains the format parameter, by default it uses + * the error number and the type as a prefix to the message + * + * @param array $config + */ + public function __construct($config = array()) { + $config += $this->_defaults; + parent::__construct($config); + } + +/** + * Writes a message to syslog + * + * Map the $type back to a LOG_ constant value, split multi-line messages into multiple + * log messages, pass all messages through the format defined in the configuration + * + * @param string $type The type of log you are making. + * @param string $message The message you want to log. + * @return boolean success of write. + */ + public function write($type, $message) { + if (!$this->_open) { + $config = $this->_config; + $this->_open($config['prefix'], $config['flag'], $config['facility']); + $this->_open = true; + } + + $priority = LOG_DEBUG; + if (isset($this->_priorityMap[$type])) { + $priority = $this->_priorityMap[$type]; + } + + $messages = explode("\n", $message); + foreach ($messages as $message) { + $message = sprintf($this->_config['format'], $type, $message); + $this->_write($priority, $message); + } + + return true; + } + +/** + * Wrapper for openlog call + * + * @param int $priority + * @param sting $output + * @return void + */ + public function _open($ident, $options, $facility) { + openlog($ident, $options, $facility); + } + +/** + * Wrapper for syslog call + * + * @param int $priority + * @param sting $output + * @return bool + */ + protected function _write($priority, $output) { + return syslog($priority, $output); + } + +/** + * Closes the logger connection + * + * @return void + **/ + public function __destruct() { + closelog(); + } + +} diff --git a/lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php b/lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php new file mode 100644 index 00000000000..e6faabfd93a --- /dev/null +++ b/lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php @@ -0,0 +1,95 @@ + + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt + * Redistributions of files must retain the above copyright notice + * + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests + * @package Cake.Test.Case.Log.Engine + * @since CakePHP(tm) v 2.4 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ +App::uses('SyslogLog', 'Log/Engine'); + +/** + * SyslogLogTest class + * + * @package Cake.Test.Case.Log.Engine + */ +class SyslogLogTest extends CakeTestCase { + +/** + * Tests that the connection to the logger is open with the right arguments + * + * @return void + */ + public function testOpenLog() { + $log = $this->getMock('SyslogLog', array('_open', '_write')); + $log->expects($this->once())->method('_open')->with('', LOG_ODELAY, LOG_USER); + $log->write('debug', 'message'); + + $log = $this->getMock('SyslogLog', array('_open', '_write')); + $log->config(array( + 'prefix' => 'thing', + 'flag' => LOG_NDELAY, + 'facility' => LOG_MAIL, + 'format' => '%s: %s' + )); + $log->expects($this->once())->method('_open') + ->with('thing', LOG_NDELAY, LOG_MAIL); + $log->write('debug', 'message'); + } + +/** + * Tests that single lines are written to syslog + * + * @dataProvider typesProvider + * @return void + */ + public function testWriteOneLine($type, $expected) { + $log = $this->getMock('SyslogLog', array('_open', '_write')); + $log->expects($this->once())->method('_write')->with($expected, $type . ': Foo'); + $log->write($type, 'Foo'); + } + +/** + * Tests that multiple lines are split and logged separately + * + * @return void + */ + public function testWriteMultiLine() { + $log = $this->getMock('SyslogLog', array('_open', '_write')); + $log->expects($this->at(1))->method('_write')->with(LOG_DEBUG, 'debug: Foo'); + $log->expects($this->at(2))->method('_write')->with(LOG_DEBUG, 'debug: Bar'); + $log->expects($this->exactly(2))->method('_write'); + $log->write('debug', "Foo\nBar"); + } + +/** + * Data provider for the write function test + * + * @return array + */ + public function typesProvider() { + return array( + array('emergency', LOG_EMERG), + array('alert', LOG_ALERT), + array('critical', LOG_CRIT), + array('error', LOG_ERR), + array('warning', LOG_WARNING), + array('notice', LOG_NOTICE), + array('info', LOG_INFO), + array('debug', LOG_DEBUG) + ); + } + +} + From 1d61e21eaabfa5044aedf9d12f3654e4781184ea Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 14 May 2013 23:52:39 +0200 Subject: [PATCH 09/18] Fixing method visibility --- lib/Cake/Log/Engine/SyslogLog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Log/Engine/SyslogLog.php b/lib/Cake/Log/Engine/SyslogLog.php index 673aff71a00..b71dad41d41 100644 --- a/lib/Cake/Log/Engine/SyslogLog.php +++ b/lib/Cake/Log/Engine/SyslogLog.php @@ -131,7 +131,7 @@ public function write($type, $message) { * @param sting $output * @return void */ - public function _open($ident, $options, $facility) { + protected function _open($ident, $options, $facility) { openlog($ident, $options, $facility); } From 785c17d1999b6d32deedd01376c6023aabb86bb9 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Wed, 15 May 2013 09:52:25 +0200 Subject: [PATCH 10/18] Fixing docblocks --- lib/Cake/Log/Engine/SyslogLog.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Log/Engine/SyslogLog.php b/lib/Cake/Log/Engine/SyslogLog.php index b71dad41d41..1c2e6ed856c 100644 --- a/lib/Cake/Log/Engine/SyslogLog.php +++ b/lib/Cake/Log/Engine/SyslogLog.php @@ -36,7 +36,10 @@ class SyslogLog extends BaseLog { * this logger * * If you wish to include a prefix to all messages, for instance to identify the - * application or the web server, then use the prefix option. + * application or the web server, then use the prefix option. Please keep in mind + * the prefix is shared by all streams using syslog, as it is dependent of + * the running process. For a local prefix, to be used only by one stream, you + * can use the format key. * * ## Example: * @@ -127,8 +130,9 @@ public function write($type, $message) { /** * Wrapper for openlog call * - * @param int $priority - * @param sting $output + * @param string $ident the prefix to add to all messages logged + * @param int $options the options flags to be used for logged messages + * @param int $facility the stream or facility to log to * @return void */ protected function _open($ident, $options, $facility) { @@ -139,11 +143,11 @@ protected function _open($ident, $options, $facility) { * Wrapper for syslog call * * @param int $priority - * @param sting $output + * @param string $message * @return bool */ - protected function _write($priority, $output) { - return syslog($priority, $output); + protected function _write($priority, $message) { + return syslog($priority, $message); } /** From e9d50ebabb672ddc1ac963d1cf50bdc13f4c8d5c Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Thu, 16 May 2013 16:06:17 +0200 Subject: [PATCH 11/18] Improving doc blocks --- lib/Cake/Log/Engine/SyslogLog.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Log/Engine/SyslogLog.php b/lib/Cake/Log/Engine/SyslogLog.php index 1c2e6ed856c..cc233c3f304 100644 --- a/lib/Cake/Log/Engine/SyslogLog.php +++ b/lib/Cake/Log/Engine/SyslogLog.php @@ -128,7 +128,8 @@ public function write($type, $message) { } /** - * Wrapper for openlog call + * Extracts the call to openlog() in order to run unit tests on it. This function + * will initialize the connection to the system logger * * @param string $ident the prefix to add to all messages logged * @param int $options the options flags to be used for logged messages @@ -140,7 +141,8 @@ protected function _open($ident, $options, $facility) { } /** - * Wrapper for syslog call + * Extracts the call to syslog() in order to run unit tests on it. This function + * will perform the actual write in the system logger * * @param int $priority * @param string $message From e466af05b935f0ab00e5b553c0610d831503544d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lorenzo=20Rodr=C3=ADguez?= Date: Thu, 16 May 2013 17:25:39 +0200 Subject: [PATCH 12/18] Removing copy pasted extra line --- lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php b/lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php index e6faabfd93a..ca6c0055e3a 100644 --- a/lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php +++ b/lib/Cake/Test/Case/Log/Engine/SyslogLogTest.php @@ -1,6 +1,5 @@ Date: Fri, 17 May 2013 10:36:17 +0200 Subject: [PATCH 13/18] CS fixes --- lib/Cake/Console/Command/Task/ProjectTask.php | 4 ++-- lib/Cake/I18n/I18n.php | 2 +- .../Case/Model/Behavior/TreeBehaviorNumberTest.php | 6 +++--- lib/Cake/Test/Case/Model/ModelReadTest.php | 14 +++++++------- lib/Cake/Test/Case/Model/ModelWriteTest.php | 6 +++--- lib/Cake/Test/Case/Network/Http/HttpSocketTest.php | 2 +- lib/Cake/Test/Case/Utility/SetTest.php | 12 ++++++------ lib/Cake/Test/Case/View/Helper/FormHelperTest.php | 6 +++--- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/Cake/Console/Command/Task/ProjectTask.php b/lib/Cake/Console/Command/Task/ProjectTask.php index e8bf783fa4a..1890dd8a15d 100644 --- a/lib/Cake/Console/Command/Task/ProjectTask.php +++ b/lib/Cake/Console/Command/Task/ProjectTask.php @@ -404,7 +404,7 @@ public function getPrefix() { } if ($this->interactive) { $this->hr(); - $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/Config/core.php to use prefix routing.')); + $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\', array(\'admin\')) in /app/Config/core.php to use prefix routing.')); $this->out(__d('cake_console', 'What would you like the prefix route to be?')); $this->out(__d('cake_console', 'Example: www.example.com/admin/controller')); while (!$admin) { @@ -412,7 +412,7 @@ public function getPrefix() { } if ($this->cakeAdmin($admin) !== true) { $this->out(__d('cake_console', 'Unable to write to /app/Config/core.php.')); - $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/Config/core.php to use prefix routing.')); + $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\', array(\'admin\')) in /app/Config/core.php to use prefix routing.')); $this->_stop(); } return $admin . '_'; diff --git a/lib/Cake/I18n/I18n.php b/lib/Cake/I18n/I18n.php index 9df77da75b5..890b072fc62 100644 --- a/lib/Cake/I18n/I18n.php +++ b/lib/Cake/I18n/I18n.php @@ -590,7 +590,7 @@ protected function _parseLiteralValue($string) { $string = $string[1]; if (substr($string, 0, 2) === $this->_escape . 'x') { $delimiter = $this->_escape . 'x'; - return implode('', array_map('chr', array_map('hexdec',array_filter(explode($delimiter, $string))))); + return implode('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string))))); } if (substr($string, 0, 2) === $this->_escape . 'd') { $delimiter = $this->_escape . 'd'; diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php index e6e5296e562..b4e881a0837 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php @@ -1046,7 +1046,7 @@ public function testRemove() { array($modelClass => array('name' => '1.2'))); $this->assertEquals($children, $expects); - $topNodes = $this->Tree->children(false, true,array('name')); + $topNodes = $this->Tree->children(false, true, array('name')); $expects = array(array($modelClass => array('name' => '1. Root')), array($modelClass => array('name' => '1.1'))); $this->assertEquals($topNodes, $expects); @@ -1077,7 +1077,7 @@ public function testRemoveLastTopParent() { $this->assertEquals($initialCount, $laterCount); $this->assertEquals($initialTopNodes, $laterTopNodes); - $topNodes = $this->Tree->children(false, true,array('name')); + $topNodes = $this->Tree->children(false, true, array('name')); $expects = array(array($modelClass => array('name' => '1.1')), array($modelClass => array('name' => '1.2')), array($modelClass => array('name' => '1. Root'))); @@ -1148,7 +1148,7 @@ public function testRemoveAndDelete() { ); $this->assertEquals($children, $expects); - $topNodes = $this->Tree->children(false, true,array('name')); + $topNodes = $this->Tree->children(false, true, array('name')); $expects = array(array($modelClass => array('name' => '1. Root'))); $this->assertEquals($topNodes, $expects); diff --git a/lib/Cake/Test/Case/Model/ModelReadTest.php b/lib/Cake/Test/Case/Model/ModelReadTest.php index 93dfab10ec0..b3c1dd5ecf1 100644 --- a/lib/Cake/Test/Case/Model/ModelReadTest.php +++ b/lib/Cake/Test/Case/Model/ModelReadTest.php @@ -232,7 +232,7 @@ public function testGroupBy() { array('Product' => array('type' => 'Music'), array('price' => 4)), array('Product' => array('type' => 'Toy'), array('price' => 3)) ); - $result = $Product->find('all',array( + $result = $Product->find('all', array( 'fields' => array('Product.type', 'MIN(Product.price) as price'), 'group' => 'Product.type', 'order' => 'Product.type ASC' @@ -7717,34 +7717,34 @@ public function testVirtualFields() { $this->assertFalse((bool)$result['Author']['false']); } - $result = $Post->find('first',array('fields' => array('author_id'))); + $result = $Post->find('first', array('fields' => array('author_id'))); $this->assertFalse(isset($result['Post']['two'])); $this->assertFalse(isset($result['Author']['false'])); - $result = $Post->find('first',array('fields' => array('author_id', 'two'))); + $result = $Post->find('first', array('fields' => array('author_id', 'two'))); $this->assertEquals(2, $result['Post']['two']); $this->assertFalse(isset($result['Author']['false'])); - $result = $Post->find('first',array('fields' => array('two'))); + $result = $Post->find('first', array('fields' => array('two'))); $this->assertEquals(2, $result['Post']['two']); $Post->id = 1; $result = $Post->field('two'); $this->assertEquals(2, $result); - $result = $Post->find('first',array( + $result = $Post->find('first', array( 'conditions' => array('two' => 2), 'limit' => 1 )); $this->assertEquals(2, $result['Post']['two']); - $result = $Post->find('first',array( + $result = $Post->find('first', array( 'conditions' => array('two <' => 3), 'limit' => 1 )); $this->assertEquals(2, $result['Post']['two']); - $result = $Post->find('first',array( + $result = $Post->find('first', array( 'conditions' => array('NOT' => array('two >' => 3)), 'limit' => 1 )); diff --git a/lib/Cake/Test/Case/Model/ModelWriteTest.php b/lib/Cake/Test/Case/Model/ModelWriteTest.php index 46ddd8a340f..18e81ff1aca 100644 --- a/lib/Cake/Test/Case/Model/ModelWriteTest.php +++ b/lib/Cake/Test/Case/Model/ModelWriteTest.php @@ -396,7 +396,7 @@ public function testCounterCacheUpdated() { $data[$Post->alias]['user_id'] = 301; $Post->save($data); - $users = $User->find('all',array('order' => 'User.id')); + $users = $User->find('all', array('order' => 'User.id')); $this->assertEquals(1, $users[0]['User']['post_count']); $this->assertEquals(2, $users[1]['User']['post_count']); } @@ -423,7 +423,7 @@ public function testCounterCacheWithNonstandardPrimaryKey() { $data[$Post->alias]['uid'] = 301; $Post->save($data); - $users = $User->find('all',array('order' => 'User.uid')); + $users = $User->find('all', array('order' => 'User.uid')); $this->assertEquals(1, $users[0]['User']['post_count']); $this->assertEquals(2, $users[1]['User']['post_count']); } @@ -551,7 +551,7 @@ public function testCounterCacheMultipleCaches() { )); $data[$Post->alias]['user_id'] = 301; $Post->save($data); - $result = $User->find('all',array('order' => 'User.id')); + $result = $User->find('all', array('order' => 'User.id')); $this->assertEquals(2, $result[0]['User']['post_count']); $this->assertEquals(1, $result[1]['User']['posts_published']); } diff --git a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php index 2bfb64f6595..71029212d14 100644 --- a/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php +++ b/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php @@ -1076,7 +1076,7 @@ public function testAuth() { 'pass' => 'hunter2' ) )); - $this->assertEquals($socket->request['auth'],array('Basic' => array('user' => 'joel', 'pass' => 'hunter2'))); + $this->assertEquals($socket->request['auth'], array('Basic' => array('user' => 'joel', 'pass' => 'hunter2'))); $this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic am9lbDpodW50ZXIy') !== false); } diff --git a/lib/Cake/Test/Case/Utility/SetTest.php b/lib/Cake/Test/Case/Utility/SetTest.php index 47efb8d3156..52d36335646 100644 --- a/lib/Cake/Test/Case/Utility/SetTest.php +++ b/lib/Cake/Test/Case/Utility/SetTest.php @@ -282,15 +282,15 @@ public function testSort() { $this->assertEquals($a, $b); $a = array( - array(7,6,4), - array(3,4,5), - array(3,2,array(1,1,1)), + array(7, 6, 4), + array(3, 4, 5), + array(3, 2, array(1, 1, 1)), ); $b = array( - array(3,2,array(1,1,1)), - array(3,4,5), - array(7,6,4), + array(3, 2, array(1, 1, 1)), + array(3, 4, 5), + array(7, 6, 4), ); $a = Set::sort($a, '{n}', 'asc'); diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 78ed898d0d1..711872dab24 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -3472,10 +3472,10 @@ public function testInputErrorEscape() { $this->Form->create('ValidateProfile'); $ValidateProfile = ClassRegistry::getObject('ValidateProfile'); $ValidateProfile->validationErrors['city'] = array('required
'); - $result = $this->Form->input('city',array('error' => array('attributes' => array('escape' => true)))); + $result = $this->Form->input('city', array('error' => array('attributes' => array('escape' => true)))); $this->assertRegExp('/required<br>/', $result); - $result = $this->Form->input('city',array('error' => array('attributes' => array('escape' => false)))); + $result = $this->Form->input('city', array('error' => array('attributes' => array('escape' => false)))); $this->assertRegExp('/required
/', $result); } @@ -8428,7 +8428,7 @@ public function testMultiRecordForm() { ); $this->assertTags($result, $expected); - $result = $this->Form->input('ValidateProfile.1.ValidateItem.2.created',array('empty' => true)); + $result = $this->Form->input('ValidateProfile.1.ValidateItem.2.created', array('empty' => true)); $expected = array( 'div' => array('class' => 'input date'), 'label' => array('for' => 'ValidateProfile1ValidateItem2CreatedMonth'), From a562d9c04e006bd2fd0c3687e8bc18d9abc1f96a Mon Sep 17 00:00:00 2001 From: TAKAHASHI Kunihiko Date: Fri, 17 May 2013 18:36:53 +0900 Subject: [PATCH 14/18] The assembly of the message was not correctly completed in specific Japanese. --- lib/Cake/Network/Email/CakeEmail.php | 2 +- .../Test/Case/Network/Email/CakeEmailTest.php | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/Email/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php index 4250893c036..8ab91f05c5b 100644 --- a/lib/Cake/Network/Email/CakeEmail.php +++ b/lib/Cake/Network/Email/CakeEmail.php @@ -1253,7 +1253,7 @@ protected function _wrap($message, $wrapLength = CakeEmail::LINE_LENGTH_MUST) { $formatted[] = ''; continue; } - if (!preg_match('/\<[a-z]/i', $line)) { + if (!preg_match('/<[a-z]+.+>/i', $line)) { $formatted = array_merge( $formatted, explode("\n", wordwrap($line, $wrapLength, "\n")) diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index 37991a169e7..ba52d3955c2 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1622,6 +1622,38 @@ public function testHeaderEncoding() { $this->assertContains('ってテーブルを作ってやってたらう', $result['message']); } + public function testWrapLongLine() { + $message = '' . str_repeat('1234567890', 100) . ""; + + $this->CakeEmail->reset(); + $this->CakeEmail->transport('Debug'); + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to('cake@cakephp.org'); + $this->CakeEmail->subject('Wordwrap Test'); + $this->CakeEmail->config(array('empty')); + $result = $this->CakeEmail->send($message); + $expected = "' . str_repeat('1234567890', 100) . "\r\n\r\n\r\n"; + $this->assertEquals($expected, $result['message']); + } + + public function testWrapForJapaneseEncoding() { + $this->skipIf(!function_exists('mb_convert_encoding')); + + $message = mb_convert_encoding('受け付けました', 'iso-2022-jp', 'UTF-8'); + + $this->CakeEmail->reset(); + $this->CakeEmail->transport('Debug'); + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to('cake@cakephp.org'); + $this->CakeEmail->subject('Wordwrap Test'); + $this->CakeEmail->config(array('empty')); + $this->CakeEmail->charset('iso-2022-jp'); + $this->CakeEmail->headerCharset('iso-2022-jp'); + $result = $this->CakeEmail->send($message); + $expected = "{$message}\r\n\r\n"; + $this->assertEquals($expected, $result['message']); + } + /** * Tests that the body is encoded using the configured charset * From f541260350e132d60ac42f8ec006aafe1fd2b337 Mon Sep 17 00:00:00 2001 From: TAKAHASHI Kunihiko Date: Fri, 17 May 2013 18:56:52 +0900 Subject: [PATCH 15/18] Add TestCase for Network/Email/CakeEmail.php --- .../Test/Case/Network/Email/CakeEmailTest.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index ba52d3955c2..b30e2d8a83d 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1623,7 +1623,7 @@ public function testHeaderEncoding() { } public function testWrapLongLine() { - $message = '' . str_repeat('1234567890', 100) . ""; + $message = '' . str_repeat('x', CakeEmail::LINE_LENGTH_MUST) . ""; $this->CakeEmail->reset(); $this->CakeEmail->transport('Debug'); @@ -1632,7 +1632,27 @@ public function testWrapLongLine() { $this->CakeEmail->subject('Wordwrap Test'); $this->CakeEmail->config(array('empty')); $result = $this->CakeEmail->send($message); - $expected = "' . str_repeat('1234567890', 100) . "\r\n\r\n\r\n"; + $expected = "' . str_repeat('x', CakeEmail::LINE_LENGTH_MUST) . "\r\n\r\n\r\n"; + $this->assertEquals($expected, $result['message']); + } + + public function testWrapIncludeTag() { + $message = 'CakePHP'; + + $this->CakeEmail->reset(); + $this->CakeEmail->transport('Debug'); + $this->CakeEmail->from('cake@cakephp.org'); + $this->CakeEmail->to('cake@cakephp.org'); + $this->CakeEmail->subject('Wordwrap Test'); + $this->CakeEmail->config(array('empty')); + $result = $this->CakeEmail->send($message); + $expected = "{$message}\r\n\r\n"; + $this->assertEquals($expected, $result['message']); + + $message = 'fooCakeEmail->send($message); + $expected = "{$message}\r\n\r\n"; $this->assertEquals($expected, $result['message']); } From e1d6bb2120ca512896bc18ec9ded42afb45117ee Mon Sep 17 00:00:00 2001 From: euromark Date: Fri, 17 May 2013 15:54:55 +0200 Subject: [PATCH 16/18] code is not translatable and should not be part of the translation strings --- lib/Cake/Console/Command/Task/ProjectTask.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Console/Command/Task/ProjectTask.php b/lib/Cake/Console/Command/Task/ProjectTask.php index 1890dd8a15d..8a83cdf45f9 100644 --- a/lib/Cake/Console/Command/Task/ProjectTask.php +++ b/lib/Cake/Console/Command/Task/ProjectTask.php @@ -404,15 +404,19 @@ public function getPrefix() { } if ($this->interactive) { $this->hr(); - $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\', array(\'admin\')) in /app/Config/core.php to use prefix routing.')); + $this->out(__d('cake_console', 'You need to enable %s in %s to use prefix routing.', + 'Configure::write(\'Routing.prefixes\', array(\'admin\'))', + '/app/Config/core.php')); $this->out(__d('cake_console', 'What would you like the prefix route to be?')); - $this->out(__d('cake_console', 'Example: www.example.com/admin/controller')); + $this->out(__d('cake_console', 'Example: %s', 'www.example.com/admin/controller')); while (!$admin) { $admin = $this->in(__d('cake_console', 'Enter a routing prefix:'), null, 'admin'); } if ($this->cakeAdmin($admin) !== true) { - $this->out(__d('cake_console', 'Unable to write to /app/Config/core.php.')); - $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\', array(\'admin\')) in /app/Config/core.php to use prefix routing.')); + $this->out(__d('cake_console', 'Unable to write to %s.', '/app/Config/core.php')); + $this->out(__d('cake_console', 'You need to enable %s in %s to use prefix routing.', + 'Configure::write(\'Routing.prefixes\', array(\'admin\'))', + '/app/Config/core.php')); $this->_stop(); } return $admin . '_'; From e23c4ffad90797cef2762be9a8e4f04beca9e657 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 17 May 2013 16:32:46 -0400 Subject: [PATCH 17/18] Fix empty response bodies when redirect URL's are empty. When redirecting XHR requests to an empty URL the response body should not be overwritten. Fixes #3835 --- .../Component/RequestHandlerComponent.php | 3 +++ .../Component/RequestHandlerComponentTest.php | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/Cake/Controller/Component/RequestHandlerComponent.php b/lib/Cake/Controller/Component/RequestHandlerComponent.php index 85a51f33891..89e50b3036f 100644 --- a/lib/Cake/Controller/Component/RequestHandlerComponent.php +++ b/lib/Cake/Controller/Component/RequestHandlerComponent.php @@ -244,6 +244,9 @@ public function beforeRedirect(Controller $controller, $url, $status = null, $ex if (!$this->request->is('ajax')) { return; } + if (empty($url)) { + return; + } $_SERVER['REQUEST_METHOD'] = 'GET'; foreach ($_POST as $key => $val) { unset($_POST[$key]); diff --git a/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php b/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php index 45c65604823..8beb0ce7564 100644 --- a/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php @@ -411,6 +411,23 @@ public function testNonAjaxRedirect() { $this->assertNull($this->RequestHandler->beforeRedirect($this->Controller, '/')); } +/** + * test that redirects with ajax and no url don't do anything. + * + * @return void + */ + public function testAjaxRedirectWithNoUrl() { + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'; + $this->Controller->response = $this->getMock('CakeResponse'); + + $this->Controller->response->expects($this->never()) + ->method('body'); + + $this->RequestHandler->initialize($this->Controller); + $this->RequestHandler->startup($this->Controller); + $this->assertNull($this->RequestHandler->beforeRedirect($this->Controller, null)); + } + /** * testRenderAs method * From f8c6138ad7ec0bef8ddcdd126d8b74ef81627e40 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 18 May 2013 12:19:35 -0400 Subject: [PATCH 18/18] Fix incorrect exception type when double slash paths are used. Fixes #3838 --- lib/Cake/Routing/Filter/AssetDispatcher.php | 2 +- .../Case/Routing/Filter/AssetDispatcherTest.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Routing/Filter/AssetDispatcher.php b/lib/Cake/Routing/Filter/AssetDispatcher.php index d1e8db107b1..0f11d2edf22 100644 --- a/lib/Cake/Routing/Filter/AssetDispatcher.php +++ b/lib/Cake/Routing/Filter/AssetDispatcher.php @@ -124,7 +124,7 @@ protected function _getAssetFile($url) { } $plugin = Inflector::camelize($parts[0]); - if (CakePlugin::loaded($plugin)) { + if ($plugin && CakePlugin::loaded($plugin)) { unset($parts[0]); $fileFragment = urldecode(implode(DS, $parts)); $pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS; diff --git a/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php b/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php index 52be23bc5a1..758798dc6e1 100644 --- a/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php +++ b/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php @@ -121,4 +121,21 @@ public function testNotModified() { $this->assertSame($response, $filter->beforeDispatch($event)); $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified()); } + +/** + * Test that no exceptions are thrown for //index.php type urls. + * + * @return void + */ + public function test404OnDoubleSlash() { + $filter = new AssetDispatcher(); + + $response = $this->getMock('CakeResponse', array('_sendHeader')); + $request = new CakeRequest('//index.php'); + $event = new CakeEvent('Dispatcher.beforeRequest', $this, compact('request', 'response')); + + $this->assertNull($filter->beforeDispatch($event)); + $this->assertFalse($event->isStopped()); + } + }