From e6aeae8935b4fc7b98b83c12601ba5bfd57ebb6a Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 31 Oct 2010 22:41:33 -0400 Subject: [PATCH 01/46] Fixing issue where value in difference array was always the string value instead of the original value. --- cake/libs/model/cake_schema.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/libs/model/cake_schema.php b/cake/libs/model/cake_schema.php index 8135d186d..541cc943f 100644 --- a/cake/libs/model/cake_schema.php +++ b/cake/libs/model/cake_schema.php @@ -550,9 +550,9 @@ class CakeSchema extends Object { $difference[$key] = $value; continue; } - $value = strval($value); + $compare = strval($value); $correspondingValue = strval($correspondingValue); - if ($value === $correspondingValue) { + if ($compare === $correspondingValue) { continue; } $difference[$key] = $value; From 3dc1f6edfafbb27dd5af76e24f3e7ff1e42169eb Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 2 Nov 2010 19:06:48 +0530 Subject: [PATCH 02/46] Fixed the minutes into seconds for session timeout Fixes #1255 Signed-off-by: mark_story --- app/config/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/core.php b/app/config/core.php index a0ae31f67..413718e8c 100644 --- a/app/config/core.php +++ b/app/config/core.php @@ -167,7 +167,7 @@ Configure::write('Session.cookie', 'CAKEPHP'); /** - * Session time out time (in minutes). + * Session time out time (in seconds). * Actual value depends on 'Security.level' setting. */ Configure::write('Session.timeout', '120'); From 2403d7fedce5cd1a5b30232b91614789c32ed4a4 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 2 Nov 2010 21:43:33 -0400 Subject: [PATCH 03/46] Applying updates to skel/core.php. Fixes #1255 --- cake/console/templates/skel/config/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/console/templates/skel/config/core.php b/cake/console/templates/skel/config/core.php index a0ae31f67..413718e8c 100644 --- a/cake/console/templates/skel/config/core.php +++ b/cake/console/templates/skel/config/core.php @@ -167,7 +167,7 @@ Configure::write('Session.cookie', 'CAKEPHP'); /** - * Session time out time (in minutes). + * Session time out time (in seconds). * Actual value depends on 'Security.level' setting. */ Configure::write('Session.timeout', '120'); From d1403b0da8b0e2f1b4efad510e2891a0e4c50928 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 2 Nov 2010 21:56:24 -0400 Subject: [PATCH 04/46] =?UTF-8?q?Changing=20NumberHelper::currency()=20to?= =?UTF-8?q?=20format=20<=201euro=20based=20on=20the=20suggestions=20from?= =?UTF-8?q?=20'Joel=20Haasnoot'.=20=20Instead=20of=2099c=20you=20will=20ge?= =?UTF-8?q?t=20=E2=82=AC0,99.=20Test=20cases=20updated.=20=20Fixes=20#1253?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cake/libs/view/helpers/number.php | 2 +- cake/tests/cases/libs/view/helpers/number.test.php | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cake/libs/view/helpers/number.php b/cake/libs/view/helpers/number.php index 236732a92..3abf3517f 100644 --- a/cake/libs/view/helpers/number.php +++ b/cake/libs/view/helpers/number.php @@ -48,7 +48,7 @@ class NumberHelper extends AppHelper { 'decimals' => '.', 'negative' => '()','escape' => false ), 'EUR' => array( - 'before'=>'€', 'after' => 'c', 'zero' => 0, 'places' => 2, 'thousands' => '.', + 'before'=>'€', 'after' => false, 'zero' => 0, 'places' => 2, 'thousands' => '.', 'decimals' => ',', 'negative' => '()', 'escape' => false ) ); diff --git a/cake/tests/cases/libs/view/helpers/number.test.php b/cake/tests/cases/libs/view/helpers/number.test.php index 9f2d238de..d5f88aa61 100644 --- a/cake/tests/cases/libs/view/helpers/number.test.php +++ b/cake/tests/cases/libs/view/helpers/number.test.php @@ -236,7 +236,7 @@ class NumberHelperTest extends CakeTestCase { $this->assertEqual($expected, $result); $result = $this->Number->currency($value, 'EUR'); - $expected = '99c'; + $expected = '€0,99'; $this->assertEqual($expected, $result); $result = $this->Number->currency($value, 'GBP'); @@ -258,7 +258,7 @@ class NumberHelperTest extends CakeTestCase { $this->assertEqual($expected, $result); $result = $this->Number->currency($value, 'EUR'); - $expected = '(99c)'; + $expected = '(€0,99)'; $this->assertEqual($expected, $result); $result = $this->Number->currency($value, 'GBP'); @@ -270,7 +270,7 @@ class NumberHelperTest extends CakeTestCase { $this->assertEqual($expected, $result); $result = $this->Number->currency($value, 'EUR', array('negative'=>'-')); - $expected = '-99c'; + $expected = '-€0,99'; $this->assertEqual($expected, $result); $result = $this->Number->currency($value, 'GBP', array('negative'=>'-')); @@ -336,6 +336,10 @@ class NumberHelperTest extends CakeTestCase { $result = $this->Number->currency('0.35', 'GBP'); $expected = '35p'; $this->assertEqual($expected, $result); + + $result = $this->Number->currency('0.35', 'EUR'); + $expected = '€0,35'; + $this->assertEqual($expected, $result); } /** From 81ce6f40b9f78d8e092d8672ad3bcbd5288412fb Mon Sep 17 00:00:00 2001 From: ADmad Date: Thu, 4 Nov 2010 17:59:23 +0530 Subject: [PATCH 05/46] Added test cases showing usage of 'full_base' key for url generation. Refs #1256 --- cake/tests/cases/libs/router.test.php | 18 ++++++++++-------- .../cases/libs/view/helpers/paginator.test.php | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/cake/tests/cases/libs/router.test.php b/cake/tests/cases/libs/router.test.php index 2e69ab7fc..8346dfec8 100644 --- a/cake/tests/cases/libs/router.test.php +++ b/cake/tests/cases/libs/router.test.php @@ -74,6 +74,8 @@ class RouterTest extends CakeTestCase { function testFullBaseURL() { $this->assertPattern('/^http(s)?:\/\//', Router::url('/', true)); $this->assertPattern('/^http(s)?:\/\//', Router::url(null, true)); + $this->assertPattern('/^http(s)?:\/\//', Router::url(array('full_base' => true))); + $this->assertIdentical(FULL_BASE_URL . '/', Router::url(array('full_base' => true))); } /** @@ -1702,8 +1704,8 @@ class RouterTest extends CakeTestCase { function testParsingWithPatternOnAction() { Router::reload(); Router::connect( - '/blog/:action/*', - array('controller' => 'blog_posts'), + '/blog/:action/*', + array('controller' => 'blog_posts'), array('action' => 'other|actions') ); $result = Router::parse('/blog/other'); @@ -1725,7 +1727,7 @@ class RouterTest extends CakeTestCase { 'named' => array() ); $this->assertEqual($expected, $result); - + $result = Router::url(array('controller' => 'blog_posts', 'action' => 'foo')); $this->assertEqual('/blog_posts/foo', $result); @@ -2535,20 +2537,20 @@ class CakeRouteTestCase extends CakeTestCase { */ function testPatternOnAction() { $route =& new CakeRoute( - '/blog/:action/*', - array('controller' => 'blog_posts'), + '/blog/:action/*', + array('controller' => 'blog_posts'), array('action' => 'other|actions') ); $result = $route->match(array('controller' => 'blog_posts', 'action' => 'foo')); $this->assertFalse($result); - + $result = $route->match(array('controller' => 'blog_posts', 'action' => 'actions')); $this->assertTrue($result); - + $result = $route->parse('/blog/other'); $expected = array('controller' => 'blog_posts', 'action' => 'other', 'pass' => array(), 'named' => array()); $this->assertEqual($expected, $result); - + $result = $route->parse('/blog/foobar'); $this->assertFalse($result); } diff --git a/cake/tests/cases/libs/view/helpers/paginator.test.php b/cake/tests/cases/libs/view/helpers/paginator.test.php index f2f1a25e7..1e78415cd 100644 --- a/cake/tests/cases/libs/view/helpers/paginator.test.php +++ b/cake/tests/cases/libs/view/helpers/paginator.test.php @@ -21,6 +21,10 @@ App::import('Helper', array('Html', 'Paginator', 'Form', 'Ajax', 'Javascript', ' Mock::generate('JsHelper', 'PaginatorMockJsHelper'); +if (!defined('FULL_BASE_URL')) { + define('FULL_BASE_URL', 'http://cakephp.org'); +} + /** * PaginatorHelperTest class * @@ -1718,6 +1722,16 @@ class PaginatorHelperTest extends CakeTestCase { '/span', ); $this->assertTags($result, $expected); + + $this->Paginator->options(array('url' => array('full_base' => true))); + $result = $this->Paginator->first(); + + $expected = array( + ' array('href' => FULL_BASE_URL . '/index/page:1/sort:Client.name/direction:DESC')), '<< first', '/a', + '/span', + ); + $this->assertTags($result, $expected); } /** From d56b81218139db77f7fc7a75594aa97b47cc04d5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 4 Nov 2010 21:08:40 -0400 Subject: [PATCH 06/46] Fixing issue where an array to string conversion error could occur if you had multiple values for a model's primary key and you created a matching form. Tests added. Fixes #1257 --- cake/libs/view/helpers/form.php | 3 ++- .../cases/libs/view/helpers/form.test.php | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/cake/libs/view/helpers/form.php b/cake/libs/view/helpers/form.php index 9f7b5340b..538d844e5 100644 --- a/cake/libs/view/helpers/form.php +++ b/cake/libs/view/helpers/form.php @@ -221,7 +221,8 @@ class FormHelper extends AppHelper { $data = $this->fieldset[$modelEntity]; $recordExists = ( isset($this->data[$model]) && - !empty($this->data[$model][$data['key']]) + !empty($this->data[$model][$data['key']]) && + !is_array($this->data[$model][$data['key']]) ); if ($recordExists) { diff --git a/cake/tests/cases/libs/view/helpers/form.test.php b/cake/tests/cases/libs/view/helpers/form.test.php index bc1683849..0dc83aed7 100644 --- a/cake/tests/cases/libs/view/helpers/form.test.php +++ b/cake/tests/cases/libs/view/helpers/form.test.php @@ -5626,6 +5626,31 @@ class FormHelperTest extends CakeTestCase { $this->assertTags($result, $expected, true); } +/** + * test that create() doesn't cause errors by multiple id's being in the primary key + * as could happen with multiple select or checkboxes. + * + * @return void + */ + function testCreateWithMultipleIdInData() { + $encoding = strtolower(Configure::read('App.encoding')); + + $this->Form->data['Contact']['id'] = array(1, 2); + $result = $this->Form->create('Contact'); + $expected = array( + 'form' => array( + 'id' => 'ContactAddForm', + 'method' => 'post', + 'action' => '/contacts/add', + 'accept-charset' => $encoding + ), + 'div' => array('style' => 'display:none;'), + 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'), + '/div' + ); + $this->assertTags($result, $expected); + } + /** * test that create() doesn't add in extra passed params. * From 268dae722e3ff663cfc2812e86a99ed8c254c96e Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 5 Nov 2010 22:31:41 -0400 Subject: [PATCH 07/46] Reverting change from [16387f196191c5cb942f887f05456cb439944f41]. Using the constant caused a number of issues for several other people. Refs #1231 --- cake/dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/dispatcher.php b/cake/dispatcher.php index 5080bfe90..1597c666f 100644 --- a/cake/dispatcher.php +++ b/cake/dispatcher.php @@ -339,7 +339,7 @@ class Dispatcher extends Object { if ($webroot === 'webroot' && $webroot === basename($base)) { $base = dirname($base); } - if ($dir === APP_DIR && $dir === basename($base)) { + if ($dir === 'app' && $dir === basename($base)) { $base = dirname($base); } From eb76ab95f23ba9daa2b97b365f63a783a7d302cc Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 3 Nov 2010 18:55:42 +0530 Subject: [PATCH 08/46] Fixed issue where Model::saveAll() would incorrectly commit a transaction which was not started in that function call itself. --- cake/libs/model/model.php | 20 +++++++++++++------ .../cases/libs/model/model_write.test.php | 16 +++++++++++++++ cake/tests/cases/libs/model/models.php | 17 +++++++++++++--- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index 30ee27996..2cd1debaa 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -559,9 +559,9 @@ class Model extends Overloadable { * * Example: Turn off the associated Model Support request, * to temporarily lighten the User model: - * + * * `$this->User->unbindModel( array('hasMany' => array('Supportrequest')) );` - * + * * unbound models that are not made permanent will reset with the next call to Model::find() * * @param array $params Set of bindings to unbind (indexed by binding type) @@ -1589,7 +1589,7 @@ class Model extends Overloadable { } if ($options['atomic'] && $options['validate'] !== 'only') { - $db->begin($this); + $transactionBegun = $db->begin($this); } if (Set::numeric(array_keys($data))) { @@ -1629,8 +1629,12 @@ class Model extends Overloadable { break; default: if ($options['atomic']) { - if ($validates && ($db->commit($this) !== false)) { - return true; + if ($validates) { + if ($transactionBegun) { + return $db->commit($this) !== false; + } else { + return true; + } } $db->rollback($this); return false; @@ -1740,7 +1744,11 @@ class Model extends Overloadable { default: if ($options['atomic']) { if ($validates) { - return ($db->commit($this) !== false); + if ($transactionBegun) { + return $db->commit($this) !== false; + } else { + return true; + } } else { $db->rollback($this); } diff --git a/cake/tests/cases/libs/model/model_write.test.php b/cake/tests/cases/libs/model/model_write.test.php index 03b8d9c84..34133d31f 100644 --- a/cake/tests/cases/libs/model/model_write.test.php +++ b/cake/tests/cases/libs/model/model_write.test.php @@ -3121,6 +3121,22 @@ class ModelWriteTest extends BaseModelTest { $Post->saveAll($data); } +/** + * test saveAll with nested saveAll call. + * + * @return void + */ + function testSaveAllNestedSaveAll() { + $this->loadFixtures('Sample'); + $TransactionTestModel =& new TransactionTestModel(); + + $data = array( + array('apple_id' => 1, 'name' => 'sample5'), + ); + + $this->assertTrue($TransactionTestModel->saveAll($data, array('atomic' => true))); + } + /** * testSaveAllTransaction method * diff --git a/cake/tests/cases/libs/model/models.php b/cake/tests/cases/libs/model/models.php index 890b4f284..febb073cc 100644 --- a/cake/tests/cases/libs/model/models.php +++ b/cake/tests/cases/libs/model/models.php @@ -290,7 +290,7 @@ class Article extends CakeTestModel { */ class BeforeDeleteComment extends CakeTestModel { var $name = 'BeforeDeleteComment'; - + var $useTable = 'comments'; function beforeDelete($cascade = true) { @@ -3557,6 +3557,7 @@ class FruitNoWith extends CakeTestModel { ) ); } + class UuidTagNoWith extends CakeTestModel { var $name = 'UuidTag'; var $useTable = 'uuid_tags'; @@ -3573,11 +3574,21 @@ class UuidTagNoWith extends CakeTestModel { class ProductUpdateAll extends CakeTestModel { var $name = 'ProductUpdateAll'; var $useTable = 'product_update_all'; - } class GroupUpdateAll extends CakeTestModel { var $name = 'GroupUpdateAll'; var $useTable = 'group_update_all'; - } + +class TransactionTestModel extends CakeTestModel { + var $name = 'TransactionTestModel'; + var $useTable = 'samples'; + + function afterSave($created) { + $data = array( + array('apple_id' => 1, 'name' => 'sample6'), + ); + $this->saveAll($data, array('atomic' => true, 'callbacks' => false)); + } +} \ No newline at end of file From e431e86aa4301ced4273dc7919b59362cbb353cb Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 7 Nov 2010 20:53:04 -0500 Subject: [PATCH 09/46] Fixing issue found by Felix Wilhelm(flxm) where users could send potentially dangerous or corrupted serialized objects to SecurityComponent, potentially allowing manipulation of file map caches. Test case added. --- cake/libs/controller/components/security.php | 7 +++++- .../controller/components/security.test.php | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/cake/libs/controller/components/security.php b/cake/libs/controller/components/security.php index c267c6ce1..7e5b3b28f 100644 --- a/cake/libs/controller/components/security.php +++ b/cake/libs/controller/components/security.php @@ -618,10 +618,15 @@ class SecurityComponent extends Object { } unset($check['_Token']); + $locked = str_rot13($locked); + if (preg_match('/(\A|;|{|})O\:[0-9]+/', $locked)) { + return false; + } + $lockedFields = array(); $fields = Set::flatten($check); $fieldList = array_keys($fields); - $locked = unserialize(str_rot13($locked)); + $locked = unserialize($locked); $multi = array(); foreach ($fieldList as $i => $key) { diff --git a/cake/tests/cases/libs/controller/components/security.test.php b/cake/tests/cases/libs/controller/components/security.test.php index 883f1c810..bbd514100 100644 --- a/cake/tests/cases/libs/controller/components/security.test.php +++ b/cake/tests/cases/libs/controller/components/security.test.php @@ -608,6 +608,30 @@ DIGEST; $result = $this->Controller->Security->validatePost($this->Controller); $this->assertFalse($result, 'validatePost passed when key was missing. %s'); } + +/** + * Test that objects can't be passed into the serialized string. This was a vector for RFI and LFI + * attacks. Thanks to Felix Wilhelm + * + * @return void + */ + function testValidatePostObjectDeserialize() { + $this->Controller->Security->startup($this->Controller); + $key = $this->Controller->params['_Token']['key']; + $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877'; + + // a corrupted serialized object, so we can see if it ever gets to deserialize + $attack = 'O:3:"App":1:{s:5:"__map";a:1:{s:3:"foo";s:7:"Hacked!";s:1:"fail"}}'; + $fields .= urlencode(':' . str_rot13($attack)); + + $this->Controller->data = array( + 'Model' => array('username' => 'mark', 'password' => 'foo', 'valid' => '0'), + '_Token' => compact('key', 'fields') + ); + $result = $this->Controller->Security->validatePost($this->Controller); + $this->assertFalse($result, 'validatePost passed when key was missing. %s'); + } + /** * Tests validation of checkbox arrays * From bc7770aa83ef0fed5d523923ae91f4aad0a23c2b Mon Sep 17 00:00:00 2001 From: Ceeram Date: Mon, 8 Nov 2010 01:14:03 +0100 Subject: [PATCH 10/46] removing useless calls to mapActions() Signed-off-by: mark_story --- cake/libs/controller/components/auth.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/cake/libs/controller/components/auth.php b/cake/libs/controller/components/auth.php index 053514d19..759c5be36 100644 --- a/cake/libs/controller/components/auth.php +++ b/cake/libs/controller/components/auth.php @@ -527,7 +527,6 @@ class AuthComponent extends Object { $valid = $this->Acl->check($user, $this->action()); break; case 'crud': - $this->mapActions(); if (!isset($this->actionMap[$this->params['action']])) { trigger_error( sprintf(__('Auth::startup() - Attempted access of un-mapped action "%1$s" in controller "%2$s"', true), $this->params['action'], $this->params['controller']), @@ -542,7 +541,6 @@ class AuthComponent extends Object { } break; case 'model': - $this->mapActions(); $action = $this->params['action']; if (isset($this->actionMap[$action])) { $action = $this->actionMap[$action]; From e8678b38acc898f0756fdf8875d6661c3020b87f Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 8 Nov 2010 21:50:45 -0500 Subject: [PATCH 11/46] Adding specific conditions to model->delete's call to dbo->delete. This helps fix a race condition where dbo->defaultConditions could cause additional data loss. Fixes #250 --- cake/libs/model/model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index 2cd1debaa..190a3660c 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -1831,7 +1831,7 @@ class Model extends Overloadable { )); } - if ($db->delete($this)) { + if ($db->delete($this, array($this->alias . '.' . $this->primaryKey => $id))) { if (!empty($this->belongsTo)) { $this->updateCounterCache($keys[$this->alias]); } From a1467822fbb50d4b524e2a98560ff74783f8af70 Mon Sep 17 00:00:00 2001 From: Mariano Iglesias Date: Wed, 10 Nov 2010 15:35:00 -0300 Subject: [PATCH 12/46] Fixing wrong assertion in test for CakeTestCase::testAction. Fixing testAction issue that would always include layout --- cake/tests/cases/libs/cake_test_case.test.php | 8 ++++---- cake/tests/lib/cake_test_case.php | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/cake/tests/cases/libs/cake_test_case.test.php b/cake/tests/cases/libs/cake_test_case.test.php index f88b99378..e9f885fab 100644 --- a/cake/tests/cases/libs/cake_test_case.test.php +++ b/cake/tests/cases/libs/cake_test_case.test.php @@ -184,7 +184,7 @@ class CakeTestCaseTest extends CakeTestCase { '/a' ); $this->assertTrue($this->Case->assertTags($input, $pattern), 'Single quoted attributes %s'); - + $input = "My link"; $pattern = array( 'a' => array('href' => 'preg:/.*\.html/', 'class' => 'active'), @@ -348,10 +348,10 @@ class CakeTestCaseTest extends CakeTestCase { ), true); $result = $this->Case->testAction('/tests_apps/index', array('return' => 'view')); - $this->assertPattern('/This is the TestsAppsController index view/', $result); + $this->assertPattern('/^\s*This is the TestsAppsController index view\s*$/i', $result); $result = $this->Case->testAction('/tests_apps/index', array('return' => 'contents')); - $this->assertPattern('/This is the TestsAppsController index view/', $result); + $this->assertPattern('/\bThis is the TestsAppsController index view\b/i', $result); $this->assertPattern('/assertPattern('/<\/html>/', $result); @@ -499,4 +499,4 @@ class CakeTestCaseTest extends CakeTestCase { $return = $Dispatcher->dispatch('/tests_apps/index', array('autoRender' => 0, 'return' => 1, 'requested' => 1)); } -} +} \ No newline at end of file diff --git a/cake/tests/lib/cake_test_case.php b/cake/tests/lib/cake_test_case.php index 06a96b51d..1d4b89eb5 100644 --- a/cake/tests/lib/cake_test_case.php +++ b/cake/tests/lib/cake_test_case.php @@ -64,6 +64,10 @@ class CakeTestDispatcher extends Dispatcher { function _invoke(&$controller, $params, $missingAction = false) { $this->controller =& $controller; + if (array_key_exists('layout', $params)) { + $this->controller->layout = $params['layout']; + } + if (isset($this->testCase) && method_exists($this->testCase, 'startController')) { $this->testCase->startController($this->controller, $params); } @@ -828,4 +832,4 @@ class CakeTestCase extends UnitTestCase { return $permuted; } } -} +} \ No newline at end of file From 76a80c262e519bf256884de72f9a0909b04d9fca Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 13 Nov 2010 12:04:22 -0500 Subject: [PATCH 13/46] Fixing failing test caused by name() being able to quote things better now. --- cake/tests/cases/libs/model/datasources/dbo/dbo_mysql.test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/tests/cases/libs/model/datasources/dbo/dbo_mysql.test.php b/cake/tests/cases/libs/model/datasources/dbo/dbo_mysql.test.php index 59298f134..32dad2626 100644 --- a/cake/tests/cases/libs/model/datasources/dbo/dbo_mysql.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo/dbo_mysql.test.php @@ -824,7 +824,7 @@ class DboMysqlTest extends CakeTestCase { $this->db->virtualFieldSeparator = '_$_'; $result = $this->db->fields($model, null, array('data', 'other__field')); - $expected = array('`BinaryTest`.`data`', '(SUM(id)) AS BinaryTest_$_other__field'); + $expected = array('`BinaryTest`.`data`', '(SUM(id)) AS `BinaryTest_$_other__field`'); $this->assertEqual($result, $expected); } From 4c3337598e9355bd866f90c25253b39b908283a3 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 13 Nov 2010 20:01:20 -0500 Subject: [PATCH 14/46] Updating version numbers for 1.3.6 --- cake/VERSION.txt | 3 ++- cake/config/config.php | 2 +- cake/libs/view/pages/home.ctp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cake/VERSION.txt b/cake/VERSION.txt index 1f0f7116b..e5c64475c 100644 --- a/cake/VERSION.txt +++ b/cake/VERSION.txt @@ -18,7 +18,8 @@ // @license MIT License (http://www.opensource.org/licenses/mit-license.php) // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -1.3.5 +1.3.6 + diff --git a/cake/config/config.php b/cake/config/config.php index 590aea6f8..09c4eec5b 100644 --- a/cake/config/config.php +++ b/cake/config/config.php @@ -17,4 +17,4 @@ * @since CakePHP(tm) v 1.1.11.4062 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -return $config['Cake.version'] = '1.3.5'; +return $config['Cake.version'] = '1.3.6'; diff --git a/cake/libs/view/pages/home.ctp b/cake/libs/view/pages/home.ctp index be2c09f28..e2cc74cee 100644 --- a/cake/libs/view/pages/home.ctp +++ b/cake/libs/view/pages/home.ctp @@ -21,7 +21,7 @@ if (Configure::read() == 0): endif; ?>

- + 0): Debugger::checkSecurityKeys(); From 5349257bbd90450ed0cfd60873d10274749e64b1 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 07:32:14 -0500 Subject: [PATCH 15/46] Changing empty() to !isset() to avoid additional cache hits when po files are missing or empty. --- cake/libs/i18n.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/libs/i18n.php b/cake/libs/i18n.php index 74ab9406b..f1234d46a 100644 --- a/cake/libs/i18n.php +++ b/cake/libs/i18n.php @@ -148,11 +148,11 @@ class I18n extends Object { $_this->domain = $domain . '_' . $_this->l10n->lang; - if (empty($_this->__domains[$domain][$_this->__lang])) { + if (!isset($_this->__domains[$domain][$_this->__lang])) { $_this->__domains[$domain][$_this->__lang] = Cache::read($_this->domain, '_cake_core_'); } - if (empty($_this->__domains[$domain][$_this->__lang][$_this->category])) { + if (!isset($_this->__domains[$domain][$_this->__lang][$_this->category])) { $_this->__bindTextDomain($domain); Cache::write($_this->domain, $_this->__domains[$domain][$_this->__lang], '_cake_core_'); } From d89581dcca3cd6d395e0af1b0f277910792ec1fc Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 21:54:05 -0500 Subject: [PATCH 16/46] Changing object construction and method call to use file_put_contents. --- cake/libs/log/file_log.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cake/libs/log/file_log.php b/cake/libs/log/file_log.php index ab319fc33..fbd4cff3e 100644 --- a/cake/libs/log/file_log.php +++ b/cake/libs/log/file_log.php @@ -67,9 +67,6 @@ class FileLog implements CakeLogInterface { $filename = $this->_path . $type . '.log'; } $output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n"; - $log = new SplFileObject($filename, 'a+'); - if ($log->isWritable()) { - return $log->fwrite($output); - } + return file_put_contents($filename, $output, FILE_APPEND); } } From 47f6a2999841bdca866725e3ffa28986ef59ffb5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 22:24:54 -0500 Subject: [PATCH 17/46] Small optimizations in env() and Helper::_parseAttributes(). --- cake/basics.php | 4 ++-- cake/libs/view/helper.php | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cake/basics.php b/cake/basics.php index 602bec763..c41301ea1 100644 --- a/cake/basics.php +++ b/cake/basics.php @@ -264,14 +264,14 @@ if (!function_exists('sortByKey')) { * @link http://book.cakephp.org/view/1130/env */ function env($key) { - if ($key == 'HTTPS') { + if ($key === 'HTTPS') { if (isset($_SERVER['HTTPS'])) { return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); } return (strpos(env('SCRIPT_URI'), 'https://') === 0); } - if ($key == 'SCRIPT_NAME') { + if ($key === 'SCRIPT_NAME') { if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) { $key = 'SCRIPT_URL'; } diff --git a/cake/libs/view/helper.php b/cake/libs/view/helper.php index 68466a25f..20e41953c 100644 --- a/cake/libs/view/helper.php +++ b/cake/libs/view/helper.php @@ -355,14 +355,13 @@ class Helper extends Object { if (!is_array($exclude)) { $exclude = array(); } - $keys = array_diff(array_keys($options), array_merge($exclude, array('escape'))); - $values = array_intersect_key(array_values($options), $keys); + $filtered = array_diff_key($options, array_merge(array_flip($exclude), array('escape' => true))); $escape = $options['escape']; $attributes = array(); - foreach ($keys as $index => $key) { - if ($values[$index] !== false && $values[$index] !== null) { - $attributes[] = $this->__formatAttribute($key, $values[$index], $escape); + foreach ($filtered as $key => $value) { + if ($value !== false && $value !== null) { + $attributes[] = $this->__formatAttribute($key, $value, $escape); } } $out = implode(' ', $attributes); From ba10003ef24381e7cea8c40a3e32ff1e0f88a3e7 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 22:52:49 -0500 Subject: [PATCH 18/46] Fixing failing tests when HtmlHelper test was run by itself. --- cake/tests/cases/libs/view/helpers/html.test.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index dd4e85708..2defe93ab 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -90,6 +90,8 @@ class HtmlHelperTest extends CakeTestCase { $this->Html = new HtmlHelper($this->View); $this->Html->request = new CakeRequest(null, false); $this->Html->request->webroot = ''; + + Configure::write('Asset.timestamp', false); } /** @@ -262,7 +264,6 @@ class HtmlHelperTest extends CakeTestCase { */ function testImageTag() { $this->Html->request->webroot = ''; - Configure::write('Asset.timestamp', false); $result = $this->Html->image('test.gif'); $this->assertTags($result, array('img' => array('src' => 'img/test.gif', 'alt' => ''))); @@ -354,7 +355,6 @@ class HtmlHelperTest extends CakeTestCase { * @return void */ function testThemeAssetsInMainWebrootPath() { - Configure::write('Asset.timestamp', false); App::build(array( 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS) )); @@ -402,7 +402,6 @@ class HtmlHelperTest extends CakeTestCase { * @return void */ function testCssLink() { - Configure::write('Asset.timestamp', false); Configure::write('Asset.filter.css', false); $result = $this->Html->css('screen'); @@ -528,7 +527,6 @@ class HtmlHelperTest extends CakeTestCase { * @return void */ function testScript() { - Configure::write('Asset.timestamp', false); $result = $this->Html->script('foo'); $expected = array( 'script' => array('type' => 'text/javascript', 'src' => 'js/foo.js') From bed7767258969698b04dcd31ad98f0f70b9938fb Mon Sep 17 00:00:00 2001 From: PhpNut Date: Wed, 17 Nov 2010 14:02:35 -0600 Subject: [PATCH 19/46] Removing __cache property that can be altered outside of the class definition. Adding __resetCache() as a replacement for checking if cache should be reset and written. --- cake/libs/configure.php | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/cake/libs/configure.php b/cake/libs/configure.php index 7166546b8..8e254266e 100644 --- a/cake/libs/configure.php +++ b/cake/libs/configure.php @@ -579,14 +579,6 @@ class App extends Object { */ var $return = false; -/** - * Determines if $__maps and $__paths cache should be written. - * - * @var boolean - * @access private - */ - var $__cache = false; - /** * Holds key/value pairs of $type => file path. * @@ -836,7 +828,7 @@ class App extends Object { } if ($cache === true) { - $_this->__cache = true; + $_this->__resetCache(true); } $_this->__objects[$name] = $objects; } @@ -932,7 +924,7 @@ class App extends Object { return true; } else { $_this->__remove($name . $ext['class'], $type, $plugin); - $_this->__cache = true; + $_this->__resetCache(true); } } if (!empty($search)) { @@ -963,7 +955,7 @@ class App extends Object { } if ($directory !== null) { - $_this->__cache = true; + $_this->__resetCache(true); $_this->__map($directory . $file, $name . $ext['class'], $type, $plugin); $_this->__overload($type, $name . $ext['class'], $parent); @@ -1292,6 +1284,21 @@ class App extends Object { } return $items; } + +/** + * Determines if $__maps and $__paths cache should be reset. + * + * @param boolean $reset + * @return boolean + * @access private + */ + function __resetCache($reset = null) { + static $cache = array(); + if (!$cache && $reset === true) { + $cache = true; + } + return $cache; + } /** * Object destructor. @@ -1302,7 +1309,7 @@ class App extends Object { * @access private */ function __destruct() { - if ($this->__cache) { + if ($this->__resetCache() === true) { $core = App::core('cake'); unset($this->__paths[rtrim($core[0], DS)]); Cache::write('dir_map', array_filter($this->__paths), '_cake_core_'); @@ -1310,4 +1317,4 @@ class App extends Object { Cache::write('object_map', $this->__objects, '_cake_core_'); } } -} +} \ No newline at end of file From 82d46067ab67c2027f6d469b392955fd019a1383 Mon Sep 17 00:00:00 2001 From: PhpNut Date: Wed, 17 Nov 2010 15:00:27 -0600 Subject: [PATCH 20/46] Corrected doc comment. --- cake/libs/configure.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/libs/configure.php b/cake/libs/configure.php index 8e254266e..e3e8e7835 100644 --- a/cake/libs/configure.php +++ b/cake/libs/configure.php @@ -1286,7 +1286,7 @@ class App extends Object { } /** - * Determines if $__maps and $__paths cache should be reset. + * Determines if $__maps, $__objects and $__paths cache should be reset. * * @param boolean $reset * @return boolean From e0a8ffe8a34937ab261b442505863d502987f0aa Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 20 Nov 2010 13:26:30 -0500 Subject: [PATCH 21/46] Applying patch from 'jmccaffrey' to fix issues on windows where virtual machine paths would not be correctly handled. Fixes #1254 --- cake/libs/folder.php | 4 ++-- cake/tests/cases/libs/folder.test.php | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cake/libs/folder.php b/cake/libs/folder.php index 3886633ed..97de64e8c 100644 --- a/cake/libs/folder.php +++ b/cake/libs/folder.php @@ -258,7 +258,7 @@ class Folder extends Object { * @static */ function isWindowsPath($path) { - return (bool)preg_match('/^[A-Z]:\\\\/i', $path); + return (preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\'); } /** @@ -270,7 +270,7 @@ class Folder extends Object { * @static */ function isAbsolute($path) { - return !empty($path) && ($path[0] === '/' || preg_match('/^[A-Z]:\\\\/i', $path)); + return !empty($path) && ($path[0] === '/' || preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\'); } /** diff --git a/cake/tests/cases/libs/folder.test.php b/cake/tests/cases/libs/folder.test.php index 61d0478e6..3b214642a 100644 --- a/cake/tests/cases/libs/folder.test.php +++ b/cake/tests/cases/libs/folder.test.php @@ -366,6 +366,7 @@ class FolderTest extends CakeTestCase { $this->assertFalse(Folder::isWindowsPath('0:\\cake\\is\\awesome')); $this->assertTrue(Folder::isWindowsPath('C:\\cake\\is\\awesome')); $this->assertTrue(Folder::isWindowsPath('d:\\cake\\is\\awesome')); + $this->assertTrue(Folder::isWindowsPath('\\\\vmware-host\\Shared Folders\\file')); } /** @@ -387,6 +388,7 @@ class FolderTest extends CakeTestCase { $this->assertTrue(Folder::isAbsolute('C:\\cake')); $this->assertTrue(Folder::isAbsolute('C:\\path\\to\\file')); $this->assertTrue(Folder::isAbsolute('d:\\path\\to\\file')); + $this->assertTrue(Folder::isAbsolute('\\\\vmware-host\\Shared Folders\\file')); } /** From 6d9b000aeeffd17811a0c774ce02638b6360fc7e Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 20 Nov 2010 22:34:24 -0500 Subject: [PATCH 22/46] Changing how mergeVars are handled, so the difference of app/current is used as a base. Also fixing issues where passing settings to helpers in AppController could result in them not being correctly merged. Thanks to hashmich for the partial patch. Fixes #1183 --- cake/libs/controller/controller.php | 8 +++---- .../cases/libs/controller/controller.test.php | 2 +- .../controller/controller_merge_vars.test.php | 23 +++++++++++++++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 6b75ea324..4a9827975 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -430,7 +430,7 @@ class Controller extends Object { foreach ($merge as $var) { if (!empty($appVars[$var]) && is_array($this->{$var})) { - if ($var === 'components') { + if ($var !== 'uses') { $normal = Set::normalize($this->{$var}); $app = Set::normalize($appVars[$var]); if ($app !== $normal) { @@ -438,7 +438,7 @@ class Controller extends Object { } } else { $this->{$var} = Set::merge( - $this->{$var}, array_diff($appVars[$var], $this->{$var}) + array_diff($appVars[$var], $this->{$var}), $this->{$var} ); } } @@ -456,7 +456,7 @@ class Controller extends Object { foreach ($merge as $var) { if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) { - if ($var === 'components') { + if ($var !== 'uses') { $normal = Set::normalize($this->{$var}); $app = Set::normalize($appVars[$var]); if ($app !== $normal) { @@ -464,7 +464,7 @@ class Controller extends Object { } } else { $this->{$var} = Set::merge( - $this->{$var}, array_diff($appVars[$var], $this->{$var}) + array_diff($appVars[$var], $this->{$var}), $this->{$var} ); } } diff --git a/cake/tests/cases/libs/controller/controller.test.php b/cake/tests/cases/libs/controller/controller.test.php index 3fe277939..d73672814 100644 --- a/cake/tests/cases/libs/controller/controller.test.php +++ b/cake/tests/cases/libs/controller/controller.test.php @@ -1149,7 +1149,7 @@ class ControllerTest extends CakeTestCase { ? array_merge($appVars['uses'], $testVars['uses']) : $testVars['uses']; - $this->assertEqual(count(array_diff($TestController->helpers, $helpers)), 0); + $this->assertEqual(count(array_diff_assoc(Set::normalize($TestController->helpers), Set::normalize($helpers))), 0); $this->assertEqual(count(array_diff($TestController->uses, $uses)), 0); $this->assertEqual(count(array_diff_assoc(Set::normalize($TestController->components), Set::normalize($components))), 0); diff --git a/cake/tests/cases/libs/controller/controller_merge_vars.test.php b/cake/tests/cases/libs/controller/controller_merge_vars.test.php index c85e5312b..b98aff1ff 100644 --- a/cake/tests/cases/libs/controller/controller_merge_vars.test.php +++ b/cake/tests/cases/libs/controller/controller_merge_vars.test.php @@ -185,6 +185,25 @@ class ControllerMergeVarsTestCase extends CakeTestCase { $this->assertEqual($Controller->helpers, $expected, 'Duplication of settings occured. %s'); } +/** + * Test that helpers declared in appcontroller come before those in the subclass + * orderwise + * + * @return void + */ + function testHelperOrderPrecedence() { + $Controller =& new MergeVariablesController(); + $Controller->helpers = array('Custom', 'Foo' => array('something')); + $Controller->constructClasses(); + + $expected = array( + 'MergeVar' => array('format' => 'html', 'terse'), + 'Custom' => null, + 'Foo' => array('something') + ); + $this->assertIdentical($Controller->helpers, $expected, 'Order is incorrect. %s'); + } + /** * test merging of vars with plugin * @@ -204,8 +223,8 @@ class ControllerMergeVarsTestCase extends CakeTestCase { $this->assertEqual($Controller->components, $expected, 'Components are unexpected %s'); $expected = array( - 'Javascript', - 'MergeVar' => array('format' => 'html', 'terse') + 'MergeVar' => array('format' => 'html', 'terse'), + 'Javascript' => null ); $this->assertEqual($Controller->helpers, $expected, 'Helpers are unexpected %s'); From ef3cb0e50cc365f248dbf3d731afc28a514bbd55 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 20 Nov 2010 22:46:55 -0500 Subject: [PATCH 23/46] Adding tests for Set::normalize() --- cake/tests/cases/libs/set.test.php | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cake/tests/cases/libs/set.test.php b/cake/tests/cases/libs/set.test.php index 7d0f47e27..ee75ba1a9 100644 --- a/cake/tests/cases/libs/set.test.php +++ b/cake/tests/cases/libs/set.test.php @@ -2988,4 +2988,50 @@ class SetTest extends CakeTestCase { ); $this->assertEqual($result, $expected); } + +/** + * test normalization + * + * @return void + */ + function testNormalizeStrings() { + $result = Set::normalize('one,two,three'); + $expected = array('one' => null, 'two' => null, 'three' => null); + $this->assertEqual($expected, $result); + + $result = Set::normalize('one two three', true, ' '); + $expected = array('one' => null, 'two' => null, 'three' => null); + $this->assertEqual($expected, $result); + + $result = Set::normalize('one , two , three ', true, ',', true); + $expected = array('one' => null, 'two' => null, 'three' => null); + $this->assertEqual($expected, $result); + } + +/** + * test normalizing arrays + * + * @return void + */ + function testNormalizeArrays() { + $result = Set::normalize(array('one', 'two', 'three')); + $expected = array('one' => null, 'two' => null, 'three' => null); + $this->assertEqual($expected, $result); + + $result = Set::normalize(array('one', 'two', 'three'), false); + $expected = array('one', 'two', 'three'); + $this->assertEqual($expected, $result); + + $result = Set::normalize(array('one' => 1, 'two' => 2, 'three' => 3, 'four'), false); + $expected = array('one' => 1, 'two' => 2, 'three' => 3, 'four' => null); + $this->assertEqual($expected, $result); + + $result = Set::normalize(array('one' => 1, 'two' => 2, 'three' => 3, 'four')); + $expected = array('one' => 1, 'two' => 2, 'three' => 3, 'four' => null); + $this->assertEqual($expected, $result); + + $result = Set::normalize(array('one' => array('a', 'b', 'c' => 'cee'), 'two' => 2, 'three')); + $expected = array('one' => array('a', 'b', 'c' => 'cee'), 'two' => 2, 'three' => null); + $this->assertEqual($expected, $result); + } } From b0ddfa07554d17f787566fcad7afd0b9fa1e89a3 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 23:06:25 -0500 Subject: [PATCH 24/46] Added the placeholder class for an 'AppShell'. Conflicts: cake/console/cake.php --- cake/console/cake.php | 1 + cake/console/libs/app_shell.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 cake/console/libs/app_shell.php diff --git a/cake/console/cake.php b/cake/console/cake.php index 2db99284e..02468c38f 100644 --- a/cake/console/cake.php +++ b/cake/console/cake.php @@ -23,3 +23,4 @@ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR. 'shell_dispatcher.php'); return ShellDispatcher::run($argv); + diff --git a/cake/console/libs/app_shell.php b/cake/console/libs/app_shell.php new file mode 100644 index 000000000..f7ccaf3b1 --- /dev/null +++ b/cake/console/libs/app_shell.php @@ -0,0 +1,17 @@ + Date: Tue, 16 Nov 2010 23:08:25 -0500 Subject: [PATCH 25/46] Moving AppShell to where the other shells live. --- cake/console/libs/app_shell.php | 17 ---------------- cake/console/shells/app_shell.php | 33 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 17 deletions(-) delete mode 100644 cake/console/libs/app_shell.php create mode 100644 cake/console/shells/app_shell.php diff --git a/cake/console/libs/app_shell.php b/cake/console/libs/app_shell.php deleted file mode 100644 index f7ccaf3b1..000000000 --- a/cake/console/libs/app_shell.php +++ /dev/null @@ -1,17 +0,0 @@ - Date: Tue, 16 Nov 2010 23:09:22 -0500 Subject: [PATCH 26/46] Adding AppShell to the ignored shell list in CommandListShell. --- cake/console/shells/command_list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/console/shells/command_list.php b/cake/console/shells/command_list.php index 613f65dd7..cd05af4ba 100644 --- a/cake/console/shells/command_list.php +++ b/cake/console/shells/command_list.php @@ -111,7 +111,7 @@ class CommandListShell extends Shell { continue; } foreach ($shells as $shell) { - if ($shell !== 'shell.php') { + if ($shell !== 'shell.php' && $shell !== 'app_shell.php') { $shell = str_replace('.php', '', $shell); $shellList[$shell][$type] = $type; } From 66c9b79c2e711aa9dae0e177f4b6af2da2ec9881 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 23:11:54 -0500 Subject: [PATCH 27/46] Removing App::__overload() it does nothing anymore. --- cake/libs/app.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/cake/libs/app.php b/cake/libs/app.php index 4261447b7..f5f183594 100644 --- a/cake/libs/app.php +++ b/cake/libs/app.php @@ -513,7 +513,6 @@ class App { if ($name != null && !class_exists($name . $ext['class'])) { if ($load = self::__mapped($name . $ext['class'], $type, $plugin)) { if (self::__load($load)) { - self::__overload($type, $name . $ext['class'], $parent); if (self::$return) { return include($load); @@ -554,7 +553,6 @@ class App { if ($directory !== null) { self::$__cache = true; self::__map($directory . $file, $name . $ext['class'], $type, $plugin); - self::__overload($type, $name . $ext['class'], $parent); if (self::$return) { return include($directory . $file); @@ -696,17 +694,6 @@ class App { return false; } -/** - * Used to overload objects as needed. - * - * @param string $type Model or Helper - * @param string $name Class name to overload - * @access private - */ - private static function __overload($type, $name, $parent) { - - } - /** * Loads parent classes based on $type. * Returns a prefix or suffix needed for loading files. From 4f6891705b05a2363c9ccac102c2074ccc39c614 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 23:14:00 -0500 Subject: [PATCH 28/46] Moving Shell test to the same path as the shell class. --- cake/tests/cases/console/{libs => shells}/shell.test.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cake/tests/cases/console/{libs => shells}/shell.test.php (100%) diff --git a/cake/tests/cases/console/libs/shell.test.php b/cake/tests/cases/console/shells/shell.test.php similarity index 100% rename from cake/tests/cases/console/libs/shell.test.php rename to cake/tests/cases/console/shells/shell.test.php From a2bc3699352b5133682410ba8071e8070fa78c72 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 23:19:15 -0500 Subject: [PATCH 29/46] Fixing missing include in HelpFormatter. --- cake/console/libs/help_formatter.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cake/console/libs/help_formatter.php b/cake/console/libs/help_formatter.php index 7af4cadf1..002689899 100644 --- a/cake/console/libs/help_formatter.php +++ b/cake/console/libs/help_formatter.php @@ -17,6 +17,8 @@ * @since CakePHP(tm) v 2.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::import('Core', 'String', false); + /** * HelpFormatter formats help for console shells. Can format to either * text or XML formats. Uses ConsoleOptionParser methods to generate help. From cbd88ede373b45e066d494a82d55fd59363b16cf Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 23:19:46 -0500 Subject: [PATCH 30/46] Adding support for AppShell into App. When you import a Shell class, App will automatically load Shell and AppShell. --- cake/libs/app.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cake/libs/app.php b/cake/libs/app.php index f5f183594..90db2b770 100644 --- a/cake/libs/app.php +++ b/cake/libs/app.php @@ -783,6 +783,9 @@ class App { if (!class_exists('Shell')) { App::import($type, 'Shell', false); } + if (!class_exists('AppModel')) { + App::import($type, 'AppShell', false); + } if ($plugin) { $path = $pluginPath . DS . 'console' . DS . 'shells' . DS; } From a8554df0779dc11a7a4e58c69e1aa4a259c90b70 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 23:32:23 -0500 Subject: [PATCH 31/46] Fixing call to a help method that doesn't exist. --- cake/console/shells/testsuite.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cake/console/shells/testsuite.php b/cake/console/shells/testsuite.php index dacf09dd0..a4e5822b8 100644 --- a/cake/console/shells/testsuite.php +++ b/cake/console/shells/testsuite.php @@ -280,8 +280,7 @@ class TestSuiteShell extends Shell { if (empty($testCases)) { $this->out(__("No test cases available \n\n")); - $this->help(); - $this->_stop(); + return $this->out($this->OptionParser->help()); } $this->out($title); From b80535573e10fcb4249b34c9676fbb62aa3c69f7 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 17 Nov 2010 23:40:19 -0500 Subject: [PATCH 32/46] Adding _mergeVars to Shell. This allows $tasks and $uses to work much like $uses in Controllers, and provides consistency in the framework. Adding tests for merging vars. --- cake/console/shells/shell.php | 30 +++++++++++++++++++ .../tests/cases/console/shells/shell.test.php | 30 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/cake/console/shells/shell.php b/cake/console/shells/shell.php index 8ce538105..5b8e733d7 100644 --- a/cake/console/shells/shell.php +++ b/cake/console/shells/shell.php @@ -164,6 +164,36 @@ class Shell extends Object { if ($this->stdin == null) { $this->stdin = new ConsoleInput('php://stdin'); } + $merge = array(); + if ($this->tasks !== null && $this->tasks !== false) { + $merge[] = 'tasks'; + } + if ($this->uses !== null && $this->uses !== false) { + $merge[] = 'uses'; + } + if (!empty($merge)) { + $this->_mergeVars($merge, get_parent_class($this)); + } + } + +/** + * Merges this objects $property with the property in $class' definition. + * This classes value for the property will be merged on top of $class' + * + * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine + * this method as an empty function. + * + * @param array $properties The name of the properties to merge. + * @param sting $class The class to merge the property with. + * @return void + */ + protected function _mergeVars($properties, $class) { + $classProperties = get_class_vars($class); + foreach ($properties as $var) { + if (isset($classProperties[$var]) && !empty($classProperties[$var]) && is_array($this->{$var})) { + $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); + } + } } /** diff --git a/cake/tests/cases/console/shells/shell.test.php b/cake/tests/cases/console/shells/shell.test.php index 51a3479d3..b7bc7098a 100644 --- a/cake/tests/cases/console/shells/shell.test.php +++ b/cake/tests/cases/console/shells/shell.test.php @@ -69,6 +69,20 @@ class TestShell extends Shell { protected function no_access() { } + + public function mergeVars($properties, $class) { + return $this->_mergeVars($properties, $class); + } +} + +/** + * Class for testing merging vars + * + * @package cake.tests.cases.console + */ +class TestMergeShell extends Shell { + var $tasks = array('DbConfig', 'Fixture'); + var $uses = array('Comment'); } /** @@ -134,6 +148,22 @@ class ShellTest extends CakeTestCase { $this->assertType('ConsoleOutput', $this->Shell->stderr); } +/** + * test merging vars + * + * @return void + */ + function testMergeVars() { + $this->Shell->tasks = array('DbConfig' => array('one', 'two')); + $this->Shell->uses = array('Posts'); + $this->Shell->mergeVars(array('tasks', 'uses'), 'TestMergeShell'); + + $this->assertEquals(array('DbConfig', 'Fixture', 'DbConfig' => array('one', 'two')), $this->Shell->tasks); + $expected = array('Fixture' => null, 'DbConfig' => array('one', 'two')); + $this->assertEquals($expected, Set::normalize($this->Shell->tasks), 'Normalized results are wrong.'); + $this->assertEquals(array('Comment', 'Posts'), $this->Shell->uses, 'Merged models are wrong.'); + } + /** * testInitialize method * From e2aeae38258f4acf28e76e1d06f2c73c0dd0a992 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 20 Nov 2010 00:20:54 -0500 Subject: [PATCH 33/46] Adding _mergeVars() into Model. Refactoring how Model does its property merging. Eventually _mergeVars() could be moved into Object. --- cake/libs/model/model.php | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index bc07631e8..f4a67d954 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -438,27 +438,15 @@ class Model extends Object { } if (is_subclass_of($this, 'AppModel')) { - $appVars = get_class_vars('AppModel'); $merge = array('_findMethods'); - if ($this->actsAs !== null || $this->actsAs !== false) { $merge[] = 'actsAs'; } $parentClass = get_parent_class($this); - if (strtolower($parentClass) !== 'appmodel') { - $parentVars = get_class_vars($parentClass); - foreach ($merge as $var) { - if (isset($parentVars[$var]) && !empty($parentVars[$var])) { - $appVars[$var] = Set::merge($appVars[$var], $parentVars[$var]); - } - } - } - - foreach ($merge as $var) { - if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) { - $this->{$var} = Set::merge($appVars[$var], $this->{$var}); - } + if ($parentClass !== 'AppModel') { + $this->_mergeVars($merge, $parentClass); } + $this->_mergeVars($merge, 'AppModel'); } $this->Behaviors = new BehaviorCollection(); @@ -480,6 +468,27 @@ class Model extends Object { $this->Behaviors->init($this->alias, $this->actsAs); } +/** + * Merges this objects $property with the property in $class' definition. + * This classes value for the property will be merged on top of $class' + * + * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine + * this method as an empty function. + * + * @param array $properties The name of the properties to merge. + * @param sting $class The class to merge the property with. + * @return void + */ + protected function _mergeVars($properties, $class) { + $classProperties = get_class_vars($class); + foreach ($properties as $var) { + if (isset($classProperties[$var]) && !empty($classProperties[$var]) && is_array($this->{$var})) { + $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); + } + } + } + + /** * Handles custom method calls, like findBy for DB models, * and custom RPC calls for remote data sources. From 8f82156a51c1ab0366313952df3423f1361f71bf Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 20 Nov 2010 13:11:26 -0500 Subject: [PATCH 34/46] Adding _mergeVars to Controller (this duplicated method will be re-factored away). Updating tests in ControllerMergeVarsTest to use PHPUnit assertions. --- cake/libs/controller/controller.php | 86 ++++++++++--------- .../controller/controller_merge_vars.test.php | 8 +- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 5e37c8dfb..db0dda8a3 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -409,29 +409,52 @@ class Controller extends Object { } } +/** + * Merges this objects $property with the property in $class' definition. + * This classes value for the property will be merged on top of $class' + * + * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine + * this method as an empty function. + * + * @param array $properties The name of the properties to merge. + * @param sting $class The class to merge the property with. + * @return void + */ + protected function _mergeVars($properties, $class) { + $classProperties = get_class_vars($class); + foreach ($properties as $var) { + if ( + isset($classProperties[$var]) && + !empty($classProperties[$var]) && + is_array($this->{$var}) && + $this->{$var} != $classProperties[$var] + ) { + $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); + } + } + } + /** * Merge components, helpers, and uses vars from AppController and PluginAppController. * * @return void */ protected function __mergeVars() { - $pluginName = Inflector::camelize($this->plugin); - $pluginController = $pluginName . 'AppController'; + $pluginName = $pluginController = null; - if (is_subclass_of($this, 'AppController') || is_subclass_of($this, $pluginController)) { + if (!empty($this->plugin)) { + $pluginName = Inflector::camelize($this->plugin); + $pluginController = $pluginName . 'AppController'; + if (!is_subclass_of($this, $pluginController)) { + $pluginController = null; + } + $plugin = $pluginName . '.'; + } + + if (is_subclass_of($this, 'AppController') || !empty($pluginController)) { $appVars = get_class_vars('AppController'); $uses = $appVars['uses']; $merge = array('components', 'helpers'); - $plugin = null; - - if (!empty($this->plugin)) { - $plugin = $pluginName . '.'; - if (!is_subclass_of($this, $pluginController)) { - $pluginController = null; - } - } else { - $pluginController = null; - } if ($uses == $this->uses && !empty($this->uses)) { if (!in_array($plugin . $this->modelClass, $this->uses)) { @@ -445,20 +468,11 @@ class Controller extends Object { } elseif ($this->uses !== null || $this->uses !== false) { $merge[] = 'uses'; } - - foreach ($merge as $var) { - if (!empty($appVars[$var]) && is_array($this->{$var})) { - if ($var !== 'uses') { - $normal = Set::normalize($this->{$var}); - $app = Set::normalize($appVars[$var]); - if ($app !== $normal) { - $this->{$var} = Set::merge($app, $normal); - } - } else { - $this->{$var} = Set::merge( - array_diff($appVars[$var], $this->{$var}), $this->{$var} - ); - } + + $this->_mergeVars($merge, 'AppController'); + foreach ($merge as $prop) { + if ($prop !== 'components') { + $this->{$prop} = array_unique($this->{$prop}); } } } @@ -471,20 +485,10 @@ class Controller extends Object { if ($this->uses !== null || $this->uses !== false) { $merge[] = 'uses'; } - - foreach ($merge as $var) { - if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) { - if ($var !== 'uses') { - $normal = Set::normalize($this->{$var}); - $app = Set::normalize($appVars[$var]); - if ($app !== $normal) { - $this->{$var} = Set::merge($app, $normal); - } - } else { - $this->{$var} = Set::merge( - array_diff($appVars[$var], $this->{$var}), $this->{$var} - ); - } + $this->_mergeVars($merge, $pluginController); + foreach ($merge as $prop) { + if ($prop !== 'components') { + $this->{$prop} = array_unique($this->{$prop}); } } } diff --git a/cake/tests/cases/libs/controller/controller_merge_vars.test.php b/cake/tests/cases/libs/controller/controller_merge_vars.test.php index 3f16bd7cd..4784707d4 100644 --- a/cake/tests/cases/libs/controller/controller_merge_vars.test.php +++ b/cake/tests/cases/libs/controller/controller_merge_vars.test.php @@ -19,6 +19,8 @@ * @since CakePHP(tm) v 1.2.3 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::import('Core', 'Controller'); + if (!class_exists('AppController')) { /** @@ -220,13 +222,13 @@ class ControllerMergeVarsTest extends CakeTestCase { 'Auth' => array('setting' => 'val', 'otherVal'), 'Email' => array('ports' => 'open') ); - $this->assertEqual($Controller->components, $expected, 'Components are unexpected %s'); + $this->assertEquals($expected, $Controller->components, 'Components are unexpected.'); $expected = array( 'MergeVar' => array('format' => 'html', 'terse'), 'Javascript' => null ); - $this->assertEqual($Controller->helpers, $expected, 'Helpers are unexpected %s'); + $this->assertEquals($expected, $Controller->helpers, 'Helpers are unexpected.'); $Controller = new MergePostsController(); $Controller->components = array(); @@ -237,7 +239,7 @@ class ControllerMergeVarsTest extends CakeTestCase { 'MergeVar' => array('flag', 'otherFlag', 'redirect' => false), 'Auth' => array('setting' => 'val', 'otherVal'), ); - $this->assertEqual($Controller->components, $expected, 'Components are unexpected %s'); + $this->assertEqual($expected, $Controller->components, 'Components are unexpected.'); } /** From 8821bec049344593f4fd3c4b3240b4631eb3b7c5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 20 Nov 2010 13:20:09 -0500 Subject: [PATCH 35/46] Moving _mergeVars() into Object as its common to Controller, Model and Shell. --- cake/console/shells/shell.php | 20 ------------------- cake/libs/controller/controller.php | 31 +++-------------------------- cake/libs/model/model.php | 21 ------------------- cake/libs/object.php | 25 +++++++++++++++++++++++ 4 files changed, 28 insertions(+), 69 deletions(-) diff --git a/cake/console/shells/shell.php b/cake/console/shells/shell.php index 5b8e733d7..dd0e2079b 100644 --- a/cake/console/shells/shell.php +++ b/cake/console/shells/shell.php @@ -176,26 +176,6 @@ class Shell extends Object { } } -/** - * Merges this objects $property with the property in $class' definition. - * This classes value for the property will be merged on top of $class' - * - * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine - * this method as an empty function. - * - * @param array $properties The name of the properties to merge. - * @param sting $class The class to merge the property with. - * @return void - */ - protected function _mergeVars($properties, $class) { - $classProperties = get_class_vars($class); - foreach ($properties as $var) { - if (isset($classProperties[$var]) && !empty($classProperties[$var]) && is_array($this->{$var})) { - $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); - } - } - } - /** * Initializes the Shell * acts as constructor for subclasses diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index db0dda8a3..4f6d21098 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -409,38 +409,13 @@ class Controller extends Object { } } -/** - * Merges this objects $property with the property in $class' definition. - * This classes value for the property will be merged on top of $class' - * - * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine - * this method as an empty function. - * - * @param array $properties The name of the properties to merge. - * @param sting $class The class to merge the property with. - * @return void - */ - protected function _mergeVars($properties, $class) { - $classProperties = get_class_vars($class); - foreach ($properties as $var) { - if ( - isset($classProperties[$var]) && - !empty($classProperties[$var]) && - is_array($this->{$var}) && - $this->{$var} != $classProperties[$var] - ) { - $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); - } - } - } - /** * Merge components, helpers, and uses vars from AppController and PluginAppController. * * @return void */ protected function __mergeVars() { - $pluginName = $pluginController = null; + $pluginName = $pluginController = $plugin = null; if (!empty($this->plugin)) { $pluginName = Inflector::camelize($this->plugin); @@ -472,7 +447,7 @@ class Controller extends Object { $this->_mergeVars($merge, 'AppController'); foreach ($merge as $prop) { if ($prop !== 'components') { - $this->{$prop} = array_unique($this->{$prop}); + $this->{$prop} = array_unique((array)$this->{$prop}); } } } @@ -488,7 +463,7 @@ class Controller extends Object { $this->_mergeVars($merge, $pluginController); foreach ($merge as $prop) { if ($prop !== 'components') { - $this->{$prop} = array_unique($this->{$prop}); + $this->{$prop} = array_unique((array)$this->{$prop}); } } } diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index f4a67d954..962461f05 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -468,27 +468,6 @@ class Model extends Object { $this->Behaviors->init($this->alias, $this->actsAs); } -/** - * Merges this objects $property with the property in $class' definition. - * This classes value for the property will be merged on top of $class' - * - * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine - * this method as an empty function. - * - * @param array $properties The name of the properties to merge. - * @param sting $class The class to merge the property with. - * @return void - */ - protected function _mergeVars($properties, $class) { - $classProperties = get_class_vars($class); - foreach ($properties as $var) { - if (isset($classProperties[$var]) && !empty($classProperties[$var]) && is_array($this->{$var})) { - $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); - } - } - } - - /** * Handles custom method calls, like findBy for DB models, * and custom RPC calls for remote data sources. diff --git a/cake/libs/object.php b/cake/libs/object.php index 036917c1c..e103b853e 100644 --- a/cake/libs/object.php +++ b/cake/libs/object.php @@ -198,6 +198,31 @@ class Object { } } +/** + * Merges this objects $property with the property in $class' definition. + * This classes value for the property will be merged on top of $class' + * + * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine + * this method as an empty function. + * + * @param array $properties The name of the properties to merge. + * @param sting $class The class to merge the property with. + * @return void + */ + protected function _mergeVars($properties, $class) { + $classProperties = get_class_vars($class); + foreach ($properties as $var) { + if ( + isset($classProperties[$var]) && + !empty($classProperties[$var]) && + is_array($this->{$var}) && + $this->{$var} != $classProperties[$var] + ) { + $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); + } + } + } + /** * You should choose a unique name for the persistent file * From 8a129ec3a05086174248ba706a84db77db6c8adf Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 00:47:42 -0500 Subject: [PATCH 36/46] Adding a normalize parameter to Object::_mergeVars(). This allows existing behavior to be maintained. Updating Controller and Shell usage to match new parameters. --- cake/console/shells/shell.php | 10 ++++------ cake/libs/controller/controller.php | 19 +++---------------- cake/libs/object.php | 7 ++++++- .../tests/cases/console/shells/shell.test.php | 11 +++++++---- .../controller/controller_merge_vars.test.php | 4 ++-- 5 files changed, 22 insertions(+), 29 deletions(-) diff --git a/cake/console/shells/shell.php b/cake/console/shells/shell.php index dd0e2079b..11cb62d11 100644 --- a/cake/console/shells/shell.php +++ b/cake/console/shells/shell.php @@ -164,15 +164,13 @@ class Shell extends Object { if ($this->stdin == null) { $this->stdin = new ConsoleInput('php://stdin'); } - $merge = array(); + + $parent = get_parent_class($this); if ($this->tasks !== null && $this->tasks !== false) { - $merge[] = 'tasks'; + $this->_mergeVars(array('tasks'), $parent, true); } if ($this->uses !== null && $this->uses !== false) { - $merge[] = 'uses'; - } - if (!empty($merge)) { - $this->_mergeVars($merge, get_parent_class($this)); + $this->_mergeVars(array('uses'), $parent, false); } } diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 4f6d21098..d4341655b 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -441,31 +441,18 @@ class Controller extends Object { array_unshift($this->uses, $plugin . $this->modelClass); } } elseif ($this->uses !== null || $this->uses !== false) { - $merge[] = 'uses'; - } - - $this->_mergeVars($merge, 'AppController'); - foreach ($merge as $prop) { - if ($prop !== 'components') { - $this->{$prop} = array_unique((array)$this->{$prop}); - } + $this->_mergeVars(array('uses'), 'AppController', false); } + $this->_mergeVars($merge, 'AppController', true); } if ($pluginController && $pluginName != null) { - $appVars = get_class_vars($pluginController); - $uses = $appVars['uses']; $merge = array('components', 'helpers'); if ($this->uses !== null || $this->uses !== false) { - $merge[] = 'uses'; + $this->_mergeVars(array('uses'), $pluginController, false); } $this->_mergeVars($merge, $pluginController); - foreach ($merge as $prop) { - if ($prop !== 'components') { - $this->{$prop} = array_unique((array)$this->{$prop}); - } - } } } diff --git a/cake/libs/object.php b/cake/libs/object.php index e103b853e..0f1d49030 100644 --- a/cake/libs/object.php +++ b/cake/libs/object.php @@ -207,9 +207,10 @@ class Object { * * @param array $properties The name of the properties to merge. * @param sting $class The class to merge the property with. + * @param boolean $normalize Set to true to run the properties through Set::normalize() before merging. * @return void */ - protected function _mergeVars($properties, $class) { + protected function _mergeVars($properties, $class, $normalize = true) { $classProperties = get_class_vars($class); foreach ($properties as $var) { if ( @@ -218,6 +219,10 @@ class Object { is_array($this->{$var}) && $this->{$var} != $classProperties[$var] ) { + if ($normalize) { + $classProperties[$var] = Set::normalize($classProperties[$var]); + $this->{$var} = Set::normalize($this->{$var}); + } $this->{$var} = Set::merge($classProperties[$var], $this->{$var}); } } diff --git a/cake/tests/cases/console/shells/shell.test.php b/cake/tests/cases/console/shells/shell.test.php index b7bc7098a..ff341468b 100644 --- a/cake/tests/cases/console/shells/shell.test.php +++ b/cake/tests/cases/console/shells/shell.test.php @@ -70,8 +70,8 @@ class TestShell extends Shell { } - public function mergeVars($properties, $class) { - return $this->_mergeVars($properties, $class); + public function mergeVars($properties, $class, $normalize = true) { + return $this->_mergeVars($properties, $class, $normalize); } } @@ -156,9 +156,12 @@ class ShellTest extends CakeTestCase { function testMergeVars() { $this->Shell->tasks = array('DbConfig' => array('one', 'two')); $this->Shell->uses = array('Posts'); - $this->Shell->mergeVars(array('tasks', 'uses'), 'TestMergeShell'); + $this->Shell->mergeVars(array('tasks'), 'TestMergeShell'); + $this->Shell->mergeVars(array('uses'), 'TestMergeShell', false); + + $expected = array('DbConfig' => null, 'Fixture' => null, 'DbConfig' => array('one', 'two')); + $this->assertEquals($expected, $this->Shell->tasks); - $this->assertEquals(array('DbConfig', 'Fixture', 'DbConfig' => array('one', 'two')), $this->Shell->tasks); $expected = array('Fixture' => null, 'DbConfig' => array('one', 'two')); $this->assertEquals($expected, Set::normalize($this->Shell->tasks), 'Normalized results are wrong.'); $this->assertEquals(array('Comment', 'Posts'), $this->Shell->uses, 'Merged models are wrong.'); diff --git a/cake/tests/cases/libs/controller/controller_merge_vars.test.php b/cake/tests/cases/libs/controller/controller_merge_vars.test.php index 4784707d4..431caa8ff 100644 --- a/cake/tests/cases/libs/controller/controller_merge_vars.test.php +++ b/cake/tests/cases/libs/controller/controller_merge_vars.test.php @@ -201,7 +201,7 @@ class ControllerMergeVarsTest extends CakeTestCase { 'Custom' => null, 'Foo' => array('something') ); - $this->assertIdentical($Controller->helpers, $expected, 'Order is incorrect. %s'); + $this->assertSame($Controller->helpers, $expected, 'Order is incorrect.'); } /** @@ -239,7 +239,7 @@ class ControllerMergeVarsTest extends CakeTestCase { 'MergeVar' => array('flag', 'otherFlag', 'redirect' => false), 'Auth' => array('setting' => 'val', 'otherVal'), ); - $this->assertEqual($expected, $Controller->components, 'Components are unexpected.'); + $this->assertEquals($expected, $Controller->components, 'Components are unexpected.'); } /** From d373dde2ef61f965ebcaa8053531fc7827bd1e71 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 12:22:44 -0500 Subject: [PATCH 37/46] Fixing notice errors in bake all. Moving some message printing around. --- cake/console/shells/bake.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cake/console/shells/bake.php b/cake/console/shells/bake.php index dfd048194..ce75dec10 100644 --- a/cake/console/shells/bake.php +++ b/cake/console/shells/bake.php @@ -40,7 +40,14 @@ class BakeShell extends Shell { public $tasks = array('Project', 'DbConfig', 'Model', 'Controller', 'View', 'Plugin', 'Fixture', 'Test'); /** - * Override loadTasks() to handle paths + * The connection being used. + * + * @var string + */ + public $connection = 'default'; + +/** + * Assign $this->connection to the active task if a connection param is set. * */ public function startup() { @@ -121,7 +128,6 @@ class BakeShell extends Shell { * */ public function all() { - $this->hr(); $this->out('Bake All'); $this->hr(); @@ -157,6 +163,7 @@ class BakeShell extends Shell { if ($modelBaked && $modelExists === false) { $this->out(sprintf(__('%s Model was baked.'), $model)); + if ($this->_checkUnitTest()) { $this->Model->bakeFixture($model); $this->Model->bakeTest($model); @@ -166,8 +173,8 @@ class BakeShell extends Shell { if ($modelExists === true) { $controller = $this->_controllerName($name); + $this->out(sprintf(__('Baking %s Controller...', 1), $controller)); if ($this->Controller->bake($controller, $this->Controller->bakeActions($controller))) { - $this->out(sprintf(__('%s Controller was baked.'), $name)); if ($this->_checkUnitTest()) { $this->Controller->bakeTest($controller); } @@ -175,7 +182,7 @@ class BakeShell extends Shell { if (App::import('Controller', $controller)) { $this->View->args = array($controller); $this->View->execute(); - $this->out(sprintf(__('%s Views were baked.'), $name)); + $this->out(sprintf(__('%s Views were baked.'), $controller)); } $this->out(__('Bake All complete')); array_shift($this->args); From d7b1f706808c6defb9ac31d5744cb0e148252e5c Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 12:47:49 -0500 Subject: [PATCH 38/46] Adding some additional output to bake tasks to make them more consistent. Adding flags for Quiet output so the shells give minimal output. --- cake/console/shells/bake.php | 7 ++----- cake/console/shells/tasks/controller.php | 2 ++ cake/console/shells/tasks/fixture.php | 2 +- cake/console/shells/tasks/model.php | 2 +- cake/console/shells/tasks/test.php | 3 ++- cake/console/shells/tasks/view.php | 1 + cake/tests/cases/console/shells/tasks/controller.test.php | 4 ++-- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/cake/console/shells/bake.php b/cake/console/shells/bake.php index ce75dec10..77dd36201 100644 --- a/cake/console/shells/bake.php +++ b/cake/console/shells/bake.php @@ -162,8 +162,6 @@ class BakeShell extends Shell { $modelBaked = $this->Model->bake($object, false); if ($modelBaked && $modelExists === false) { - $this->out(sprintf(__('%s Model was baked.'), $model)); - if ($this->_checkUnitTest()) { $this->Model->bakeFixture($model); $this->Model->bakeTest($model); @@ -173,7 +171,6 @@ class BakeShell extends Shell { if ($modelExists === true) { $controller = $this->_controllerName($name); - $this->out(sprintf(__('Baking %s Controller...', 1), $controller)); if ($this->Controller->bake($controller, $this->Controller->bakeActions($controller))) { if ($this->_checkUnitTest()) { $this->Controller->bakeTest($controller); @@ -182,9 +179,9 @@ class BakeShell extends Shell { if (App::import('Controller', $controller)) { $this->View->args = array($controller); $this->View->execute(); - $this->out(sprintf(__('%s Views were baked.'), $controller)); } - $this->out(__('Bake All complete')); + $this->out('', 1, Shell::QUIET); + $this->out(__('Bake All complete'), 1, Shell::QUIET); array_shift($this->args); } else { $this->error(__('Bake All could not continue without a valid model')); diff --git a/cake/console/shells/tasks/controller.php b/cake/console/shells/tasks/controller.php index e88dc2059..f56f55d3b 100644 --- a/cake/console/shells/tasks/controller.php +++ b/cake/console/shells/tasks/controller.php @@ -302,6 +302,8 @@ class ControllerTask extends BakeTask { * @return string Baked controller */ public function bake($controllerName, $actions = '', $helpers = null, $components = null) { + $this->out("\nBaking controller class for $controllerName...", 1, Shell::QUIET); + $isScaffold = ($actions === 'scaffold') ? true : false; $this->Template->set('plugin', Inflector::camelize($this->plugin)); diff --git a/cake/console/shells/tasks/fixture.php b/cake/console/shells/tasks/fixture.php index 1313ab1dd..333359121 100644 --- a/cake/console/shells/tasks/fixture.php +++ b/cake/console/shells/tasks/fixture.php @@ -254,7 +254,7 @@ class FixtureTask extends BakeTask { $this->Template->set($vars); $content = $this->Template->generate('classes', 'fixture'); - $this->out("\nBaking test fixture for $model..."); + $this->out("\nBaking test fixture for $model...", 1, Shell::QUIET); $this->createFile($path . $filename, $content); return $content; } diff --git a/cake/console/shells/tasks/model.php b/cake/console/shells/tasks/model.php index 7e8de3e36..6abd25344 100644 --- a/cake/console/shells/tasks/model.php +++ b/cake/console/shells/tasks/model.php @@ -742,7 +742,7 @@ class ModelTask extends BakeTask { $path = $this->getPath(); $filename = $path . Inflector::underscore($name) . '.php'; - $this->out("\nBaking model class for $name..."); + $this->out("\nBaking model class for $name...", 1, Shell::QUIET); $this->createFile($filename, $out); ClassRegistry::flush(); return $out; diff --git a/cake/console/shells/tasks/test.php b/cake/console/shells/tasks/test.php index bb277bbcc..173a65079 100644 --- a/cake/console/shells/tasks/test.php +++ b/cake/console/shells/tasks/test.php @@ -115,7 +115,7 @@ class TestTask extends BakeTask { */ public function bake($type, $className) { if ($this->typeCanDetectFixtures($type) && $this->isLoadableClass($type, $className)) { - $this->out(__('Bake is detecting possible fixtures..')); + $this->out(__('Bake is detecting possible fixtures...')); $testSubject = $this->buildTestSubject($type, $className); $this->generateFixtureList($testSubject); } elseif ($this->interactive) { @@ -134,6 +134,7 @@ class TestTask extends BakeTask { if ($this->plugin) { $plugin = $this->plugin . '.'; } + $this->out("\nBaking test case for $className $type...", 1, Shell::QUIET); $this->Template->set('fixtures', $this->_fixtures); $this->Template->set('plugin', $plugin); diff --git a/cake/console/shells/tasks/view.php b/cake/console/shells/tasks/view.php index 2acbfdeaa..14d67b7fe 100644 --- a/cake/console/shells/tasks/view.php +++ b/cake/console/shells/tasks/view.php @@ -366,6 +366,7 @@ class ViewTask extends BakeTask { if (empty($content)) { return false; } + $this->out("\nBaking `$action` view file...", 1, Shell::QUIET); $path = $this->getPath(); $filename = $path . $this->controllerPath . DS . Inflector::underscore($action) . '.ctp'; return $this->createFile($filename, $content); diff --git a/cake/tests/cases/console/shells/tasks/controller.test.php b/cake/tests/cases/console/shells/tasks/controller.test.php index 61d00b4f1..f3601376e 100644 --- a/cake/tests/cases/console/shells/tasks/controller.test.php +++ b/cake/tests/cases/console/shells/tasks/controller.test.php @@ -304,11 +304,11 @@ class ControllerTaskTest extends CakeTestCase { $path = APP . 'plugins' . DS . 'controller_test' . DS . 'controllers' . DS . 'articles_controller.php'; - $this->Task->expects($this->at(0))->method('createFile')->with( + $this->Task->expects($this->at(1))->method('createFile')->with( $path, new PHPUnit_Framework_Constraint_IsAnything() ); - $this->Task->expects($this->at(1))->method('createFile')->with( + $this->Task->expects($this->at(3))->method('createFile')->with( $path, new PHPUnit_Framework_Constraint_PCREMatch('/ArticlesController extends ControllerTestAppController/') ); From a729d29cfd6da6b584dbe68c5f86166c44898110 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 13:39:18 -0500 Subject: [PATCH 39/46] Updating ModelTask test to have fewer skips and collisions with the rest of the testsuite. --- .../cases/console/shells/tasks/model.test.php | 224 +++++++++--------- 1 file changed, 108 insertions(+), 116 deletions(-) diff --git a/cake/tests/cases/console/shells/tasks/model.test.php b/cake/tests/cases/console/shells/tasks/model.test.php index b2072fdeb..ac2a2c7fc 100644 --- a/cake/tests/cases/console/shells/tasks/model.test.php +++ b/cake/tests/cases/console/shells/tasks/model.test.php @@ -42,7 +42,10 @@ class ModelTaskTest extends CakeTestCase { * @var array * @access public */ - public $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag', 'core.category_thread'); + public $fixtures = array( + 'core.bake_article', 'core.bake_comment', 'core.bake_articles_bake_tag', + 'core.bake_tag', 'core.category_thread' + ); /** * setUp method @@ -116,25 +119,25 @@ class ModelTaskTest extends CakeTestCase { } $this->_useMockedOut(); - $this->Task->expects($this->at(1))->method('out')->with('1. Article'); - $this->Task->expects($this->at(2))->method('out')->with('2. ArticlesTag'); - $this->Task->expects($this->at(3))->method('out')->with('3. CategoryThread'); - $this->Task->expects($this->at(4))->method('out')->with('4. Comment'); - $this->Task->expects($this->at(5))->method('out')->with('5. Tag'); + $this->Task->expects($this->at(1))->method('out')->with('1. BakeArticle'); + $this->Task->expects($this->at(2))->method('out')->with('2. BakeArticlesBakeTag'); + $this->Task->expects($this->at(3))->method('out')->with('3. BakeComment'); + $this->Task->expects($this->at(4))->method('out')->with('4. BakeTag'); + $this->Task->expects($this->at(5))->method('out')->with('5. CategoryThread'); - $this->Task->expects($this->at(7))->method('out')->with('1. Article'); - $this->Task->expects($this->at(8))->method('out')->with('2. ArticlesTag'); - $this->Task->expects($this->at(9))->method('out')->with('3. CategoryThread'); - $this->Task->expects($this->at(10))->method('out')->with('4. Comment'); - $this->Task->expects($this->at(11))->method('out')->with('5. Tag'); + $this->Task->expects($this->at(7))->method('out')->with('1. BakeArticle'); + $this->Task->expects($this->at(8))->method('out')->with('2. BakeArticlesBakeTag'); + $this->Task->expects($this->at(9))->method('out')->with('3. BakeComment'); + $this->Task->expects($this->at(10))->method('out')->with('4. BakeTag'); + $this->Task->expects($this->at(11))->method('out')->with('5. CategoryThread'); $result = $this->Task->listAll('test'); - $expected = array('articles', 'articles_tags', 'category_threads', 'comments', 'tags'); + $expected = array('bake_articles', 'bake_articles_bake_tags', 'bake_comments', 'bake_tags', 'category_threads'); $this->assertEqual($result, $expected); $this->Task->connection = 'test'; $result = $this->Task->listAll(); - $expected = array('articles', 'articles_tags', 'category_threads', 'comments', 'tags'); + $expected = array('bake_articles', 'bake_articles_bake_tags', 'bake_comments', 'bake_tags', 'category_threads'); $this->assertEqual($result, $expected); } @@ -155,20 +158,14 @@ class ModelTaskTest extends CakeTestCase { * @return void */ function testGetNameValidOption() { - $count = count($this->Task->listAll('test')); - if ($count != count($this->fixtures)) { - $this->markTestSkipped('Additional tables detected.'); - } - + $listing = $this->Task->listAll('test'); $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls(1, 4)); $result = $this->Task->getName('test'); - $expected = 'Article'; - $this->assertEqual($result, $expected); + $this->assertEquals(Inflector::classify($listing[0]), $result); $result = $this->Task->getName('test'); - $expected = 'Comment'; - $this->assertEqual($result, $expected); + $this->assertEquals(Inflector::classify($listing[3]), $result); } /** @@ -190,8 +187,8 @@ class ModelTaskTest extends CakeTestCase { */ public function testGetTableName() { $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y')); - $result = $this->Task->getTable('Article', 'test'); - $expected = 'articles'; + $result = $this->Task->getTable('BakeArticle', 'test'); + $expected = 'bake_articles'; $this->assertEqual($result, $expected); } @@ -202,7 +199,7 @@ class ModelTaskTest extends CakeTestCase { */ function testGetTableNameCustom() { $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls('n', 'my_table')); - $result = $this->Task->getTable('Article', 'test'); + $result = $this->Task->getTable('BakeArticle', 'test'); $expected = 'my_table'; $this->assertEqual($result, $expected); } @@ -419,19 +416,19 @@ class ModelTaskTest extends CakeTestCase { * @return void */ public function testBelongsToGeneration() { - $model = new Model(array('ds' => 'test', 'name' => 'Comment')); + $model = new Model(array('ds' => 'test', 'name' => 'BakeComment')); $result = $this->Task->findBelongsTo($model, array()); $expected = array( 'belongsTo' => array( array( - 'alias' => 'Article', - 'className' => 'Article', - 'foreignKey' => 'article_id', + 'alias' => 'BakeArticle', + 'className' => 'BakeArticle', + 'foreignKey' => 'bake_article_id', ), array( - 'alias' => 'User', - 'className' => 'User', - 'foreignKey' => 'user_id', + 'alias' => 'BakeUser', + 'className' => 'BakeUser', + 'foreignKey' => 'bake_user_id', ), ) ); @@ -457,23 +454,23 @@ class ModelTaskTest extends CakeTestCase { * @return void */ public function testHasManyHasOneGeneration() { - $model = new Model(array('ds' => 'test', 'name' => 'Article')); + $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle')); $this->Task->connection = 'test'; $this->Task->listAll(); $result = $this->Task->findHasOneAndMany($model, array()); $expected = array( 'hasMany' => array( array( - 'alias' => 'Comment', - 'className' => 'Comment', - 'foreignKey' => 'article_id', + 'alias' => 'BakeComment', + 'className' => 'BakeComment', + 'foreignKey' => 'bake_article_id', ), ), 'hasOne' => array( array( - 'alias' => 'Comment', - 'className' => 'Comment', - 'foreignKey' => 'article_id', + 'alias' => 'BakeComment', + 'className' => 'BakeComment', + 'foreignKey' => 'bake_article_id', ), ), ); @@ -506,23 +503,18 @@ class ModelTaskTest extends CakeTestCase { * @return void */ public function testHasAndBelongsToManyGeneration() { - $count = count($this->Task->listAll('test')); - if ($count != count($this->fixtures)) { - $this->markTestSkipped('Additional tables detected.'); - } - - $model = new Model(array('ds' => 'test', 'name' => 'Article')); + $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle')); $this->Task->connection = 'test'; $this->Task->listAll(); $result = $this->Task->findHasAndBelongsToMany($model, array()); $expected = array( 'hasAndBelongsToMany' => array( array( - 'alias' => 'Tag', - 'className' => 'Tag', - 'foreignKey' => 'article_id', - 'joinTable' => 'articles_tags', - 'associationForeignKey' => 'tag_id', + 'alias' => 'BakeTag', + 'className' => 'BakeTag', + 'foreignKey' => 'bake_article_id', + 'joinTable' => 'bake_articles_bake_tags', + 'associationForeignKey' => 'bake_tag_id', ), ), ); @@ -537,23 +529,23 @@ class ModelTaskTest extends CakeTestCase { public function testDoAssociationsNonInteractive() { $this->Task->connection = 'test'; $this->Task->interactive = false; - $model = new Model(array('ds' => 'test', 'name' => 'Article')); + $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle')); $result = $this->Task->doAssociations($model); $expected = array( 'hasMany' => array( array( - 'alias' => 'Comment', - 'className' => 'Comment', - 'foreignKey' => 'article_id', + 'alias' => 'BakeComment', + 'className' => 'BakeComment', + 'foreignKey' => 'bake_article_id', ), ), 'hasAndBelongsToMany' => array( array( - 'alias' => 'Tag', - 'className' => 'Tag', - 'foreignKey' => 'article_id', - 'joinTable' => 'articles_tags', - 'associationForeignKey' => 'tag_id', + 'alias' => 'BakeTag', + 'className' => 'BakeTag', + 'foreignKey' => 'bake_article_id', + 'joinTable' => 'bake_articles_bake_tags', + 'associationForeignKey' => 'bake_tag_id', ), ), ); @@ -567,8 +559,8 @@ class ModelTaskTest extends CakeTestCase { public function testBakeFixture() { $this->Task->plugin = 'test_plugin'; $this->Task->interactive = true; - $this->Task->Fixture->expects($this->at(0))->method('bake')->with('Article', 'articles'); - $this->Task->bakeFixture('Article', 'articles'); + $this->Task->Fixture->expects($this->at(0))->method('bake')->with('BakeArticle', 'bake_articles'); + $this->Task->bakeFixture('BakeArticle', 'bake_articles'); $this->assertEqual($this->Task->plugin, $this->Task->Fixture->plugin); $this->assertEqual($this->Task->connection, $this->Task->Fixture->connection); @@ -583,8 +575,8 @@ class ModelTaskTest extends CakeTestCase { public function testBakeTest() { $this->Task->plugin = 'test_plugin'; $this->Task->interactive = true; - $this->Task->Test->expects($this->at(0))->method('bake')->with('Model', 'Article'); - $this->Task->bakeTest('Article'); + $this->Task->Test->expects($this->at(0))->method('bake')->with('Model', 'BakeArticle'); + $this->Task->bakeTest('BakeArticle'); $this->assertEqual($this->Task->plugin, $this->Task->Test->plugin); $this->assertEqual($this->Task->connection, $this->Task->Test->connection); @@ -676,9 +668,9 @@ class ModelTaskTest extends CakeTestCase { 'time' => 'time' ) ); - $result = $this->Task->bake('Article', compact('validate')); - $this->assertPattern('/class Article extends AppModel \{/', $result); - $this->assertPattern('/\$name \= \'Article\'/', $result); + $result = $this->Task->bake('BakeArticle', compact('validate')); + $this->assertPattern('/class BakeArticle extends AppModel \{/', $result); + $this->assertPattern('/\$name \= \'BakeArticle\'/', $result); $this->assertPattern('/\$validate \= array\(/', $result); $expected = <<< STRINGEND array( @@ -708,9 +700,9 @@ STRINGEND; 'foreignKey' => 'something_else_id', ), array( - 'alias' => 'User', - 'className' => 'User', - 'foreignKey' => 'user_id', + 'alias' => 'BakeUser', + 'className' => 'BakeUser', + 'foreignKey' => 'bake_user_id', ), ), 'hasOne' => array( @@ -722,30 +714,30 @@ STRINGEND; ), 'hasMany' => array( array( - 'alias' => 'Comment', - 'className' => 'Comment', + 'alias' => 'BakeComment', + 'className' => 'BakeComment', 'foreignKey' => 'parent_id', ), ), 'hasAndBelongsToMany' => array( array( - 'alias' => 'Tag', - 'className' => 'Tag', - 'foreignKey' => 'article_id', - 'joinTable' => 'articles_tags', - 'associationForeignKey' => 'tag_id', + 'alias' => 'BakeTag', + 'className' => 'BakeTag', + 'foreignKey' => 'bake_article_id', + 'joinTable' => 'bake_articles_bake_tags', + 'associationForeignKey' => 'bake_tag_id', ), ) ); - $result = $this->Task->bake('Article', compact('associations')); + $result = $this->Task->bake('BakeArticle', compact('associations')); $this->assertPattern('/\$hasAndBelongsToMany \= array\(/', $result); $this->assertPattern('/\$hasMany \= array\(/', $result); $this->assertPattern('/\$belongsTo \= array\(/', $result); $this->assertPattern('/\$hasOne \= array\(/', $result); - $this->assertPattern('/Tag/', $result); + $this->assertPattern('/BakeTag/', $result); $this->assertPattern('/OtherModel/', $result); $this->assertPattern('/SomethingElse/', $result); - $this->assertPattern('/Comment/', $result); + $this->assertPattern('/BakeComment/', $result); } /** @@ -756,11 +748,11 @@ STRINGEND; public function testBakeWithPlugin() { $this->Task->plugin = 'controllerTest'; - $path = APP . 'plugins' . DS . 'controller_test' . DS . 'models' . DS . 'article.php'; + $path = APP . 'plugins' . DS . 'controller_test' . DS . 'models' . DS . 'bake_article.php'; $this->Task->expects($this->once())->method('createFile') - ->with($path, new PHPUnit_Framework_Constraint_PCREMatch('/Article extends ControllerTestAppModel/')); + ->with($path, new PHPUnit_Framework_Constraint_PCREMatch('/BakeArticle extends ControllerTestAppModel/')); - $this->Task->bake('Article', array(), array()); + $this->Task->bake('BakeArticle', array(), array()); $this->assertEqual(count(ClassRegistry::keys()), 0); $this->assertEqual(count(ClassRegistry::mapKeys()), 0); @@ -774,12 +766,12 @@ STRINGEND; public function testExecuteWithNamedModel() { $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; - $this->Task->args = array('article'); - $filename = '/my/path/article.php'; + $this->Task->args = array('bake_article'); + $filename = '/my/path/bake_article.php'; $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1)); $this->Task->expects($this->once())->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Article extends AppModel/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeArticle extends AppModel/')); $this->Task->execute(); @@ -794,7 +786,7 @@ STRINGEND; */ static function nameVariations() { return array( - array('Articles'), array('Article'), array('article'), array('articles') + array('BakeArticles'), array('BakeArticle'), array('bake_article'), array('bake_articles') ); } @@ -810,10 +802,10 @@ STRINGEND; $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1)); $this->Task->args = array($name); - $filename = '/my/path/article.php'; + $filename = '/my/path/bake_article.php'; $this->Task->expects($this->at(0))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Article extends AppModel/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeArticle extends AppModel/')); $this->Task->execute(); } @@ -825,12 +817,12 @@ STRINGEND; public function testExecuteWithNamedModelHasManyCreated() { $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; - $this->Task->args = array('article'); - $filename = '/my/path/article.php'; + $this->Task->args = array('bake_article'); + $filename = '/my/path/bake_article.php'; $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1)); $this->Task->expects($this->at(0))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch("/'Comment' \=\> array\(/")); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch("/'BakeComment' \=\> array\(/")); $this->Task->execute(); } @@ -854,26 +846,26 @@ STRINGEND; $this->Task->Fixture->expects($this->exactly(5))->method('bake'); $this->Task->Test->expects($this->exactly(5))->method('bake'); - $filename = '/my/path/article.php'; + $filename = '/my/path/bake_article.php'; $this->Task->expects($this->at(1))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Article/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeArticle/')); - $filename = '/my/path/articles_tag.php'; + $filename = '/my/path/bake_articles_bake_tag.php'; $this->Task->expects($this->at(2))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class ArticlesTag/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeArticlesBakeTag/')); - $filename = '/my/path/category_thread.php'; + $filename = '/my/path/bake_comment.php'; $this->Task->expects($this->at(3))->method('createFile') + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeComment/')); + + $filename = '/my/path/bake_tag.php'; + $this->Task->expects($this->at(4)) + ->method('createFile')->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeTag/')); + + $filename = '/my/path/category_thread.php'; + $this->Task->expects($this->at(5))->method('createFile') ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class CategoryThread/')); - $filename = '/my/path/comment.php'; - $this->Task->expects($this->at(4))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Comment/')); - - $filename = '/my/path/tag.php'; - $this->Task->expects($this->at(5)) - ->method('createFile')->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Tag/')); - $this->Task->execute(); $this->assertEqual(count(ClassRegistry::keys()), 0); @@ -895,26 +887,26 @@ STRINGEND; $this->Task->path = '/my/path/'; $this->Task->args = array('all'); $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true)); - $this->Task->skipTables = array('tags'); + $this->Task->skipTables = array('bake_tags'); $this->Task->Fixture->expects($this->exactly(4))->method('bake'); $this->Task->Test->expects($this->exactly(4))->method('bake'); - $filename = '/my/path/article.php'; + $filename = '/my/path/bake_article.php'; $this->Task->expects($this->at(1))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Article/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeArticle/')); - $filename = '/my/path/articles_tag.php'; + $filename = '/my/path/bake_articles_bake_tag.php'; $this->Task->expects($this->at(2))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class ArticlesTag/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeArticlesBakeTag/')); + + $filename = '/my/path/bake_comment.php'; + $this->Task->expects($this->at(3))->method('createFile') + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeComment/')); $filename = '/my/path/category_thread.php'; - $this->Task->expects($this->at(3))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class CategoryThread/')); - - $filename = '/my/path/comment.php'; $this->Task->expects($this->at(4))->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Comment/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class CategoryThread/')); $this->Task->execute(); } @@ -950,10 +942,10 @@ STRINGEND; $this->Task->Test->expects($this->once())->method('bake'); $this->Task->Fixture->expects($this->once())->method('bake'); - $filename = '/my/path/article.php'; + $filename = '/my/path/bake_article.php'; $this->Task->expects($this->once())->method('createFile') - ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class Article/')); + ->with($filename, new PHPUnit_Framework_Constraint_PCREMatch('/class BakeArticle/')); $this->Task->execute(); From cb657b158b0e0c5a59132664ba01aeac0abcc36c Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 14:39:07 -0500 Subject: [PATCH 40/46] Fixing failing test and adding skip for test that will fail in a non-isolated case. --- cake/tests/cases/console/shells/testsuite.test.php | 3 ++- .../tests/cases/libs/controller/controller_merge_vars.test.php | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cake/tests/cases/console/shells/testsuite.test.php b/cake/tests/cases/console/shells/testsuite.test.php index b132aa557..bfe463dbf 100644 --- a/cake/tests/cases/console/shells/testsuite.test.php +++ b/cake/tests/cases/console/shells/testsuite.test.php @@ -41,6 +41,7 @@ class TestSuiteShellTest extends CakeTestCase { array('in', 'out', 'hr', 'help', 'error', 'err', '_stop', 'initialize', 'run', 'clear'), array($out, $out, $in) ); + $this->Shell->OptionParser = $this->getMock('ConsoleOptionParser', array(), array(null, false)); } /** @@ -61,7 +62,7 @@ class TestSuiteShellTest extends CakeTestCase { $this->Shell->startup(); $this->Shell->args = array('unexistant-category'); $this->Shell->expects($this->at(0))->method('out')->with(__("No test cases available \n\n")); - $this->Shell->expects($this->once())->method('help'); + $this->Shell->OptionParser->expects($this->once())->method('help'); $this->Shell->available(); } diff --git a/cake/tests/cases/libs/controller/controller_merge_vars.test.php b/cake/tests/cases/libs/controller/controller_merge_vars.test.php index 431caa8ff..a3199b3a2 100644 --- a/cake/tests/cases/libs/controller/controller_merge_vars.test.php +++ b/cake/tests/cases/libs/controller/controller_merge_vars.test.php @@ -192,6 +192,8 @@ class ControllerMergeVarsTest extends CakeTestCase { * @return void */ function testHelperOrderPrecedence() { + $this->skipIf(defined('APP_CONTROLLER_EXISTS'), "APP_CONTROLLER_EXISTS cannot run {$this->name}"); + $Controller =& new MergeVariablesController(); $Controller->helpers = array('Custom', 'Foo' => array('something')); $Controller->constructClasses(); From 8aabf3689ee8136e23fdb3df2d96481f2d7d63d8 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 14:42:13 -0500 Subject: [PATCH 41/46] Making BehaviorCollection more consistent with other object collections. Fixing failing tests caused by not being updated when behavior changed. --- cake/libs/model/behavior_collection.php | 4 ++-- cake/tests/cases/libs/model/model_integration.test.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cake/libs/model/behavior_collection.php b/cake/libs/model/behavior_collection.php index 9820d568b..3ce783c76 100644 --- a/cake/libs/model/behavior_collection.php +++ b/cake/libs/model/behavior_collection.php @@ -64,8 +64,8 @@ class BehaviorCollection extends ObjectCollection { $this->modelName = $modelName; if (!empty($behaviors)) { - foreach (Set::normalize($behaviors) as $behavior => $config) { - $this->load($behavior, $config); + foreach (BehaviorCollection::normalizeObjectArray($behaviors) as $behavior => $config) { + $this->load($config['class'], $config['settings']); } } } diff --git a/cake/tests/cases/libs/model/model_integration.test.php b/cake/tests/cases/libs/model/model_integration.test.php index 5790ec344..b3d78af1a 100644 --- a/cake/tests/cases/libs/model/model_integration.test.php +++ b/cake/tests/cases/libs/model/model_integration.test.php @@ -1309,12 +1309,12 @@ class ModelIntegrationTest extends BaseModelTest { $this->loadFixtures('Post'); $TestModel = ClassRegistry::init('MergeVarPluginPost'); - $this->assertEqual($TestModel->actsAs, array('Containable', 'Tree')); + $this->assertEqual($TestModel->actsAs, array('Containable' => null, 'Tree' => null)); $this->assertTrue(isset($TestModel->Behaviors->Containable)); $this->assertTrue(isset($TestModel->Behaviors->Tree)); $TestModel = ClassRegistry::init('MergeVarPluginComment'); - $expected = array('Containable', 'Containable' => array('some_settings')); + $expected = array('Containable' => array('some_settings')); $this->assertEqual($TestModel->actsAs, $expected); $this->assertTrue(isset($TestModel->Behaviors->Containable)); } From 8e1f7cc7b931b9514f693f92ac6e7f8920b8520b Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 15:12:44 -0500 Subject: [PATCH 42/46] Removing extra line. --- cake/libs/app.php | 1 - 1 file changed, 1 deletion(-) diff --git a/cake/libs/app.php b/cake/libs/app.php index 90db2b770..11b0ff07c 100644 --- a/cake/libs/app.php +++ b/cake/libs/app.php @@ -513,7 +513,6 @@ class App { if ($name != null && !class_exists($name . $ext['class'])) { if ($load = self::__mapped($name . $ext['class'], $type, $plugin)) { if (self::__load($load)) { - if (self::$return) { return include($load); } From 4c0e69b8fccb9f6dbafa343defe839d85d7da2e0 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 15:13:33 -0500 Subject: [PATCH 43/46] Removing constant checks, they aren't used anymore. --- .../cases/libs/model/datasources/dbo/dbo_mssql.test.php | 4 +--- .../cases/libs/model/datasources/dbo/dbo_mysqli.test.php | 4 +--- .../cases/libs/model/datasources/dbo/dbo_oracle.test.php | 4 +--- .../tests/cases/libs/model/datasources/dbo_source.test.php | 4 +--- cake/tests/cases/libs/model/models.php | 3 --- cake/tests/cases/libs/view/media.test.php | 7 ------- 6 files changed, 4 insertions(+), 22 deletions(-) diff --git a/cake/tests/cases/libs/model/datasources/dbo/dbo_mssql.test.php b/cake/tests/cases/libs/model/datasources/dbo/dbo_mssql.test.php index 545aff38f..8ea86d221 100644 --- a/cake/tests/cases/libs/model/datasources/dbo/dbo_mssql.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo/dbo_mssql.test.php @@ -17,9 +17,7 @@ * @since CakePHP(tm) v 1.2.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) { - define('CAKEPHP_UNIT_TEST_EXECUTION', 1); -} + require_once LIBS.'model'.DS.'model.php'; require_once LIBS.'model'.DS.'datasources'.DS.'datasource.php'; require_once LIBS.'model'.DS.'datasources'.DS.'dbo_source.php'; diff --git a/cake/tests/cases/libs/model/datasources/dbo/dbo_mysqli.test.php b/cake/tests/cases/libs/model/datasources/dbo/dbo_mysqli.test.php index 82591a8b1..4ab881478 100644 --- a/cake/tests/cases/libs/model/datasources/dbo/dbo_mysqli.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo/dbo_mysqli.test.php @@ -17,9 +17,7 @@ * @since CakePHP(tm) v 1.2.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) { - define('CAKEPHP_UNIT_TEST_EXECUTION', 1); -} + App::import('Core', array('Model', 'DataSource', 'DboSource', 'DboMysqli')); /** diff --git a/cake/tests/cases/libs/model/datasources/dbo/dbo_oracle.test.php b/cake/tests/cases/libs/model/datasources/dbo/dbo_oracle.test.php index 5a36e3899..3efa451bd 100644 --- a/cake/tests/cases/libs/model/datasources/dbo/dbo_oracle.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo/dbo_oracle.test.php @@ -17,9 +17,7 @@ * @since CakePHP(tm) v 1.2.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) { - define('CAKEPHP_UNIT_TEST_EXECUTION', 1); -} + require_once LIBS . 'model' . DS . 'datasources' . DS . 'dbo_source.php'; require_once LIBS . 'model' . DS . 'datasources' . DS . 'dbo' . DS . 'dbo_oracle.php'; diff --git a/cake/tests/cases/libs/model/datasources/dbo_source.test.php b/cake/tests/cases/libs/model/datasources/dbo_source.test.php index df2baad64..fc09e5d55 100644 --- a/cake/tests/cases/libs/model/datasources/dbo_source.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo_source.test.php @@ -17,9 +17,7 @@ * @since CakePHP(tm) v 1.2.0.4206 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) { - define('CAKEPHP_UNIT_TEST_EXECUTION', 1); -} + App::import('Model', array('Model', 'DataSource', 'DboSource', 'DboMysql', 'App')); require_once dirname(dirname(__FILE__)) . DS . 'models.php'; diff --git a/cake/tests/cases/libs/model/models.php b/cake/tests/cases/libs/model/models.php index 5daa08506..b92543e49 100644 --- a/cake/tests/cases/libs/model/models.php +++ b/cake/tests/cases/libs/model/models.php @@ -19,9 +19,6 @@ * @since CakePHP(tm) v 1.2.0.6464 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) { - define('CAKEPHP_UNIT_TEST_EXECUTION', 1); -} PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT'); diff --git a/cake/tests/cases/libs/view/media.test.php b/cake/tests/cases/libs/view/media.test.php index b08c54e23..39b9d190d 100644 --- a/cake/tests/cases/libs/view/media.test.php +++ b/cake/tests/cases/libs/view/media.test.php @@ -19,13 +19,6 @@ */ App::import('Core', array('Media', 'Controller', 'CakeResponse')); -if (!class_exists('ErrorHandler')) { - App::import('Core', array('Error')); -} -if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) { - define('CAKEPHP_UNIT_TEST_EXECUTION', 1); -} - /** * MediaViewTest class * From fdcfd03340d851fcfca6c05c6a2dbdd76abef3a1 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 22:59:49 -0500 Subject: [PATCH 44/46] Fixing typo that prevented html coverage reports from being generated. --- cake/console/shells/testsuite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/console/shells/testsuite.php b/cake/console/shells/testsuite.php index a4e5822b8..67f2743d5 100644 --- a/cake/console/shells/testsuite.php +++ b/cake/console/shells/testsuite.php @@ -56,7 +56,7 @@ class TestSuiteShell extends Shell { ))->addOption('log-dbus', array( 'help' => __('Log test execution to DBUS.'), 'default' => false - ))->addOption('--coverage-html', array( + ))->addOption('coverage-html', array( 'help' => __(' Generate code coverage report in HTML format.'), 'default' => false ))->addOption('coverage-clover', array( From 2d21e9c331fdd04a7cd6558ce4eecefb0a8c2f74 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 23:01:26 -0500 Subject: [PATCH 45/46] Removing cache hits, as App::core() is almost always called before Cache is initialized, as Cache uses App::core to load the first configured engine. This Cache::read call can never succeed so it should be removed. --- cake/libs/app.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cake/libs/app.php b/cake/libs/app.php index 11b0ff07c..2f765047c 100644 --- a/cake/libs/app.php +++ b/cake/libs/app.php @@ -324,9 +324,6 @@ class App { */ public static function core($type = null) { static $paths = false; - if ($paths === false) { - $paths = Cache::read('core_paths', '_cake_core_'); - } if (!$paths) { $paths = array(); $libs = dirname(__FILE__) . DS; @@ -347,8 +344,6 @@ class App { $paths['shells'][] = $cake . 'console' . DS . 'shells' . DS; // Provide BC path to vendors/shells $paths['shells'][] = $path . 'vendors' . DS . 'shells' . DS; - - Cache::write('core_paths', array_filter($paths), '_cake_core_'); } if ($type && isset($paths[$type])) { return $paths[$type]; From 7013a8f1e0877b178498755d7fbfb1f4d02885b0 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 22 Nov 2010 21:07:21 -0500 Subject: [PATCH 46/46] Fixing typo. Should be AppShell, not AppModel. --- cake/libs/app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/libs/app.php b/cake/libs/app.php index 2f765047c..2812219c1 100644 --- a/cake/libs/app.php +++ b/cake/libs/app.php @@ -777,7 +777,7 @@ class App { if (!class_exists('Shell')) { App::import($type, 'Shell', false); } - if (!class_exists('AppModel')) { + if (!class_exists('AppShell')) { App::import($type, 'AppShell', false); } if ($plugin) {