From b7b6859c274d3f5ec64b204cab74fb07b85c8355 Mon Sep 17 00:00:00 2001 From: Bob Fanger Date: Fri, 21 Dec 2012 16:12:51 +0100 Subject: [PATCH 01/24] Fixes corrupted CakeRequests when a $_GET value contains "://" --- lib/Cake/Network/CakeRequest.php | 6 +++++- lib/Cake/Test/Case/Network/CakeRequestTest.php | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index 903fa72ca..cf4227382 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -232,7 +232,11 @@ class CakeRequest implements ArrayAccess { } elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) { $uri = $_SERVER['REQUEST_URI']; } elseif (isset($_SERVER['REQUEST_URI'])) { - $uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL)); + if (strpos($_SERVER['REQUEST_URI'], '?') !== false && strpos($_SERVER['REQUEST_URI'], '://') > strpos($_SERVER['REQUEST_URI'], '?')) { + $uri = $_SERVER['REQUEST_URI']; + } else { + $uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL)); + } } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) { $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']); } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index 487f60e80..8d7bcba4f 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -136,6 +136,10 @@ class CakeRequestTest extends CakeTestCase { $_SERVER['REQUEST_URI'] = '/tasks/index/page:1/?ts=123456'; $request = new CakeRequest(); $this->assertEquals('tasks/index/page:1/', $request->url); + + $_SERVER['REQUEST_URI'] = '/some/path?url=http://cakephp.org'; + $request = new CakeRequest(); + $this->assertEquals('some/path', $request->url); } /** From 13dc39717201533dd54b73864ed2212e57b9254e Mon Sep 17 00:00:00 2001 From: Bob Fanger Date: Fri, 21 Dec 2012 19:55:20 +0100 Subject: [PATCH 02/24] Added unittest for REQUEST_URI with multiple FQDNs. --- lib/Cake/Test/Case/Network/CakeRequestTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index 8d7bcba4f..a9a0e7e37 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -140,6 +140,10 @@ class CakeRequestTest extends CakeTestCase { $_SERVER['REQUEST_URI'] = '/some/path?url=http://cakephp.org'; $request = new CakeRequest(); $this->assertEquals('some/path', $request->url); + + $_SERVER['REQUEST_URI'] = FULL_BASE_URL.'/other/path?url=http://cakephp.org'; + $request = new CakeRequest(); + $this->assertEquals('other/path', $request->url); } /** From eff4004261a2bd05e4df54ee2af057c680ff50fc Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 14 Jan 2013 20:39:01 -0500 Subject: [PATCH 03/24] Don't treat tables that substring match as associations The table structure of: - packages - userpackages - georegions - userpackages_georegions Should not create a habtm between packages & georegions. Fixes #3532 --- lib/Cake/Console/Command/Task/ModelTask.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php index df2725d1f..be90d2168 100644 --- a/lib/Cake/Console/Command/Task/ModelTask.php +++ b/lib/Cake/Console/Command/Task/ModelTask.php @@ -627,7 +627,7 @@ class ModelTask extends BakeTask { $offset = strpos($otherTable, $model->table . '_'); $otherOffset = strpos($otherTable, '_' . $model->table); - if ($offset !== false) { + if ($offset === 0) { $offset = strlen($model->table . '_'); $habtmName = $this->_modelName(substr($otherTable, $offset)); $associations['hasAndBelongsToMany'][] = array( @@ -637,7 +637,7 @@ class ModelTask extends BakeTask { 'associationForeignKey' => $this->_modelKey($habtmName), 'joinTable' => $otherTable ); - } elseif ($otherOffset !== false) { + } elseif ($otherOffset === 0) { $habtmName = $this->_modelName(substr($otherTable, 0, $otherOffset)); $associations['hasAndBelongsToMany'][] = array( 'alias' => $habtmName, From ad0d6644c4d632943a7c142ec4c26400302657e5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 14 Jan 2013 21:12:11 -0500 Subject: [PATCH 04/24] Partially revert default niceShortFormat In 9fa531d6e3a3d0291ea36ccd9f0b9f2ab1d9f11b the default niceShortFormat was changed, which has been interpreted as a regression in #3533. This change partially reverts the previous change and tries to strike a balance between the old behavior and new. Refs #3533 --- lib/Cake/Test/Case/Utility/CakeTimeTest.php | 6 ++++++ lib/Cake/Utility/CakeTime.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Utility/CakeTimeTest.php b/lib/Cake/Test/Case/Utility/CakeTimeTest.php index f21d066c8..c0c30ff77 100644 --- a/lib/Cake/Test/Case/Utility/CakeTimeTest.php +++ b/lib/Cake/Test/Case/Utility/CakeTimeTest.php @@ -367,6 +367,12 @@ class CakeTimeTest extends CakeTestCase { $time = time() + DAY; $this->assertEquals('Tomorrow, ' . date('H:i', $time), $this->Time->niceShort($time)); + $time = strtotime('+6 days'); + $this->assertEquals('On ' . date('l F d, H:i', $time), $this->Time->niceShort($time)); + + $time = strtotime('-6 days'); + $this->assertEquals(date('l F d, H:i', $time), $this->Time->niceShort($time)); + date_default_timezone_set('Europe/London'); $result = $this->Time->niceShort('2005-01-15 10:00:00', new DateTimeZone('Europe/Brussels')); $this->assertEquals('Jan 15th 2005, 11:00', $result); diff --git a/lib/Cake/Utility/CakeTime.php b/lib/Cake/Utility/CakeTime.php index 35c7241d0..c2b549798 100644 --- a/lib/Cake/Utility/CakeTime.php +++ b/lib/Cake/Utility/CakeTime.php @@ -56,7 +56,7 @@ class CakeTime { * @var string * @see CakeTime::niceShort() */ - public static $niceShortFormat = '%d/%m, %H:%M'; + public static $niceShortFormat = '%B %d, %H:%M'; /** * The format to use when formatting a time using `CakeTime::timeAgoInWords()` From 0ed9e3c120aff65839ef16d315a3d2cd93515873 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 15 Jan 2013 21:43:30 -0500 Subject: [PATCH 05/24] Only bake HABTM associations for tables that exist. bake often guesses wrong when it comes to habtm. Only add associations we're highly confident of. This includes tables where the foreign table also exists. Refs #3532 --- lib/Cake/Console/Command/Task/ModelTask.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php index be90d2168..f5479a279 100644 --- a/lib/Cake/Console/Command/Task/ModelTask.php +++ b/lib/Cake/Console/Command/Task/ModelTask.php @@ -621,6 +621,7 @@ class ModelTask extends BakeTask { public function findHasAndBelongsToMany(Model $model, $associations) { $foreignKey = $this->_modelKey($model->name); foreach ($this->_tables as $otherTable) { + $tableName = null; $tempOtherModel = $this->_getModelObject($this->_modelName($otherTable), $otherTable); $modelFieldsTemp = $tempOtherModel->schema(true); @@ -628,17 +629,12 @@ class ModelTask extends BakeTask { $otherOffset = strpos($otherTable, '_' . $model->table); if ($offset === 0) { - $offset = strlen($model->table . '_'); - $habtmName = $this->_modelName(substr($otherTable, $offset)); - $associations['hasAndBelongsToMany'][] = array( - 'alias' => $habtmName, - 'className' => $habtmName, - 'foreignKey' => $foreignKey, - 'associationForeignKey' => $this->_modelKey($habtmName), - 'joinTable' => $otherTable - ); + $tableName = substr($otherTable, strlen($model->table . '_')); } elseif ($otherOffset === 0) { - $habtmName = $this->_modelName(substr($otherTable, 0, $otherOffset)); + $tableName = substr($otherTable, 0, $otherOffset); + } + if ($tableName && in_array($tableName, $this->_tables)) { + $habtmName = $this->_modelName($tableName); $associations['hasAndBelongsToMany'][] = array( 'alias' => $habtmName, 'className' => $habtmName, From 5a6a45d0d1b9e4f844e950939c63204b4c0d2065 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 16 Jan 2013 12:57:18 -0500 Subject: [PATCH 06/24] Add support for --admin to bake controller all. I missed this when originally implementing bake controller all. Fixes #3536 --- .../Console/Command/Task/ControllerTask.php | 10 +++++ .../Command/Task/ControllerTaskTest.php | 37 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/lib/Cake/Console/Command/Task/ControllerTask.php b/lib/Cake/Console/Command/Task/ControllerTask.php index 8feecc1a5..ff2cf2d69 100644 --- a/lib/Cake/Console/Command/Task/ControllerTask.php +++ b/lib/Cake/Console/Command/Task/ControllerTask.php @@ -105,12 +105,22 @@ class ControllerTask extends BakeTask { $this->listAll($this->connection, false); ClassRegistry::config('Model', array('ds' => $this->connection)); $unitTestExists = $this->_checkUnitTest(); + + $admin = false; + if (!empty($this->params['admin'])) { + $admin = $this->Project->getPrefix(); + } + foreach ($this->__tables as $table) { $model = $this->_modelName($table); $controller = $this->_controllerName($model); App::uses($model, 'Model'); if (class_exists($model)) { $actions = $this->bakeActions($controller); + if ($admin) { + $this->out(__d('cake_console', 'Adding %s methods', $admin)); + $actions .= "\n" . $this->bakeActions($controller, $admin); + } if ($this->bake($controller, $actions) && $unitTestExists) { $this->bakeTest($controller); } diff --git a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php index 4d11cbe60..2fefa1e7e 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php @@ -514,6 +514,7 @@ class ControllerTaskTest extends CakeTestCase { if (!defined('ARTICLE_MODEL_CREATED')) { $this->markTestSkipped('Execute into all could not be run as an Article, Tag or Comment model was already loaded.'); } + $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; $this->Task->args = array('all'); @@ -530,6 +531,42 @@ class ControllerTaskTest extends CakeTestCase { $this->Task->execute(); } +/** + * Test execute() with all and --admin + * + * @return void + */ + public function testExecuteIntoAllAdmin() { + $count = count($this->Task->listAll('test')); + if ($count != count($this->fixtures)) { + $this->markTestSkipped('Additional tables detected.'); + } + if (!defined('ARTICLE_MODEL_CREATED')) { + $this->markTestSkipped('Execute into all could not be run as an Article, Tag or Comment model was already loaded.'); + } + + $this->Task->connection = 'test'; + $this->Task->path = '/my/path/'; + $this->Task->args = array('all'); + $this->Task->params['admin'] = true; + + $this->Task->Project->expects($this->any()) + ->method('getPrefix') + ->will($this->returnValue('admin_')); + $this->Task->expects($this->any()) + ->method('_checkUnitTest') + ->will($this->returnValue(true)); + $this->Task->Test->expects($this->once())->method('bake'); + + $filename = '/my/path/BakeArticlesController.php'; + $this->Task->expects($this->once())->method('createFile')->with( + $filename, + $this->stringContains('function admin_index') + )->will($this->returnValue(true)); + + $this->Task->execute(); + } + /** * test that `cake bake controller foos` works. * From 95ed471c41f61555b2b7f642422bfef8a279cfd4 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 16 Jan 2013 12:59:13 -0500 Subject: [PATCH 07/24] Reduce duplication in code. This will result in all tests being skipped when any of the required models pre-exists. --- .../Command/Task/ControllerTaskTest.php | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php index 2fefa1e7e..9d543ce7c 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php @@ -90,6 +90,10 @@ class ControllerTaskTest extends CakeTestCase { array($out, $out, $in) ); $this->Task->Test = $this->getMock('TestTask', array(), array($out, $out, $in)); + + if (!defined('ARTICLE_MODEL_CREATED')) { + $this->markTestSkipped('Could not run as an Article, Tag or Comment model was already loaded.'); + } } /** @@ -340,7 +344,6 @@ class ControllerTaskTest extends CakeTestCase { * @return void */ public function testBakeActionsUsingSessions() { - $this->skipIf(!defined('ARTICLE_MODEL_CREATED'), 'Testing bakeActions requires Article, Comment & Tag Model to be undefined.'); $result = $this->Task->bakeActions('BakeArticles', null, true); @@ -379,7 +382,6 @@ class ControllerTaskTest extends CakeTestCase { * @return void */ public function testBakeActionsWithNoSessions() { - $this->skipIf(!defined('ARTICLE_MODEL_CREATED'), 'Testing bakeActions requires Article, Tag, Comment Models to be undefined.'); $result = $this->Task->bakeActions('BakeArticles', null, false); @@ -511,9 +513,6 @@ class ControllerTaskTest extends CakeTestCase { if ($count != count($this->fixtures)) { $this->markTestSkipped('Additional tables detected.'); } - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Execute into all could not be run as an Article, Tag or Comment model was already loaded.'); - } $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; @@ -541,9 +540,6 @@ class ControllerTaskTest extends CakeTestCase { if ($count != count($this->fixtures)) { $this->markTestSkipped('Additional tables detected.'); } - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Execute into all could not be run as an Article, Tag or Comment model was already loaded.'); - } $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; @@ -573,9 +569,6 @@ class ControllerTaskTest extends CakeTestCase { * @return void */ public function testExecuteWithController() { - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Execute with scaffold param requires no Article, Tag or Comment model to be defined'); - } $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; $this->Task->args = array('BakeArticles'); @@ -607,9 +600,6 @@ class ControllerTaskTest extends CakeTestCase { * @return void */ public function testExecuteWithControllerNameVariations($name) { - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Execute with scaffold param requires no Article, Tag or Comment model to be defined.'); - } $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; $this->Task->args = array($name); @@ -627,9 +617,6 @@ class ControllerTaskTest extends CakeTestCase { * @return void */ public function testExecuteWithPublicParam() { - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Execute with public param requires no Article, Tag or Comment model to be defined.'); - } $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; $this->Task->args = array('BakeArticles'); @@ -649,9 +636,6 @@ class ControllerTaskTest extends CakeTestCase { * @return void */ public function testExecuteWithControllerAndBoth() { - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Execute with controller and both requires no Article, Tag or Comment model to be defined.'); - } $this->Task->Project->expects($this->any())->method('getPrefix')->will($this->returnValue('admin_')); $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; @@ -671,9 +655,6 @@ class ControllerTaskTest extends CakeTestCase { * @return void */ public function testExecuteWithControllerAndAdmin() { - if (!defined('ARTICLE_MODEL_CREATED')) { - $this->markTestSkipped('Execute with controller and admin requires no Article, Tag or Comment model to be defined.'); - } $this->Task->Project->expects($this->any())->method('getPrefix')->will($this->returnValue('admin_')); $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; From 23d4807933657ef44f8f8ce6f58ca87a66d663f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renan=20Gonc=CC=A7alves?= Date: Thu, 17 Jan 2013 13:00:56 +0100 Subject: [PATCH 08/24] Fixing expected value from find when it results in failure. When a behavior callback (eg: beforeFind) stops the event, find will return null. False is really never returned from find(). --- lib/Cake/Model/Model.php | 2 +- lib/Cake/Test/Case/Model/ModelDeleteTest.php | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 51780e281..136405e49 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -2496,7 +2496,7 @@ class Model extends Object implements CakeEventListener { 'fields' => "{$this->alias}.{$this->primaryKey}", 'recursive' => 0), compact('conditions')) ); - if ($ids === false) { + if ($ids === null) { return false; } diff --git a/lib/Cake/Test/Case/Model/ModelDeleteTest.php b/lib/Cake/Test/Case/Model/ModelDeleteTest.php index 7a69585c6..63362f00d 100644 --- a/lib/Cake/Test/Case/Model/ModelDeleteTest.php +++ b/lib/Cake/Test/Case/Model/ModelDeleteTest.php @@ -434,6 +434,26 @@ class ModelDeleteTest extends BaseModelTest { $this->assertFalse($result, 'deleteAll returned true when find query generated sql error. %s'); } +/** + * testDeleteAllFailedFind method + * + * Eg: Behavior callback stops the event, find returns null + * + * @return void + */ + public function testDeleteAllFailedFind() { + $this->loadFixtures('Article'); + $this->getMock('Article', array('find'), array(), 'ArticleDeleteAll'); + + $TestModel = new ArticleDeleteAll(); + $TestModel->expects($this->once()) + ->method('find') + ->will($this->returnValue(null)); + + $result = $TestModel->deleteAll(array('Article.user_id' => 999)); + $this->assertFalse($result); + } + /** * testRecursiveDel method * From 689745d7054fb7adae1b1f1faad99945c1a65521 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 17 Jan 2013 09:51:47 -0500 Subject: [PATCH 09/24] Follow redirects when fetching XML files. Previously file_get_contents followed redirects, restore that behavior. See fb275c5fa257c98f85883115ae12dbf5671094e1 --- lib/Cake/Utility/Xml.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Utility/Xml.php b/lib/Cake/Utility/Xml.php index cf257b494..80831dee4 100644 --- a/lib/Cake/Utility/Xml.php +++ b/lib/Cake/Utility/Xml.php @@ -101,7 +101,7 @@ class Xml { } elseif (file_exists($input)) { return self::_loadXml(file_get_contents($input), $options); } elseif (strpos($input, 'http://') === 0 || strpos($input, 'https://') === 0) { - $socket = new HttpSocket(); + $socket = new HttpSocket(array('redirect' => 10)); $response = $socket->get($input); if (!$response->isOk()) { throw new XmlException(__d('cake_dev', 'XML cannot be read.')); From 84b10ba70790a1e23abf89728ee154f86461ca15 Mon Sep 17 00:00:00 2001 From: johnymonster Date: Thu, 17 Jan 2013 14:14:12 -0500 Subject: [PATCH 10/24] Strict in_array for mixed id variable types Setting the in_array check to strict, as this would return true incorrectly when and if values are of mixed type. --- lib/Cake/View/Helper/FormHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index b7961142f..384e2906f 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -2471,7 +2471,7 @@ class FormHelper extends AppHelper { if ($name !== null) { if ( (!$selectedIsArray && !$selectedIsEmpty && (string)$attributes['value'] == (string)$name) || - ($selectedIsArray && in_array($name, $attributes['value'])) + ($selectedIsArray && in_array($name, $attributes['value'], true)) ) { if ($attributes['style'] === 'checkbox') { $htmlOptions['checked'] = true; From 18e282f3aa6faead59bb8fbcdd9f0f6967c29ec2 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 17 Jan 2013 19:35:25 -0500 Subject: [PATCH 11/24] Fix space between function + parenthesis. --- lib/Cake/Model/Model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php index 136405e49..75ab9d68f 100644 --- a/lib/Cake/Model/Model.php +++ b/lib/Cake/Model/Model.php @@ -977,7 +977,7 @@ class Model extends Object implements CakeEventListener { $plugin = null; if (is_numeric($assoc)) { - unset ($this->{$type}[$assoc]); + unset($this->{$type}[$assoc]); $assoc = $value; $value = array(); @@ -1153,7 +1153,7 @@ class Model extends Object implements CakeEventListener { foreach ($fieldSet as $fieldName => $fieldValue) { if (isset($this->validationErrors[$fieldName])) { - unset ($this->validationErrors[$fieldName]); + unset($this->validationErrors[$fieldName]); } if ($modelName === $this->alias) { From 773666ddad93d3eb713b3c1f521a29e0d1a12a32 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 17 Jan 2013 20:34:25 -0500 Subject: [PATCH 12/24] Fix coding standards and save a function call. --- lib/Cake/Network/CakeRequest.php | 3 ++- lib/Cake/Test/Case/Network/CakeRequestTest.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php index cf4227382..047f6b138 100644 --- a/lib/Cake/Network/CakeRequest.php +++ b/lib/Cake/Network/CakeRequest.php @@ -232,7 +232,8 @@ class CakeRequest implements ArrayAccess { } elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) { $uri = $_SERVER['REQUEST_URI']; } elseif (isset($_SERVER['REQUEST_URI'])) { - if (strpos($_SERVER['REQUEST_URI'], '?') !== false && strpos($_SERVER['REQUEST_URI'], '://') > strpos($_SERVER['REQUEST_URI'], '?')) { + $qPosition = strpos($_SERVER['REQUEST_URI'], '?'); + if ($qPosition !== false && strpos($_SERVER['REQUEST_URI'], '://') > $qPosition) { $uri = $_SERVER['REQUEST_URI']; } else { $uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL)); diff --git a/lib/Cake/Test/Case/Network/CakeRequestTest.php b/lib/Cake/Test/Case/Network/CakeRequestTest.php index a9a0e7e37..e45d870b6 100644 --- a/lib/Cake/Test/Case/Network/CakeRequestTest.php +++ b/lib/Cake/Test/Case/Network/CakeRequestTest.php @@ -141,7 +141,7 @@ class CakeRequestTest extends CakeTestCase { $request = new CakeRequest(); $this->assertEquals('some/path', $request->url); - $_SERVER['REQUEST_URI'] = FULL_BASE_URL.'/other/path?url=http://cakephp.org'; + $_SERVER['REQUEST_URI'] = FULL_BASE_URL . '/other/path?url=http://cakephp.org'; $request = new CakeRequest(); $this->assertEquals('other/path', $request->url); } From 7790bcacffa8ad33bb94e4fad0f8b9f092e3ffb9 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 17 Jan 2013 20:35:37 -0500 Subject: [PATCH 13/24] Allow afterFind() to fully remove an associated record. By returnning array() or unsetting the 0'th result an afterFind callback should be able to fully remove data from the results. Fixes #3541 --- lib/Cake/Model/Datasource/DboSource.php | 4 +++- lib/Cake/Test/Case/Model/ModelReadTest.php | 24 ++++++++++++++++++++++ lib/Cake/Test/Case/Model/models.php | 10 +++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index c84171810..fc09feb10 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -1153,10 +1153,12 @@ class DboSource extends DataSource { } $linkedModel = $model->{$className}; $filtering[] = $className; - foreach ($results as &$result) { + foreach ($results as $key => &$result) { $data = $linkedModel->afterFind(array(array($className => $result[$className])), false); if (isset($data[0][$className])) { $result[$className] = $data[0][$className]; + } else { + unset($results[$key]); } } } diff --git a/lib/Cake/Test/Case/Model/ModelReadTest.php b/lib/Cake/Test/Case/Model/ModelReadTest.php index 65e7f90eb..8ad2bd4e0 100644 --- a/lib/Cake/Test/Case/Model/ModelReadTest.php +++ b/lib/Cake/Test/Case/Model/ModelReadTest.php @@ -3006,6 +3006,30 @@ class ModelReadTest extends BaseModelTest { $this->assertEquals($afterFindData, $noAfterFindData); } +/** + * Test that afterFind can completely unset data. + * + * @return void + */ + public function testAfterFindUnset() { + $this->loadFixtures('Article', 'Comment', 'User'); + $model = new CustomArticle(); + $model->bindModel(array( + 'hasMany' => array( + 'ModifiedComment' => array( + 'className' => 'ModifiedComment', + 'foreignKey' => 'article_id', + ) + ) + )); + $model->ModifiedComment->remove = true; + $result = $model->find('all'); + $this->assertTrue( + empty($result[0]['ModifiedComment']), + 'Zeroith row should be removed by afterFind' + ); + } + /** * testFindThreadedNoParent method * diff --git a/lib/Cake/Test/Case/Model/models.php b/lib/Cake/Test/Case/Model/models.php index b86a4b583..7dd8fc3db 100644 --- a/lib/Cake/Test/Case/Model/models.php +++ b/lib/Cake/Test/Case/Model/models.php @@ -551,6 +551,13 @@ class ModifiedComment extends CakeTestModel { */ public $useTable = 'comments'; +/** + * Property used to toggle filtering of results + * + * @var boolean + */ + public $remove = false; + /** * belongsTo property * @@ -567,6 +574,9 @@ class ModifiedComment extends CakeTestModel { if (isset($results[0])) { $results[0]['Comment']['callback'] = 'Fire'; } + if ($this->remove) { + return array(); + } return $results; } From 76fe9f8787fdc89c172030c6f24cb6f6d69d61cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renan=20Gonc=CC=A7alves?= Date: Fri, 18 Jan 2013 12:27:43 +0100 Subject: [PATCH 14/24] Fixing the way to follow redirects when fetching XML files. See: 689745d7054fb7adae1b1f1faad99945c1a65521 --- lib/Cake/Utility/Xml.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Utility/Xml.php b/lib/Cake/Utility/Xml.php index 80831dee4..7e87949dc 100644 --- a/lib/Cake/Utility/Xml.php +++ b/lib/Cake/Utility/Xml.php @@ -101,7 +101,7 @@ class Xml { } elseif (file_exists($input)) { return self::_loadXml(file_get_contents($input), $options); } elseif (strpos($input, 'http://') === 0 || strpos($input, 'https://') === 0) { - $socket = new HttpSocket(array('redirect' => 10)); + $socket = new HttpSocket(array('request' => array('redirect' => 10))); $response = $socket->get($input); if (!$response->isOk()) { throw new XmlException(__d('cake_dev', 'XML cannot be read.')); From 631da2d04adbe2838a757a85ded421c0ae88393f Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 18 Jan 2013 11:05:02 -0500 Subject: [PATCH 15/24] Update doc block. --- lib/Cake/Controller/Component/CookieComponent.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Controller/Component/CookieComponent.php b/lib/Cake/Controller/Component/CookieComponent.php index 1d962bc28..7e67543f0 100644 --- a/lib/Cake/Controller/Component/CookieComponent.php +++ b/lib/Cake/Controller/Component/CookieComponent.php @@ -208,7 +208,8 @@ class CookieComponent extends Component { * @param string|array $key Key for the value * @param mixed $value Value * @param boolean $encrypt Set to true to encrypt value, false otherwise - * @param integer|string $expires Can be either Unix timestamp, or date string + * @param integer|string $expires Can be either the number of seconds until a cookie + * expires, or a strtotime compatible time offset. * @return void * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::write */ From db8127626a912fd3a2167d766d6bd107c485af59 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 19 Jan 2013 13:15:33 +0530 Subject: [PATCH 16/24] Update helper usage to 2.x style in code examples --- lib/Cake/View/Helper/HtmlHelper.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cake/View/Helper/HtmlHelper.php b/lib/Cake/View/Helper/HtmlHelper.php index 7bfe5247a..3e63241b5 100644 --- a/lib/Cake/View/Helper/HtmlHelper.php +++ b/lib/Cake/View/Helper/HtmlHelper.php @@ -557,7 +557,7 @@ class HtmlHelper extends AppHelper { public function scriptBlock($script, $options = array()) { $options += array('safe' => true, 'inline' => true); if ($options['safe']) { - $script = "\n" . '//' . "\n"; + $script = "\n" . '//' . "\n"; } if (!$options['inline'] && empty($options['block'])) { $options['block'] = 'script'; @@ -616,7 +616,7 @@ class HtmlHelper extends AppHelper { * ### Usage: * * {{{ - * echo $html->style(array('margin' => '10px', 'padding' => '10px'), true); + * echo $this->Html->style(array('margin' => '10px', 'padding' => '10px'), true); * * // creates * 'margin:10px;padding:10px;' @@ -745,11 +745,11 @@ class HtmlHelper extends AppHelper { * * Create a regular image: * - * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP'));` + * `echo $this->Html->image('cake_icon.png', array('alt' => 'CakePHP'));` * * Create an image link: * - * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP', 'url' => 'http://cakephp.org'));` + * `echo $this->Html->image('cake_icon.png', array('alt' => 'CakePHP', 'url' => 'http://cakephp.org'));` * * ### Options: * From e8647d77ebd3db79ae051e55eca2907b762df924 Mon Sep 17 00:00:00 2001 From: jroberts0001 Date: Tue, 15 Jan 2013 03:13:54 -0500 Subject: [PATCH 17/24] Added App::uses to the PluginAppController and PluginAppModel bake templates --- lib/Cake/Console/Command/Task/PluginTask.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Cake/Console/Command/Task/PluginTask.php b/lib/Cake/Console/Command/Task/PluginTask.php index 2f972b68d..e11c1bf28 100644 --- a/lib/Cake/Console/Command/Task/PluginTask.php +++ b/lib/Cake/Console/Command/Task/PluginTask.php @@ -145,6 +145,7 @@ class PluginTask extends AppShell { $controllerFileName = $plugin . 'AppController.php'; $out = "createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out); @@ -152,6 +153,7 @@ class PluginTask extends AppShell { $modelFileName = $plugin . 'AppModel.php'; $out = "createFile($this->path . $plugin . DS . 'Model' . DS . $modelFileName, $out); From 622d2f04f9b3cb10c72fb37aeba51c269d0616b2 Mon Sep 17 00:00:00 2001 From: Rachman Chavik Date: Sun, 20 Jan 2013 09:07:31 +0700 Subject: [PATCH 18/24] removing extra newline in baked files --- lib/Cake/Console/Command/Task/PluginTask.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Console/Command/Task/PluginTask.php b/lib/Cake/Console/Command/Task/PluginTask.php index e11c1bf28..e844628a7 100644 --- a/lib/Cake/Console/Command/Task/PluginTask.php +++ b/lib/Cake/Console/Command/Task/PluginTask.php @@ -147,7 +147,7 @@ class PluginTask extends AppShell { $out = "createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out); $modelFileName = $plugin . 'AppModel.php'; @@ -155,7 +155,7 @@ class PluginTask extends AppShell { $out = "createFile($this->path . $plugin . DS . 'Model' . DS . $modelFileName, $out); $this->_modifyBootstrap($plugin); From efadf3dcd32d235981aa798ae826b8b7b38aa9b4 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 21 Jan 2013 20:46:41 -0500 Subject: [PATCH 19/24] Make sure sessions are started before destroying them. Fixes #3551 --- lib/Cake/Model/Datasource/CakeSession.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Datasource/CakeSession.php b/lib/Cake/Model/Datasource/CakeSession.php index af457cdba..187857fca 100644 --- a/lib/Cake/Model/Datasource/CakeSession.php +++ b/lib/Cake/Model/Datasource/CakeSession.php @@ -421,9 +421,10 @@ class CakeSession { * @return void */ public static function destroy() { - if (self::started()) { - session_destroy(); + if (!self::started()) { + self::start(); } + session_destroy(); self::clear(); } From 75495705a60a637406defbb9b9563eda4baaa2e6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 21 Jan 2013 20:50:46 -0500 Subject: [PATCH 20/24] Fix Hash::get($data, '0') Fixes #3555 --- lib/Cake/Test/Case/Utility/HashTest.php | 8 ++++++++ lib/Cake/Utility/Hash.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Utility/HashTest.php b/lib/Cake/Test/Case/Utility/HashTest.php index 059de1839..61766ed62 100644 --- a/lib/Cake/Test/Case/Utility/HashTest.php +++ b/lib/Cake/Test/Case/Utility/HashTest.php @@ -170,6 +170,14 @@ class HashTest extends CakeTestCase { * return void */ public function testGet() { + $data = array('abc', 'def'); + + $result = Hash::get($data, '0'); + $this->assertEquals('abc', $result); + + $result = Hash::get($data, '1'); + $this->assertEquals('def', $result); + $data = self::articleData(); $result = Hash::get(array(), '1.Article.title'); diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php index 278a01aa9..8974ef8d7 100644 --- a/lib/Cake/Utility/Hash.php +++ b/lib/Cake/Utility/Hash.php @@ -39,7 +39,7 @@ class Hash { * @return mixed The value fetched from the array, or null. */ public static function get(array $data, $path) { - if (empty($data) || empty($path)) { + if (empty($data)) { return null; } if (is_string($path)) { From 0cdef75060d4eee0f28cddb2cf3260ac8cc8a907 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 21 Jan 2013 21:13:35 -0500 Subject: [PATCH 21/24] Fix failing tests. I have no idea why the updated session test was expected to fail as the data was written to the session. Refs #3551 --- .../Test/Case/Controller/Component/SessionComponentTest.php | 2 +- lib/Cake/Test/Case/Utility/HashTest.php | 3 +++ lib/Cake/Utility/Hash.php | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php b/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php index 0920186c5..72d07c027 100644 --- a/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php @@ -205,7 +205,7 @@ class SessionComponentTest extends CakeTestCase { $this->assertEquals($Session->read('Test'), $array); $Session->delete('Test'); - $this->assertFalse($Session->write(array('Test'), 'some value')); + $this->assertTrue($Session->write(array('Test'), 'some value')); $this->assertTrue($Session->write(array('Test' => 'some value'))); $this->assertEquals('some value', $Session->read('Test')); $Session->delete('Test'); diff --git a/lib/Cake/Test/Case/Utility/HashTest.php b/lib/Cake/Test/Case/Utility/HashTest.php index 61766ed62..1ce4cb31a 100644 --- a/lib/Cake/Test/Case/Utility/HashTest.php +++ b/lib/Cake/Test/Case/Utility/HashTest.php @@ -175,6 +175,9 @@ class HashTest extends CakeTestCase { $result = Hash::get($data, '0'); $this->assertEquals('abc', $result); + $result = Hash::get($data, 0); + $this->assertEquals('abc', $result); + $result = Hash::get($data, '1'); $this->assertEquals('def', $result); diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php index 8974ef8d7..b76460a2e 100644 --- a/lib/Cake/Utility/Hash.php +++ b/lib/Cake/Utility/Hash.php @@ -42,7 +42,7 @@ class Hash { if (empty($data)) { return null; } - if (is_string($path)) { + if (is_string($path) || is_numeric($path)) { $parts = explode('.', $path); } else { $parts = $path; From ec619eec04397df8ad2b780baaa46cabbfad548a Mon Sep 17 00:00:00 2001 From: "Gordon Pettey (petteyg)" Date: Wed, 23 Jan 2013 23:20:41 +0000 Subject: [PATCH 22/24] Remove some spacial overkill --- lib/Cake/Console/Command/Task/DbConfigTask.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Console/Command/Task/DbConfigTask.php b/lib/Cake/Console/Command/Task/DbConfigTask.php index 596ad817d..83f710f7a 100644 --- a/lib/Cake/Console/Command/Task/DbConfigTask.php +++ b/lib/Cake/Console/Command/Task/DbConfigTask.php @@ -211,7 +211,7 @@ class DbConfigTask extends AppShell { $this->out(__d('cake_console', 'The following database configuration will be created:')); $this->hr(); $this->out(__d('cake_console', "Name: %s", $name)); - $this->out(__d('cake_console', "Datasource: %s", $datasource)); + $this->out(__d('cake_console', "Datasource: %s", $datasource)); $this->out(__d('cake_console', "Persistent: %s", $persistent)); $this->out(__d('cake_console', "Host: %s", $host)); From 0b659d513e73f757f150cdf863dfebcedb634111 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 23 Jan 2013 21:19:37 -0500 Subject: [PATCH 23/24] Add tests for #3545 Fix included in GH-1075 Closes #3545 --- lib/Cake/Test/Case/View/Helper/FormHelperTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index ae5b8fc91..bb156ae9a 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -3786,6 +3786,17 @@ class FormHelperTest extends CakeTestCase { '/select' ); $this->assertTags($result, $expected); + + $this->Form->request->data['Model']['field'] = 50; + $result = $this->Form->select('Model.field', array('50f5c0cf' => 'Stringy', '50' => 'fifty')); + $expected = array( + 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'), + array('option' => array('value' => '')), '/option', + array('option' => array('value' => '50f5c0cf')), 'Stringy', '/option', + array('option' => array('value' => '50', 'selected' => 'selected')), 'fifty', '/option', + '/select' + ); + $this->assertTags($result, $expected); } /** From ce7f85abe8e54352ad8ad38425ce20e1aac794ec Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 25 Jan 2013 15:21:16 -0500 Subject: [PATCH 24/24] Fix Token fields being added to GET forms. They are not used so there is not much point in appending them. Fixes #3565 --- .../Test/Case/View/Helper/FormHelperTest.php | 17 +++++++++++++++++ lib/Cake/View/Helper/FormHelper.php | 10 ++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index bb156ae9a..3077b4cae 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -723,6 +723,23 @@ class FormHelperTest extends CakeTestCase { $this->assertTags($result, $expected); } +/** + * testFormCreateGetNoSecurity method + * + * Test form->create() with no security key as its a get form + * + * @return void + */ + public function testCreateEndGetNoSecurity() { + $this->Form->request['_Token'] = array('key' => 'testKey'); + $encoding = strtolower(Configure::read('App.encoding')); + $result = $this->Form->create('Contact', array('type' => 'get', 'url' => '/contacts/add')); + $this->assertNotContains('Token', $result); + + $result = $this->Form->end('Save'); + $this->assertNotContains('Token', $result); + } + /** * test that create() clears the fields property so it starts fresh * diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 384e2906f..81c2bef3f 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -433,7 +433,9 @@ class FormHelper extends AppHelper { $htmlAttributes = array_merge($options, $htmlAttributes); $this->fields = array(); - $append .= $this->_csrfField(); + if ($this->requestType !== 'get') { + $append .= $this->_csrfField(); + } if (!empty($append)) { $append = $this->Html->useTag('block', ' style="display:none;"', $append); @@ -504,7 +506,11 @@ class FormHelper extends AppHelper { } $out .= $this->submit($submit, $submitOptions); } - if (isset($this->request['_Token']) && !empty($this->request['_Token'])) { + if ( + $this->requestType !== 'get' && + isset($this->request['_Token']) && + !empty($this->request['_Token']) + ) { $out .= $this->secure($this->fields); $this->fields = array(); }