From 4b3a8ea348df96c0a62bb29e597fc26ff73a93ca Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sun, 1 Jul 2012 18:25:14 -0430 Subject: [PATCH 01/27] Update version number to 2.2.0 --- lib/Cake/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/VERSION.txt b/lib/Cake/VERSION.txt index e7ba0f1ccc2..366cf87786f 100644 --- a/lib/Cake/VERSION.txt +++ b/lib/Cake/VERSION.txt @@ -17,4 +17,4 @@ // @license MIT License (http://www.opensource.org/licenses/mit-license.php) // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -2.2.0-RC2 +2.2.0 From 31033239bd06750358a8aea3542392209234278a Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 2 Jul 2012 23:34:37 -0400 Subject: [PATCH 02/27] Add missing urlencoding to nested named parameters. Fixes #2988 --- lib/Cake/Routing/Route/CakeRoute.php | 4 ++-- lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Routing/Route/CakeRoute.php b/lib/Cake/Routing/Route/CakeRoute.php index b3121de3998..8fab212cf57 100644 --- a/lib/Cake/Routing/Route/CakeRoute.php +++ b/lib/Cake/Routing/Route/CakeRoute.php @@ -497,9 +497,9 @@ protected function _writeUrl($params) { $named = array(); foreach ($params['named'] as $key => $value) { if (is_array($value)) { - $flat = Hash::flatten($value, ']['); + $flat = Hash::flatten($value, '%5D%5B'); foreach ($flat as $namedKey => $namedValue) { - $named[] = $key . "[$namedKey]" . $separator . rawurlencode($namedValue); + $named[] = $key . "%5B{$namedKey}%5D" . $separator . rawurlencode($namedValue); } } else { $named[] = $key . $separator . rawurlencode($value); diff --git a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php index 01799363f63..c393dc27c65 100644 --- a/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php +++ b/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php @@ -798,7 +798,7 @@ public function testMatchNamedParametersArray() { ) ); $result = $route->match($url); - $expected = '/posts/index/filter[0]:one/filter[model]:value'; + $expected = '/posts/index/filter%5B0%5D:one/filter%5Bmodel%5D:value'; $this->assertEquals($expected, $result); $url = array( @@ -813,7 +813,7 @@ public function testMatchNamedParametersArray() { ) ); $result = $route->match($url); - $expected = '/posts/index/filter[0]:one/filter[model][0]:two/filter[model][order]:field'; + $expected = '/posts/index/filter%5B0%5D:one/filter%5Bmodel%5D%5B0%5D:two/filter%5Bmodel%5D%5Border%5D:field'; $this->assertEquals($expected, $result); } From 86a74e38871e8eec4c6dbb20ad6cf63462b38bea Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Mon, 2 Jul 2012 21:19:02 +0700 Subject: [PATCH 03/27] fix: windows console may not have ansi color support --- lib/Cake/Log/Engine/ConsoleLog.php | 7 ++++++- .../Test/Case/Log/Engine/ConsoleLogTest.php | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Log/Engine/ConsoleLog.php b/lib/Cake/Log/Engine/ConsoleLog.php index 24d4fab4d8a..255be190db1 100644 --- a/lib/Cake/Log/Engine/ConsoleLog.php +++ b/lib/Cake/Log/Engine/ConsoleLog.php @@ -49,11 +49,16 @@ class ConsoleLog extends BaseLog { */ public function __construct($config = array()) { parent::__construct($config); + if (DS == '\\' && !(bool)env('ANSICON')) { + $outputAs = ConsoleOutput::PLAIN; + } else { + $outputAs = ConsoleOutput::COLOR; + } $config = Hash::merge(array( 'stream' => 'php://stderr', 'types' => null, 'scopes' => array(), - 'outputAs' => ConsoleOutput::COLOR, + 'outputAs' => $outputAs, ), $this->_config); $config = $this->config($config); if ($config['stream'] instanceof ConsoleOutput) { diff --git a/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php b/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php index 6db6bf8d147..e7868270672 100644 --- a/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php +++ b/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php @@ -116,4 +116,21 @@ public function testCombinedLogWriting() { $this->assertContains($message, $logOutput); } +/** + * test default value of stream 'outputAs' + */ + public function testDefaultOutputAs() { + TestCakeLog::config('test_console_log', array( + 'engine' => 'TestConsoleLog', + )); + if (DS == '\\' && !(bool)env('ANSICON')) { + $expected = ConsoleOutput::PLAIN; + } else { + $expected = ConsoleOutput::COLOR; + } + $stream = TestCakeLog::stream('test_console_log'); + $config = $stream->config(); + $this->assertEquals($expected, $config['outputAs']); + } + } From 22373868bb0e58d7a40da6c8b4c346b1d0830f12 Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Tue, 3 Jul 2012 19:23:21 +0700 Subject: [PATCH 04/27] if blackHoleCallback is set, requests _must_ get blackholed --- .../Component/SecurityComponent.php | 2 +- .../Component/SecurityComponentTest.php | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/SecurityComponent.php b/lib/Cake/Controller/Component/SecurityComponent.php index 1a204389569..5c24a2e5fa9 100644 --- a/lib/Cake/Controller/Component/SecurityComponent.php +++ b/lib/Cake/Controller/Component/SecurityComponent.php @@ -590,7 +590,7 @@ protected function _callback(Controller $controller, $method, $params = array()) if (is_callable(array($controller, $method))) { return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params); } else { - return null; + throw new BadRequestException(__d('cake_dev', 'The request has been black-holed')); } } diff --git a/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php b/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php index f7f592cc466..84f78036b9a 100644 --- a/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php @@ -107,6 +107,20 @@ public function header($status) { } +class BrokenCallbackController extends Controller { + + public $name = 'UncallableCallback'; + + public $components = array('Session', 'TestSecurity'); + + public function index() { + } + + protected function _fail() { + } + +} + /** * SecurityComponentTest class * @@ -161,6 +175,25 @@ public function tearDown() { unset($this->Controller); } +/** + * Test that requests are still blackholed when controller has incorrect + * visibility keyword in the blackhole callback + * + * @expectedException BadRequestException + */ + public function testBlackholeWithBrokenCallback() { + $request = new CakeRequest('posts/index', false); + $request->addParams(array( + 'controller' => 'posts', 'action' => 'index') + ); + $this->Controller = new BrokenCallbackController($request); + $this->Controller->Components->init($this->Controller); + $this->Controller->Security = $this->Controller->TestSecurity; + $this->Controller->Security->blackHoleCallback = '_fail'; + $this->Controller->Security->startup($this->Controller); + $this->Controller->Security->blackHole($this->Controller, 'csrf'); + } + /** * test that initialize can set properties. * From e61f636bc7e6d9bcc53ed2dba7f4041bfd7a42dc Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 3 Jul 2012 20:48:10 -0400 Subject: [PATCH 05/27] Fix double base dir in image() with fullBase. Fixes #2991 --- .../Test/Case/View/Helper/HtmlHelperTest.php | 16 ++++++++++++++++ lib/Cake/View/Helper.php | 8 +++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php index e9feffd0222..678a1df234d 100644 --- a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php @@ -361,7 +361,14 @@ public function testImageTag() { $result = $this->Html->image('test.gif?one=two&three=four'); $this->assertTags($result, array('img' => array('src' => 'img/test.gif?one=two&three=four', 'alt' => ''))); + } +/** + * Test that image() works with fullBase and a webroot not equal to / + * + * @return void + */ + public function testImageWithFullBase() { $result = $this->Html->image('test.gif', array('fullBase' => true)); $here = $this->Html->url('/', true); $this->assertTags($result, array('img' => array('src' => $here . 'img/test.gif', 'alt' => ''))); @@ -369,6 +376,15 @@ public function testImageTag() { $result = $this->Html->image('sub/test.gif', array('fullBase' => true)); $here = $this->Html->url('/', true); $this->assertTags($result, array('img' => array('src' => $here . 'img/sub/test.gif', 'alt' => ''))); + + $request = $this->Html->request; + $request->webroot = '/myproject/'; + $request->base = '/myproject'; + Router::setRequestInfo($request); + + $result = $this->Html->image('sub/test.gif', array('fullBase' => true)); + $here = $this->Html->url('/', true); + $this->assertTags($result, array('img' => array('src' => $here . 'img/sub/test.gif', 'alt' => ''))); } /** diff --git a/lib/Cake/View/Helper.php b/lib/Cake/View/Helper.php index a0b4aef4e49..f6b17acf529 100644 --- a/lib/Cake/View/Helper.php +++ b/lib/Cake/View/Helper.php @@ -313,10 +313,12 @@ public function assetUrl($path, $options = array()) { $path = h($this->assetTimestamp($this->webroot($path))); if (!empty($options['fullBase'])) { - if ($path[0] == '/') { - $path = substr($path, 1); + $base = $this->url('/', true); + $len = strlen($this->request->webroot); + if ($len) { + $base = substr($base, 0, -$len); } - $path = $this->url('/', true) . $path; + $path = $base . $path; } } From de703a26923a4f17db3a2cae91c437784de5be08 Mon Sep 17 00:00:00 2001 From: Simon East Date: Fri, 6 Jul 2012 11:49:44 +1000 Subject: [PATCH 06/27] Fix for CakeEmailTest.php that failed unless using 'localhost' --- lib/Cake/Test/Case/Network/Email/CakeEmailTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index 22591c4b67b..dbbf2025a6b 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1119,7 +1119,7 @@ public function testSendRenderWithImage() { $this->CakeEmail->template('image'); $this->CakeEmail->emailFormat('html'); - $expected = 'cool image'; + $expected = 'cool image'; $result = $this->CakeEmail->send(); $this->assertContains($expected, $result['message']); } From e10f6f57a3c186f91f264f8b016e2259b682d644 Mon Sep 17 00:00:00 2001 From: Rodrigo Moyle Date: Mon, 2 Jul 2012 19:18:12 -0300 Subject: [PATCH 07/27] Fix notice error when parsing input data. Prevent error in CakeRequest from parsing input data in PUT and DELETE requests. Fixes #3002 Signed-off-by: mark_story --- lib/Cake/Network/CakeRequest.php | 6 +++--- lib/Cake/Test/Case/Network/CakeRequestTest.php | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index 7342f123a46..cadbbbd0cc2 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -175,7 +175,8 @@ protected function _processPost() { if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) { $this->data['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE'); } - if (isset($this->data['_method'])) { + $isArray = is_array($this->data); + if ($isArray && isset($this->data['_method'])) { if (!empty($_SERVER)) { $_SERVER['REQUEST_METHOD'] = $this->data['_method']; } else { @@ -183,8 +184,7 @@ protected function _processPost() { } unset($this->data['_method']); } - - if (isset($this->data['data'])) { + if ($isArray && isset($this->data['data'])) { $data = $this->data['data']; if (count($this->data) <= 1) { $this->data = $data; diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index 321e92d9206..8ef0e186881 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -300,6 +300,22 @@ public function testPutParsing() { $this->assertEquals($data, $request->data); } +/** + * test parsing json PUT data into the object. + * + * @return void + */ + public function testPutParsingJSON() { + $_SERVER['REQUEST_METHOD'] = 'PUT'; + $_SERVER['CONTENT_TYPE'] = 'application/json'; + + $request = $this->getMock('TestCakeRequest', array('_readInput')); + $request->expects($this->at(0))->method('_readInput') + ->will($this->returnValue('{Article":["title"]}')); + $request->reConstruct(); + $this->assertEquals('{Article":["title"]}', $request->data); + } + /** * test parsing of FILES array * From f528bb29ba87bec6f20e0e66b69b72821416b60b Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 5 Jul 2012 22:42:57 -0400 Subject: [PATCH 08/27] Fix lint error. --- lib/Cake/Controller/Component/SecurityComponent.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Cake/Controller/Component/SecurityComponent.php b/lib/Cake/Controller/Component/SecurityComponent.php index 5c24a2e5fa9..6973febe5d6 100644 --- a/lib/Cake/Controller/Component/SecurityComponent.php +++ b/lib/Cake/Controller/Component/SecurityComponent.php @@ -585,6 +585,7 @@ protected function _expireTokens($tokens) { * @param string $method Method to execute * @param array $params Parameters to send to method * @return mixed Controller callback method's response + * @throws BadRequestException When a the blackholeCallback is not callable. */ protected function _callback(Controller $controller, $method, $params = array()) { if (is_callable(array($controller, $method))) { From 591022f182df42c10af7fb0f6bd1d045bf557b40 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 5 Jul 2012 22:56:45 -0400 Subject: [PATCH 09/27] Make test case use SERVER_NAME conditionally. --- lib/Cake/Test/Case/Network/Email/CakeEmailTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index dbbf2025a6b..cde649558f2 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1119,7 +1119,8 @@ public function testSendRenderWithImage() { $this->CakeEmail->template('image'); $this->CakeEmail->emailFormat('html'); - $expected = 'cool image'; + $server = env('SERVER_NAME') ? env('SERVER_NAME') : 'localhost'; + $expected = 'cool image'; $result = $this->CakeEmail->send(); $this->assertContains($expected, $result['message']); } From ed4493da0c9492d4d91eda000924fb7c582b9dc8 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Fri, 6 Jul 2012 16:00:13 -0430 Subject: [PATCH 10/27] Automatic console logging streams were not respecting --quiet --- lib/Cake/Console/Shell.php | 41 +++++++++++++++++------- lib/Cake/Test/Case/Console/ShellTest.php | 34 +++++++++++++++++++- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index a23a38fb3c0..801410ba56f 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -165,23 +165,13 @@ public function __construct($stdout = null, $stderr = null, $stdin = null) { if ($this->stdout == null) { $this->stdout = new ConsoleOutput('php://stdout'); } - CakeLog::config('stdout', array( - 'engine' => 'ConsoleLog', - 'types' => array('notice', 'info'), - 'stream' => $this->stdout, - )); if ($this->stderr == null) { $this->stderr = new ConsoleOutput('php://stderr'); } - CakeLog::config('stderr', array( - 'engine' => 'ConsoleLog', - 'types' => array('emergency', 'alert', 'critical', 'error', 'warning', 'debug'), - 'stream' => $this->stderr, - )); if ($this->stdin == null) { $this->stdin = new ConsoleInput('php://stdin'); } - + $this->_useLogger(); $parent = get_parent_class($this); if ($this->tasks !== null && $this->tasks !== false) { $this->_mergeVars(array('tasks'), $parent, true); @@ -379,6 +369,10 @@ public function runCommand($command, $argv) { return false; } + if (!empty($this->params['quiet'])) { + $this->_useLogger(false); + } + $this->command = $command; if (!empty($this->params['help'])) { return $this->_displayHelp($command); @@ -825,4 +819,29 @@ protected function _pluginPath($pluginName) { return current(App::path('plugins')) . $pluginName . DS; } +/** + * Used to enable or disable logging stream output to stdout and stderr + * If you don't wish to see in your stdout or stderr everything that is logged + * through CakeLog, call this function with first param as false + * + * @param boolean $enable wheter to enable CakeLog output or not + * @return void + **/ + protected function _useLogger($enable = true) { + if (!$enable) { + CakeLog::drop('stdout'); + CakeLog::drop('stderr'); + return; + } + CakeLog::config('stdout', array( + 'engine' => 'ConsoleLog', + 'types' => array('notice', 'info'), + 'stream' => $this->stdout, + )); + CakeLog::config('stderr', array( + 'engine' => 'ConsoleLog', + 'types' => array('emergency', 'alert', 'critical', 'error', 'warning', 'debug'), + 'stream' => $this->stderr, + )); + } } diff --git a/lib/Cake/Test/Case/Console/ShellTest.php b/lib/Cake/Test/Case/Console/ShellTest.php index 4d7248243fc..875b23dccd7 100644 --- a/lib/Cake/Test/Case/Console/ShellTest.php +++ b/lib/Cake/Test/Case/Console/ShellTest.php @@ -80,6 +80,10 @@ public function mergeVars($properties, $class, $normalize = true) { return $this->_mergeVars($properties, $class, $normalize); } + public function useLogger($enable = true) { + $this->_useLogger($enable); + } + } /** @@ -825,7 +829,7 @@ public function testFileAndConsoleLogging() { require_once CORE_TEST_CASES . DS . 'Log' . DS . 'Engine' . DS . 'ConsoleLogTest.php'; $mock = $this->getMock('ConsoleLog', array('write'), array( array('types' => 'error'), - )); + )); TestCakeLog::config('console', array( 'engine' => 'ConsoleLog', 'stream' => 'php://stderr', @@ -840,4 +844,32 @@ public function testFileAndConsoleLogging() { $this->assertContains($this->Shell->testMessage, $contents); } +/** + * Tests that _useLogger works properly + * + * @return void + **/ + public function testProtectedUseLogger() { + CakeLog::drop('stdout'); + CakeLog::drop('stderr'); + $this->Shell->useLogger(true); + $this->assertNotEmpty(CakeLog::stream('stdout')); + $this->assertNotEmpty(CakeLog::stream('stderr')); + $this->Shell->useLogger(false); + $this->assertFalse(CakeLog::stream('stdout')); + $this->assertFalse(CakeLog::stream('stderr')); + } + +/** + * Test file and console and logging quiet output + */ + public function testQuietLog() { + $output = $this->getMock('ConsoleOutput', array(), array(), '', false); + $error = $this->getMock('ConsoleOutput', array(), array(), '', false); + $in = $this->getMock('ConsoleInput', array(), array(), '', false); + $this->Shell = $this->getMock('ShellTestShell', array('_useLogger'), array($output, $error, $in)); + $this->Shell->expects($this->once())->method('_useLogger')->with(false); + $this->Shell->runCommand('foo', array('--quiet')); + } + } From 1c0b6c076a15516688df5c6474392fa8e79bb010 Mon Sep 17 00:00:00 2001 From: Thomas von Hassel Date: Fri, 6 Jul 2012 16:28:30 +0300 Subject: [PATCH 11/27] Update afterSave to ensure created entires have all translated fields present Without all fields being present, find() will be unable to find the translated records. Fixes #3009 --- lib/Cake/Model/Behavior/TranslateBehavior.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/Cake/Model/Behavior/TranslateBehavior.php b/lib/Cake/Model/Behavior/TranslateBehavior.php index 2662506f880..dfd88d6c989 100644 --- a/lib/Cake/Model/Behavior/TranslateBehavior.php +++ b/lib/Cake/Model/Behavior/TranslateBehavior.php @@ -392,6 +392,16 @@ public function afterSave(Model $model, $created) { unset($this->runtime[$model->alias]['beforeValidate'], $this->runtime[$model->alias]['beforeSave']); $conditions = array('model' => $model->alias, 'foreign_key' => $model->id); $RuntimeModel = $this->translateModel($model); + + $fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']); + if ($created) { + foreach ($fields as $field) { + if (!isset($tempData[$field])) { + //set the field value to an empty string + $tempData[$field] = ''; + } + } + } foreach ($tempData as $field => $value) { unset($conditions['content']); From 5e680cb292a51a3ef8a01bece67042ce2d503fd6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 7 Jul 2012 12:02:05 -0400 Subject: [PATCH 12/27] Add tests for translate + partial fields. Refs #3009 --- .../Model/Behavior/TranslateBehaviorTest.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php b/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php index e9e893bae88..2593d443e65 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php @@ -531,6 +531,34 @@ public function testSaveCreate() { $this->assertEquals($expected, $result); } +/** + * Test that saving only some of the translated fields allows the record to be found again. + * + * @return void + */ + public function testSavePartialFields() { + $this->loadFixtures('Translate', 'TranslatedItem'); + + $TestModel = new TranslatedItem(); + $TestModel->locale = 'spa'; + $data = array( + 'slug' => 'fourth_translated', + 'title' => 'Leyenda #4', + ); + $TestModel->create($data); + $TestModel->save(); + $result = $TestModel->read(); + $expected = array( + 'TranslatedItem' => array( + 'id' => $TestModel->id, + 'translated_article_id' => null, + 'locale' => 'spa', + 'content' => '', + ) + $data + ); + $this->assertEquals($expected, $result); + } + /** * testSaveUpdate method * From 73d44c5f6bcdb2874aa9c3d7413c51aeccea9fb1 Mon Sep 17 00:00:00 2001 From: Ilie Pandia Date: Sun, 8 Jul 2012 07:33:14 +0300 Subject: [PATCH 13/27] Fixed some typos in the comments in this file. This helps with type hinting in IDEs that support that. --- lib/Cake/Routing/Dispatcher.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Routing/Dispatcher.php b/lib/Cake/Routing/Dispatcher.php index 88a9a1ad877..bf3e3954e8a 100644 --- a/lib/Cake/Routing/Dispatcher.php +++ b/lib/Cake/Routing/Dispatcher.php @@ -43,7 +43,7 @@ class Dispatcher implements CakeEventListener { /** * Event manager, used to handle dispatcher filters * - * @var CakeEventMaanger + * @var CakeEventManager */ protected $_eventManager; @@ -62,7 +62,7 @@ public function __construct($base = false) { * Returns the CakeEventManager instance or creates one if none was * creted. Attaches the default listeners and filters * - * @return CakeEventmanger + * @return CakeEventManager */ public function getEventManager() { if (!$this->_eventManager) { From 39715bcd89239dc5aaf219b99032ffe95a9bb26c Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 10 Jul 2012 20:33:49 -0430 Subject: [PATCH 14/27] Adding missing afterValidate callback to behaviors, Fixes #3024 --- lib/Cake/Model/BehaviorCollection.php | 1 + lib/Cake/Model/ModelBehavior.php | 11 +++++ .../Case/Model/BehaviorCollectionTest.php | 44 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/lib/Cake/Model/BehaviorCollection.php b/lib/Cake/Model/BehaviorCollection.php index 76c1996283d..fff3e7d5b4a 100644 --- a/lib/Cake/Model/BehaviorCollection.php +++ b/lib/Cake/Model/BehaviorCollection.php @@ -285,6 +285,7 @@ public function implementedEvents() { 'Model.beforeFind' => 'trigger', 'Model.afterFind' => 'trigger', 'Model.beforeValidate' => 'trigger', + 'Model.afterValidate' => 'trigger', 'Model.beforeSave' => 'trigger', 'Model.afterSave' => 'trigger', 'Model.beforeDelete' => 'trigger', diff --git a/lib/Cake/Model/ModelBehavior.php b/lib/Cake/Model/ModelBehavior.php index 0ad9a4da9d4..141b9d59cf6 100644 --- a/lib/Cake/Model/ModelBehavior.php +++ b/lib/Cake/Model/ModelBehavior.php @@ -146,6 +146,17 @@ public function beforeValidate(Model $model) { return true; } +/** + * afterValidate is called just after model data was validated, you can use this callback + * to perform any data cleanup or preparation if needed + * + * @param Model $model Model using this behavior + * @return mixed False will stop this event from being passed to other behaviors + */ + public function afterValidate(Model $model) { + return true; + } + /** * beforeSave is called before a model is saved. Returning false from a beforeSave callback * will abort the save operation. diff --git a/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php b/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php index b05355d92cd..b2b26b7f147 100644 --- a/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php +++ b/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php @@ -194,6 +194,29 @@ public function beforeValidate(Model $model) { } } +/** + * afterValidate method + * + * @param Model $model + * @param bool $cascade + * @return void + */ + public function afterValidate(Model $model) { + $settings = $this->settings[$model->alias]; + if (!isset($settings['afterValidate']) || $settings['afterValidate'] == 'off') { + return parent::afterValidate($model); + } + switch ($settings['afterValidate']) { + case 'on': + return false; + break; + case 'test': + $model->data = array('foo'); + return true; + break; + } + } + /** * beforeDelete method * @@ -966,6 +989,27 @@ public function testBehaviorValidateCallback() { $this->assertSame($Apple->whitelist, array('unknown', 'name')); } +/** + * testBehaviorValidateAfterCallback method + * + * @return void + */ + public function testBehaviorValidateAfterCallback() { + $Apple = new Apple(); + + $Apple->Behaviors->attach('Test'); + $this->assertSame($Apple->validates(), true); + + $Apple->Behaviors->attach('Test', array('afterValidate' => 'on')); + $this->assertSame($Apple->validates(), true); + $this->assertSame($Apple->validationErrors, array()); + + $Apple->Behaviors->attach('Test', array('afterValidate' => 'test')); + $Apple->data = array('bar'); + $Apple->validates(); + $this->assertEquals(array('foo'), $Apple->data); + } + /** * testBehaviorValidateMethods method * From db247558b07113efa62c7e78ae7e654bc4572735 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 10 Jul 2012 20:46:56 -0430 Subject: [PATCH 15/27] Correctly passing ellipsis options to all internal method calls insie PaginatorHelper::numbers(), under some combinations of modulus/limit it would not get passed even though there are pages in between to show --- lib/Cake/View/Helper/PaginatorHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/View/Helper/PaginatorHelper.php b/lib/Cake/View/Helper/PaginatorHelper.php index 22b375e98bc..05a9935b114 100644 --- a/lib/Cake/View/Helper/PaginatorHelper.php +++ b/lib/Cake/View/Helper/PaginatorHelper.php @@ -701,7 +701,7 @@ public function numbers($options = array()) { if ($offset < $start - 1) { $out .= $this->first($offset, compact('tag', 'separator', 'ellipsis', 'class')); } else { - $out .= $this->first($offset, compact('tag', 'separator', 'class') + array('after' => $separator)); + $out .= $this->first($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('after' => $separator)); } } @@ -735,7 +735,7 @@ public function numbers($options = array()) { if ($offset <= $last && $params['pageCount'] - $end > $offset) { $out .= $this->last($offset, compact('tag', 'separator', 'ellipsis', 'class')); } else { - $out .= $this->last($offset, compact('tag', 'separator', 'class') + array('before' => $separator)); + $out .= $this->last($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('before' => $separator)); } } From b7415525c8de61ff7261f4a5b45ab128aacb7a66 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 11 Jul 2012 15:50:50 -0400 Subject: [PATCH 16/27] Fix missing line breaks. Fixes #3028 --- lib/Cake/Console/Command/Task/ModelTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php index 5f211ee45d6..b308454de4f 100644 --- a/lib/Cake/Console/Command/Task/ModelTask.php +++ b/lib/Cake/Console/Command/Task/ModelTask.php @@ -414,7 +414,7 @@ public function fieldValidation($fieldName, $metaData, $primaryKey = 'id') { for ($i = 1, $m = $defaultChoice / 2; $i < $m; $i++) { $line = sprintf("%2d. %s", $i, $this->_validations[$i]); $optionText .= $line . str_repeat(" ", 31 - strlen($line)); - $optionText .= sprintf("%2d. %s", $m + $i, $this->_validations[$m + $i]); + $optionText .= sprintf("%2d. %s\n", $m + $i, $this->_validations[$m + $i]); } $this->out($optionText); $this->out(__d('cake_console', "%s - Do not do any validation on this field.", $defaultChoice)); From 3baaecc81c629aab0e3b0730000a30f859e42de7 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 11 Jul 2012 15:54:24 -0400 Subject: [PATCH 17/27] Type check before unset() Calling unset() on string indices fails fatally on 5.3.x and lower. Fixes #3027 --- lib/Cake/Controller/Component/SecurityComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/SecurityComponent.php b/lib/Cake/Controller/Component/SecurityComponent.php index 6973febe5d6..3b5eb8669db 100644 --- a/lib/Cake/Controller/Component/SecurityComponent.php +++ b/lib/Cake/Controller/Component/SecurityComponent.php @@ -229,7 +229,7 @@ public function startup(Controller $controller) { } } $this->generateToken($controller->request); - if ($isPost) { + if ($isPost && is_array($controller->request->data)) { unset($controller->request->data['_Token']); } } From 8fc5726920374f40afa773c811eca0c2bc5f0a12 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 11 Jul 2012 21:39:32 -0400 Subject: [PATCH 18/27] Remove trailing whitespace. --- lib/Cake/Model/Behavior/TranslateBehavior.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Model/Behavior/TranslateBehavior.php b/lib/Cake/Model/Behavior/TranslateBehavior.php index dfd88d6c989..387a37f0f31 100644 --- a/lib/Cake/Model/Behavior/TranslateBehavior.php +++ b/lib/Cake/Model/Behavior/TranslateBehavior.php @@ -392,7 +392,7 @@ public function afterSave(Model $model, $created) { unset($this->runtime[$model->alias]['beforeValidate'], $this->runtime[$model->alias]['beforeSave']); $conditions = array('model' => $model->alias, 'foreign_key' => $model->id); $RuntimeModel = $this->translateModel($model); - + $fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']); if ($created) { foreach ($fields as $field) { From 46f8de72a2be00ab10ebbf6536a50b4982f34701 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 13 Jul 2012 22:58:07 -0400 Subject: [PATCH 19/27] Fix web runner showing fails as passes when show_passes is on. Fixes #3035 --- lib/Cake/TestSuite/Reporter/CakeBaseReporter.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php b/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php index 6ac39c079ba..27dfbd7906f 100644 --- a/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php +++ b/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php @@ -201,6 +201,9 @@ public function startTest(PHPUnit_Framework_Test $test) { */ public function endTest(PHPUnit_Framework_Test $test, $time) { $this->numAssertions += $test->getNumAssertions(); + if ($test->hasFailed()) { + return; + } $this->paintPass($test, $time); } From 6c905411bac66caad5e220a70e3d561b8a648507 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 14 Jul 2012 11:53:37 -0400 Subject: [PATCH 20/27] Fix XML decoding attack via external entities. --- lib/Cake/Test/Case/Utility/XmlTest.php | 18 ++++++++++ lib/Cake/Utility/Xml.php | 46 ++++++++++++++++++-------- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/XmlTest.php b/lib/Cake/Test/Case/Utility/XmlTest.php index a2693713a39..23517314d11 100644 --- a/lib/Cake/Test/Case/Utility/XmlTest.php +++ b/lib/Cake/Test/Case/Utility/XmlTest.php @@ -1039,4 +1039,22 @@ public function testAmpInText() { $this->assertContains('mark & mark', $result); } +/** + * Test that entity loading is disabled by default. + * + * @return void + */ + public function testNoEntityLoading() { + $file = CAKE . 'VERSION.txt'; + $xml = <<]> + + &payload; + +XML; + $result = Xml::build($xml); + $this->assertEquals('', (string)$result->xxe); + } + } diff --git a/lib/Cake/Utility/Xml.php b/lib/Cake/Utility/Xml.php index eb5c6d0f8ea..f8662b282fc 100644 --- a/lib/Cake/Utility/Xml.php +++ b/lib/Cake/Utility/Xml.php @@ -74,6 +74,8 @@ class Xml { * ### Options * * - `return` Can be 'simplexml' to return object of SimpleXMLElement or 'domdocument' to return DOMDocument. + * - `loadEntities` Defaults to false. Set to true to enable loading of ` (string)$options); } $defaults = array( - 'return' => 'simplexml' + 'return' => 'simplexml', + 'loadEntities' => false, ); $options = array_merge($defaults, $options); if (is_array($input) || is_object($input)) { return self::fromArray((array)$input, $options); } elseif (strpos($input, '<') !== false) { - if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') { - return new SimpleXMLElement($input, LIBXML_NOCDATA); - } - $dom = new DOMDocument(); - $dom->loadXML($input); - return $dom; + return self::_loadXml($input, $options); } elseif (file_exists($input) || strpos($input, 'http://') === 0 || strpos($input, 'https://') === 0) { - if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') { - return new SimpleXMLElement($input, LIBXML_NOCDATA, true); - } - $dom = new DOMDocument(); - $dom->load($input); - return $dom; + $input = file_get_contents($input); + return self::_loadXml($input, $options); } elseif (!is_string($input)) { throw new XmlException(__d('cake_dev', 'Invalid input.')); } throw new XmlException(__d('cake_dev', 'XML cannot be read.')); } +/** + * Parse the input data and create either a SimpleXmlElement object or a DOMDocument. + * + * @param string $input The input to load. + * @param array $options The options to use. See Xml::build() + * @return SimpleXmlElement|DOMDocument. + */ + protected static function _loadXml($input, $options) { + $hasDisable = function_exists('libxml_disable_entity_loader'); + $internalErrors = libxml_use_internal_errors(true); + if ($hasDisable && !$options['loadEntities']) { + libxml_disable_entity_loader(true); + } + if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') { + $xml = new SimpleXMLElement($input, LIBXML_NOCDATA); + } else { + $xml = new DOMDocument(); + $xml->loadXML($input); + } + if ($hasDisable && !$options['loadEntities']) { + libxml_disable_entity_loader(false); + } + libxml_use_internal_errors($internalErrors); + return $xml; + } + /** * Transform an array into a SimpleXMLElement * From a7c79e5da2fd3948fe5fdf0989c222c6c1a38006 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 14 Jul 2012 15:54:07 -0400 Subject: [PATCH 21/27] Fix warnings when deleting records that do not exist. Fixes #3037 --- lib/Cake/Model/Behavior/TreeBehavior.php | 8 +++++--- .../Case/Model/Behavior/TreeBehaviorNumberTest.php | 12 ++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php index af650c455b8..a92c367fdf2 100644 --- a/lib/Cake/Model/Behavior/TreeBehavior.php +++ b/lib/Cake/Model/Behavior/TreeBehavior.php @@ -124,11 +124,13 @@ public function beforeFind(Model $Model, $query) { */ public function beforeDelete(Model $Model, $cascade = true) { extract($this->settings[$Model->alias]); - $data = current($Model->find('first', array( + $data = $Model->find('first', array( 'conditions' => array($Model->alias . '.' . $Model->primaryKey => $Model->id), 'fields' => array($Model->alias . '.' . $left, $Model->alias . '.' . $right), - 'recursive' => -1))); - $this->_deletedRow = $data; + 'recursive' => -1)); + if ($data) { + $this->_deletedRow = current($data); + } return true; } diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php index 17552f40da6..10782865e10 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php @@ -914,6 +914,18 @@ public function testDelete() { $this->assertSame($validTree, true); } +/** + * Test deleting a record that doesn't exist. + * + * @return void + */ + public function testDeleteDoesNotExist() { + extract($this->settings); + $this->Tree = new $modelClass(); + $this->Tree->initialize(2, 2); + $this->Tree->delete(99999); + } + /** * testRemove method * From 22d4cb3794e78381556636f90849608d4f1864e9 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 14 Jul 2012 16:08:54 -0400 Subject: [PATCH 22/27] Allow warnings for Xml entities. For some installations libxml_use_internal_errors() does not work, a warning is another way to measure the entities not being loaded. --- lib/Cake/Test/Case/Utility/XmlTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/XmlTest.php b/lib/Cake/Test/Case/Utility/XmlTest.php index 23517314d11..20067b5299b 100644 --- a/lib/Cake/Test/Case/Utility/XmlTest.php +++ b/lib/Cake/Test/Case/Utility/XmlTest.php @@ -1053,8 +1053,12 @@ public function testNoEntityLoading() { &payload; XML; - $result = Xml::build($xml); - $this->assertEquals('', (string)$result->xxe); + try { + $result = Xml::build($xml); + $this->assertEquals('', (string)$result->xxe); + } catch (PHPUnit_Framework_Error_Warning $e) { + $this->assertTrue(true, 'A warning was raised meaning external entities were not loaded'); + } } } From fb92bde0fef83eefc18510bcfce75d231fcf7585 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 14 Jul 2012 16:18:21 -0400 Subject: [PATCH 23/27] Loosen exception types. --- lib/Cake/Test/Case/Utility/XmlTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Utility/XmlTest.php b/lib/Cake/Test/Case/Utility/XmlTest.php index 20067b5299b..7108d75a791 100644 --- a/lib/Cake/Test/Case/Utility/XmlTest.php +++ b/lib/Cake/Test/Case/Utility/XmlTest.php @@ -1056,7 +1056,7 @@ public function testNoEntityLoading() { try { $result = Xml::build($xml); $this->assertEquals('', (string)$result->xxe); - } catch (PHPUnit_Framework_Error_Warning $e) { + } catch (Exception $e) { $this->assertTrue(true, 'A warning was raised meaning external entities were not loaded'); } } From cc44130fc07abdc0faf438c5c98d636ad6ef1f1c Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 14 Jul 2012 16:42:59 -0400 Subject: [PATCH 24/27] Update version number to 2.2.1 --- lib/Cake/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/VERSION.txt b/lib/Cake/VERSION.txt index 366cf87786f..3ec56db31f2 100644 --- a/lib/Cake/VERSION.txt +++ b/lib/Cake/VERSION.txt @@ -17,4 +17,4 @@ // @license MIT License (http://www.opensource.org/licenses/mit-license.php) // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -2.2.0 +2.2.1 From 928de97338c26304386db969aaf0713c90154121 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 15 Jul 2012 19:45:10 -0400 Subject: [PATCH 25/27] Add additional tests for error triggering on missing validator. Closes #3039 --- .../Validator/CakeValidationRuleTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php b/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php index 31caf5f34fa..e0d9c8b35f0 100644 --- a/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php +++ b/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php @@ -73,6 +73,7 @@ public function testIsValid() { $Rule->process('fieldName', $data, $methods); $this->assertTrue($Rule->isValid()); } + /** * tests that passing custom validation methods work * @@ -98,6 +99,24 @@ public function testCustomMethods() { $this->assertFalse($Rule->isValid()); } +/** + * Make sure errors are triggered when validation is missing. + * + * @expectedException PHPUnit_Framework_Error_Warning + * @expectedExceptionMessage Could not find validation handler totallyMissing for fieldName + * @return void + */ + public function testCustomMethodMissingError() { + $def = array('rule' => array('totallyMissing')); + $data = array( + 'fieldName' => 'some data' + ); + $methods = array('mytestrule' => array($this, 'myTestRule')); + + $Rule = new CakeValidationRule($def); + $Rule->process('fieldName', $data, $methods); + } + /** * Test isRequired method * From a63dd9ee9d7e58b9df6fe4110120e9f1b40f5275 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 17 Jul 2012 21:06:41 -0400 Subject: [PATCH 26/27] Fix incorrect formatting in TreeBehavior. Fixes #3045 --- lib/Cake/Model/Behavior/TreeBehavior.php | 3 +-- .../Model/Behavior/TreeBehaviorNumberTest.php | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php index a92c367fdf2..365d26002c0 100644 --- a/lib/Cake/Model/Behavior/TreeBehavior.php +++ b/lib/Cake/Model/Behavior/TreeBehavior.php @@ -371,8 +371,7 @@ public function generateTreeList(Model $Model, $conditions = null, $keyPath = nu $valuePath = array('%s%s', '{n}.tree_prefix', $valuePath); } else { - $valuePath[0] = '{' . (count($valuePath) - 1) . '}' . $valuePath[0]; - $valuePath[] = '{n}.tree_prefix'; + array_unshift($valuePath, '%s' . $valuePath[0], '{n}.tree_prefix'); } $order = $Model->alias . '.' . $left . ' asc'; $results = $Model->find('all', compact('conditions', 'fields', 'order', 'recursive')); diff --git a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php index 10782865e10..d93c6334e45 100644 --- a/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php +++ b/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php @@ -1281,6 +1281,26 @@ public function testGenerateTreeListWithSelfJoin() { $this->assertSame($expected, $result); } +/** + * Test the formatting options of generateTreeList() + * + * @return void + */ + public function testGenerateTreeListFormatting() { + extract($this->settings); + $this->Tree = new $modelClass(); + $this->Tree->initialize(2, 2); + + $result = $this->Tree->generateTreeList( + null, + "{n}.$modelClass.id", + array('%s - %s', "{n}.$modelClass.id", "{n}.$modelClass.name") + ); + $this->assertEquals('1 - 1. Root', $result[1]); + $this->assertEquals('_2 - 1.1', $result[2]); + $this->assertEquals('__3 - 1.1.1', $result[3]); + } + /** * testArraySyntax method * From 3b46cd43f1279b7d24c58861466c414e0eb8d72c Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 17 Jul 2012 22:48:50 -0400 Subject: [PATCH 27/27] Add logging and error when fixture creation fails. This helps people find and solve issues faster/easier. Fixes #3044 --- lib/Cake/TestSuite/Fixture/CakeTestFixture.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php index 359d57f6fec..db16cfff6e9 100644 --- a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php +++ b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php @@ -194,6 +194,14 @@ public function create($db) { $db->execute($db->createSchema($this->Schema), array('log' => false)); $this->created[] = $db->configKeyName; } catch (Exception $e) { + $msg = __d( + 'cake_dev', + 'Fixture creation for "%s" failed "%s"', + $this->table, + $e->getMessage() + ); + CakeLog::error($msg); + trigger_error($msg, E_USER_WARNING); return false; } return true;