From e6aeae8935b4fc7b98b83c12601ba5bfd57ebb6a Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 31 Oct 2010 22:41:33 -0400 Subject: [PATCH 001/160] 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 002/160] 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 003/160] 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 004/160] =?UTF-8?q?Changing=20NumberHelper::currency()=20t?= =?UTF-8?q?o=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 005/160] 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 006/160] 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 007/160] 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 008/160] 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 1424e02488e8fffabdbf6787a3793b8d95c4c3ac Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 7 Nov 2010 01:35:36 -0400 Subject: [PATCH 009/160] Adding a method to CakeRequest to parse out the accept-language header. This will help remove features from l10n. --- cake/libs/cake_request.php | 22 ++++++++++++++++++++- cake/tests/cases/libs/cake_request.test.php | 21 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/cake/libs/cake_request.php b/cake/libs/cake_request.php index 24870a3cd..52c44fd99 100644 --- a/cake/libs/cake_request.php +++ b/cake/libs/cake_request.php @@ -550,7 +550,7 @@ class CakeRequest implements ArrayAccess { * @param string $name Name of the header you want. * @return mixed Either false on no header being set or the value of the header. */ - public function header($name) { + public static function header($name) { $name = 'HTTP_' . strtoupper(str_replace('-', '_', $name)); if (!empty($_SERVER[$name])) { return $_SERVER[$name]; @@ -629,6 +629,26 @@ class CakeRequest implements ArrayAccess { return in_array($type, $acceptTypes); } +/** + * Get the lanaguages accepted by the client, or check if a specific language is accepted. + * + * @param string $language The language to test. + * @return If a $language is provided, a boolean. Otherwise the array of accepted languages. + */ + public static function acceptLanguage($language = null) { + $accepts = preg_split('/[;,]/', self::header('Accept-Language')); + foreach ($accepts as &$accept) { + $accept = strtolower($accept); + if (strpos($accept, '_') !== false) { + $accept = str_replace('_', '-', $accept); + } + } + if ($language === null) { + return $accepts; + } + return in_array($language, $accepts); + } + /** * Provides a read/write accessor for `$this->data`. Allows you * to use a syntax similar to `CakeSession` for reading post data. diff --git a/cake/tests/cases/libs/cake_request.test.php b/cake/tests/cases/libs/cake_request.test.php index f452631c1..010a9cff0 100644 --- a/cake/tests/cases/libs/cake_request.test.php +++ b/cake/tests/cases/libs/cake_request.test.php @@ -1338,6 +1338,27 @@ class CakeRequestTestCase extends CakeTestCase { $this->assertSame('', $request->data['Post']['empty']); } +/** + * test accept language + * + * @return void + */ + function testAcceptLanguage() { + $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'inexistent,en-ca'; + $result = CakeRequest::acceptLanguage(); + $this->assertEquals(array('inexistent', 'en-ca'), $result, 'Languages do not match'); + + $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'es_mx;en_ca'; + $result = CakeRequest::acceptLanguage(); + $this->assertEquals(array('es-mx', 'en-ca'), $result, 'Languages do not match'); + + $result = CakeRequest::acceptLanguage('en-ca'); + $this->assertTrue($result); + + $result = CakeRequest::acceptLanguage('en-us'); + $this->assertFalse($result); + } + /** * backupEnvironment method * From 22bb07abb0bda06d33d0ab9588eaa40aff937f58 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 7 Nov 2010 01:36:37 -0400 Subject: [PATCH 010/160] Adding visibility to a few methods. --- cake/libs/cake_request.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/libs/cake_request.php b/cake/libs/cake_request.php index 52c44fd99..7a464f742 100644 --- a/cake/libs/cake_request.php +++ b/cake/libs/cake_request.php @@ -582,7 +582,7 @@ class CakeRequest implements ArrayAccess { * @param int $tldLength Number of segments your tld contains * @return string Domain name without subdomains. */ - function domain($tldLength = 1) { + public function domain($tldLength = 1) { $segments = explode('.', $this->host()); $domain = array_slice($segments, -1 * ($tldLength + 1)); return implode('.', $domain); @@ -594,7 +594,7 @@ class CakeRequest implements ArrayAccess { * @param int $tldLength Number of segments your tld contains. * @return array of subdomains. */ - function subdomains($tldLength = 1) { + public function subdomains($tldLength = 1) { $segments = explode('.', $this->host()); return array_slice($segments, 0, -1 * ($tldLength + 1)); } From 09d3a0626a77e8ca1a71eee870c430ffc2be79ce Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 7 Nov 2010 01:38:25 -0400 Subject: [PATCH 011/160] Updating l10n to use the new CakeRequest method. --- cake/libs/l10n.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cake/libs/l10n.php b/cake/libs/l10n.php index 816bf212c..4f5868412 100644 --- a/cake/libs/l10n.php +++ b/cake/libs/l10n.php @@ -17,6 +17,7 @@ * @since CakePHP(tm) v 1.2.0.4116 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::import('Core', 'CakeRequest'); /** * Localization @@ -407,13 +408,8 @@ class L10n { * @access private */ function __autoLanguage() { - $_detectableLanguages = preg_split('/[,;]/', env('HTTP_ACCEPT_LANGUAGE')); + $_detectableLanguages = CakeRequest::acceptLanguage(); foreach ($_detectableLanguages as $key => $langKey) { - $langKey = strtolower($langKey); - if (strpos($langKey, '_') !== false) { - $langKey = str_replace('_', '-', $langKey); - } - if (isset($this->__l10nCatalog[$langKey])) { $this->__setLanguage($langKey); return true; From 157bdfafc61bc14c4091fd5e910c40552e31b672 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 31 Oct 2010 23:07:18 -0400 Subject: [PATCH 012/160] Moving beforeLayout, before additional viewVars are processed. Refs #624 --- cake/libs/view/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 33b42902a..49bb7bf44 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -423,6 +423,7 @@ class View extends Object { if (empty($layoutFileName)) { return $this->output; } + $this->Helpers->trigger('beforeLayout', array(&$this)); $dataForLayout = array_merge($this->viewVars, array( 'content_for_layout' => $content_for_layout, @@ -441,7 +442,6 @@ class View extends Object { $dataForLayout = array_merge($dataForLayout); } - $this->Helpers->trigger('beforeLayout', array(&$this)); $this->output = $this->_render($layoutFileName, $dataForLayout, $loadHelpers, true); if ($this->output === false) { From 8f31ef714940d6b9527d28084c2fa95c0873081a Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 31 Oct 2010 23:15:34 -0400 Subject: [PATCH 013/160] Making $scripts_for_layout and $content_for_layout regular viewVars. This will allow helpers to manipulate them in callbacks. Made $___dataForView an optional parameter, it defaults to $this->viewVars if left undefined. Refs #624 --- cake/libs/view/view.php | 16 +++++++++------- cake/tests/cases/libs/view/view.test.php | 3 +++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 49bb7bf44..f3ded56f1 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -379,7 +379,7 @@ class View extends Object { } if ($action !== false && $viewFileName = $this->_getViewFileName($action)) { - $out = $this->_render($viewFileName, $this->viewVars); + $out = $this->_render($viewFileName); } if ($layout === null) { @@ -425,13 +425,13 @@ class View extends Object { } $this->Helpers->trigger('beforeLayout', array(&$this)); - $dataForLayout = array_merge($this->viewVars, array( + $this->viewVars = array_merge($this->viewVars, array( 'content_for_layout' => $content_for_layout, 'scripts_for_layout' => implode("\n\t", $this->_scripts), )); - if (!isset($dataForLayout['title_for_layout'])) { - $dataForLayout['title_for_layout'] = Inflector::humanize($this->viewPath); + if (!isset($this->viewVars['title_for_layout'])) { + $this->viewVars['title_for_layout'] = Inflector::humanize($this->viewPath); } $attached = $this->Helpers->attached(); @@ -439,10 +439,9 @@ class View extends Object { $loadHelpers = true; } else { $loadHelpers = false; - $dataForLayout = array_merge($dataForLayout); } - $this->output = $this->_render($layoutFileName, $dataForLayout, $loadHelpers, true); + $this->output = $this->_render($layoutFileName, array(), $loadHelpers, true); if ($this->output === false) { $this->output = $this->_render($layoutFileName, $data_for_layout); @@ -662,13 +661,16 @@ class View extends Object { * @param boolean $cached Whether or not to trigger the creation of a cache file. * @return string Rendered output */ - protected function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) { + protected function _render($___viewFn, $___dataForView = array(), $loadHelpers = true, $cached = false) { $attached = $this->Helpers->attached(); if (count($attached) === 0 && $loadHelpers === true) { $this->loadHelpers(); $this->Helpers->trigger('beforeRender', array(&$this)); unset($attached); } + if (empty($___dataForView)) { + $___dataForView = $this->viewVars; + } extract($___dataForView, EXTR_SKIP); ob_start(); diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index d6295f74f..c31e7ef82 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -665,6 +665,9 @@ class ViewTest extends CakeTestCase { $this->assertPattern("//", $result); $this->assertPattern("/<div id=\"content\">posts index<\/div>/", $result); $this->assertPattern("/<div id=\"content\">posts index<\/div>/", $result); + + $this->assertTrue(isset($View->viewVars['content_for_layout']), 'content_for_layout should be a view var'); + $this->assertTrue(isset($View->viewVars['scripts_for_layout']), 'scripts_for_layout should be a view var'); $this->PostsController->set('url', 'flash'); $this->PostsController->set('message', 'yo what up'); From 3f61fa004e384f0a58dd0fe4e0d92cced598710f Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Wed, 3 Nov 2010 22:34:43 -0400 Subject: [PATCH 014/160] Removing dead import. --- cake/libs/view/view.php | 1 - 1 file changed, 1 deletion(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index f3ded56f1..3c3466f84 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -21,7 +21,6 @@ /** * Included libraries. */ -App::import('Core', 'ClassRegistry'); App::import('View', 'HelperCollection', false); App::import('View', 'Helper', false); From 540f1426be1c535a48b0078de7d53126da3f22ea Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Wed, 3 Nov 2010 22:46:11 -0400 Subject: [PATCH 015/160] Removing View::error(). Instead you should be handling error states in your controller, or throwing exceptions and letting the application error handling deal with the error. --- cake/libs/view/view.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 3c3466f84..92c917f1d 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -599,21 +599,6 @@ class View extends Object { $this->viewVars = $data + $this->viewVars; } -/** - * Displays an error page to the user. Uses layouts/error.ctp to render the page. - * - * @param integer $code HTTP Error code (for instance: 404) - * @param string $name Name of the error (for instance: Not Found) - * @param string $message Error message as a web page - */ - public function error($code, $name, $message) { - header ("HTTP/1.1 {$code} {$name}"); - print ($this->_render( - $this->_getLayoutFileName('error'), - array('code' => $code, 'name' => $name, 'message' => $message) - )); - } - /** * Magic accessor for helpers. Provides access to attributes that were deprecated. * From 76919902b90be98c05d7aaf49ab233912333edda Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Thu, 4 Nov 2010 22:29:41 -0400 Subject: [PATCH 016/160] Removing direct tests of protected method. Refactoring View with the intention of eventually removing coupling with CacheHelper. Making Helpers load after the first rendering method is called. Moving callbacks out of _render() to make logic simpler, and with the idea that elements will get a callback too. --- cake/libs/view/view.php | 45 +++++++++++++----------- cake/tests/cases/libs/view/view.test.php | 4 +-- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 92c917f1d..04f7ef028 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -267,6 +267,13 @@ class View extends Object { */ private $__paths = array(); +/** + * boolean to indicate that helpers have been loaded. + * + * @var boolean + */ + protected $_helpersLoaded = false; + /** * Constructor * @@ -345,6 +352,9 @@ class View extends Object { } if (is_file($file)) { + if (!$this->_helpersLoaded) { + $this->loadHelpers(); + } $element = $this->_render($file, array_merge($this->viewVars, $params), $loadHelpers); if (isset($params['cache']) && isset($cacheFile) && isset($expires)) { cache('views' . DS . $cacheFile, $element, $expires); @@ -371,6 +381,9 @@ class View extends Object { if ($this->hasRendered) { return true; } + if (!$this->_helpersLoaded) { + $this->loadHelpers(); + } $out = null; if ($file != null) { @@ -378,7 +391,9 @@ class View extends Object { } if ($action !== false && $viewFileName = $this->_getViewFileName($action)) { + $this->Helpers->trigger('beforeRender', array($this, $viewFileName)); $out = $this->_render($viewFileName); + $this->Helpers->trigger('afterRender', array($this, $viewFileName, $out)); } if ($layout === null) { @@ -422,7 +437,10 @@ class View extends Object { if (empty($layoutFileName)) { return $this->output; } - $this->Helpers->trigger('beforeLayout', array(&$this)); + if (!$this->_helpersLoaded) { + $this->loadHelpers(); + } + $this->Helpers->trigger('beforeLayout', array(&$this, $layoutFileName)); $this->viewVars = array_merge($this->viewVars, array( 'content_for_layout' => $content_for_layout, @@ -432,23 +450,16 @@ class View extends Object { if (!isset($this->viewVars['title_for_layout'])) { $this->viewVars['title_for_layout'] = Inflector::humanize($this->viewPath); } - - $attached = $this->Helpers->attached(); - if (empty($attached) && !empty($this->helpers)) { - $loadHelpers = true; - } else { - $loadHelpers = false; - } - $this->output = $this->_render($layoutFileName, array(), $loadHelpers, true); + $this->output = $this->_render($layoutFileName); if ($this->output === false) { $this->output = $this->_render($layoutFileName, $data_for_layout); trigger_error(sprintf(__("Error in layout %s, got: <blockquote>%s</blockquote>"), $layoutFileName, $this->output), E_USER_ERROR); return false; } - - $this->Helpers->trigger('afterLayout', array(&$this)); + + $this->Helpers->trigger('afterLayout', array(&$this, $layoutFileName, $this->output)); return $this->output; } @@ -633,6 +644,7 @@ class View extends Object { foreach ($helpers as $name => $properties) { $this->Helpers->load($properties['class'], $properties['settings'], true); } + $this->_helpersLoaded = true; } /** @@ -646,12 +658,6 @@ class View extends Object { * @return string Rendered output */ protected function _render($___viewFn, $___dataForView = array(), $loadHelpers = true, $cached = false) { - $attached = $this->Helpers->attached(); - if (count($attached) === 0 && $loadHelpers === true) { - $this->loadHelpers(); - $this->Helpers->trigger('beforeRender', array(&$this)); - unset($attached); - } if (empty($___dataForView)) { $___dataForView = $this->viewVars; } @@ -661,11 +667,8 @@ class View extends Object { include $___viewFn; - if ($loadHelpers === true) { - $this->Helpers->trigger('afterRender', array(&$this)); - } - $out = ob_get_clean(); + $caching = ( isset($this->Helpers->Cache) && (($this->cacheAction != false)) && (Configure::read('Cache.check') === true) diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index c31e7ef82..5c303cf74 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -635,7 +635,7 @@ class ViewTest extends CakeTestCase { $this->PostsController->helpers = array('Session', 'Html', 'Form', 'Number'); $View = new TestView($this->PostsController); - $result = $View->render_($View->getViewFileName('index'), array()); + $result = $View->render('index', false); $this->assertEqual($result, 'posts index'); $attached = $View->Helpers->attached(); @@ -644,7 +644,7 @@ class ViewTest extends CakeTestCase { $this->PostsController->helpers = array('Html', 'Form', 'Number', 'TestPlugin.PluggedHelper'); $View = new TestView($this->PostsController); - $result = $View->render_($View->getViewFileName('index'), array()); + $result = $View->render('index', false); $this->assertEqual($result, 'posts index'); $attached = $View->Helpers->attached(); From 882efa883e1c3b0cfb3530d2f40cade1f380b76c Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Thu, 4 Nov 2010 22:36:37 -0400 Subject: [PATCH 017/160] Removing the trigger_error and view re-renders and replacing them with exceptions. --- cake/libs/view/view.php | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 04f7ef028..8fac92859 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -399,25 +399,22 @@ class View extends Object { if ($layout === null) { $layout = $this->layout; } - - if ($out !== false) { - if ($layout && $this->autoLayout) { - $out = $this->renderLayout($out, $layout); - $isCached = ( - isset($this->Helpers->Cache) || - Configure::read('Cache.check') === true - ); - - if ($isCached) { - $replace = array('<cake:nocache>', '</cake:nocache>'); - $out = str_replace($replace, '', $out); - } - } - $this->hasRendered = true; - } else { - $out = $this->_render($viewFileName, $this->viewVars); - trigger_error(sprintf(__("Error in view %s, got: <blockquote>%s</blockquote>"), $viewFileName, $out), E_USER_ERROR); + if ($out === false) { + throw new RuntimeException(sprintf(__("Error in view %s, got no content."), $viewFileName)); } + if ($layout && $this->autoLayout) { + $out = $this->renderLayout($out, $layout); + $isCached = ( + isset($this->Helpers->Cache) || + Configure::read('Cache.check') === true + ); + + if ($isCached) { + $replace = array('<cake:nocache>', '</cake:nocache>'); + $out = str_replace($replace, '', $out); + } + } + $this->hasRendered = true; return $out; } @@ -454,9 +451,7 @@ class View extends Object { $this->output = $this->_render($layoutFileName); if ($this->output === false) { - $this->output = $this->_render($layoutFileName, $data_for_layout); - trigger_error(sprintf(__("Error in layout %s, got: <blockquote>%s</blockquote>"), $layoutFileName, $this->output), E_USER_ERROR); - return false; + throw new RuntimeException(sprintf(__("Error in layout %s, got no content."), $layoutFileName)); } $this->Helpers->trigger('afterLayout', array(&$this, $layoutFileName, $this->output)); From 1b19ad48b4dd4a3319f84fa8ab89605b68bc55d2 Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Thu, 4 Nov 2010 22:53:00 -0400 Subject: [PATCH 018/160] Adding parameters to helper callbacks, these allow helpers to introspect more on the view/layout being rendered. Updating tests. --- cake/libs/view/helper.php | 14 ++++++++++---- cake/libs/view/helpers/paginator.php | 4 ++-- cake/libs/view/view.php | 8 ++++---- .../cases/libs/view/helpers/paginator.test.php | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/cake/libs/view/helper.php b/cake/libs/view/helper.php index 43a7ecbcd..e435ed067 100644 --- a/cake/libs/view/helper.php +++ b/cake/libs/view/helper.php @@ -801,9 +801,10 @@ class Helper extends Object { * * Overridden in subclasses. * + * @param string $viewFile The view file that is going to be rendered * @return void */ - public function beforeRender() { + public function beforeRender($viewFile) { } /** @@ -812,9 +813,11 @@ class Helper extends Object { * * Overridden in subclasses. * + * @param string $viewFile The view file that was rendered. + * @param string $content The content of the rendered view. * @return void */ - public function afterRender() { + public function afterRender($viewFile, $content) { } /** @@ -822,9 +825,10 @@ class Helper extends Object { * * Overridden in subclasses. * + * @param string $layoutFile The layout about to be rendered. * @return void */ - public function beforeLayout() { + public function beforeLayout($layoutFile) { } /** @@ -832,9 +836,11 @@ class Helper extends Object { * * Overridden in subclasses. * + * @param string $layoutFile The layout file that was rendered. + * @param string $content The content of the rendered layout. * @return void */ - public function afterLayout() { + public function afterLayout($layoutFile, $content) { } /** diff --git a/cake/libs/view/helpers/paginator.php b/cake/libs/view/helpers/paginator.php index d20f89481..a9b3b32ed 100644 --- a/cake/libs/view/helpers/paginator.php +++ b/cake/libs/view/helpers/paginator.php @@ -110,10 +110,10 @@ class PaginatorHelper extends AppHelper { * * @return void */ - public function beforeRender() { + public function beforeRender($viewFile) { $this->options['url'] = array_merge($this->request->params['pass'], $this->request->params['named']); - parent::beforeRender(); + parent::beforeRender($viewFile); } /** diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 8fac92859..f0bdb4e4e 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -391,9 +391,9 @@ class View extends Object { } if ($action !== false && $viewFileName = $this->_getViewFileName($action)) { - $this->Helpers->trigger('beforeRender', array($this, $viewFileName)); + $this->Helpers->trigger('beforeRender', array($viewFileName)); $out = $this->_render($viewFileName); - $this->Helpers->trigger('afterRender', array($this, $viewFileName, $out)); + $this->Helpers->trigger('afterRender', array($viewFileName, $out)); } if ($layout === null) { @@ -437,7 +437,7 @@ class View extends Object { if (!$this->_helpersLoaded) { $this->loadHelpers(); } - $this->Helpers->trigger('beforeLayout', array(&$this, $layoutFileName)); + $this->Helpers->trigger('beforeLayout', array($layoutFileName)); $this->viewVars = array_merge($this->viewVars, array( 'content_for_layout' => $content_for_layout, @@ -454,7 +454,7 @@ class View extends Object { throw new RuntimeException(sprintf(__("Error in layout %s, got no content."), $layoutFileName)); } - $this->Helpers->trigger('afterLayout', array(&$this, $layoutFileName, $this->output)); + $this->Helpers->trigger('afterLayout', array($layoutFileName, $this->output)); return $this->output; } diff --git a/cake/tests/cases/libs/view/helpers/paginator.test.php b/cake/tests/cases/libs/view/helpers/paginator.test.php index e4a30f268..101f5395f 100644 --- a/cake/tests/cases/libs/view/helpers/paginator.test.php +++ b/cake/tests/cases/libs/view/helpers/paginator.test.php @@ -657,7 +657,7 @@ class PaginatorHelperTest extends CakeTestCase { $this->Paginator->request->params['pass'] = array(2); $this->Paginator->request->params['named'] = array('foo' => 'bar'); - $this->Paginator->beforeRender(); + $this->Paginator->beforeRender('posts/index'); $result = $this->Paginator->sort('title'); $expected = array( From 32587c154c034a47a46a2cbcfb8e4dcd5ddb511f Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Thu, 4 Nov 2010 23:32:18 -0400 Subject: [PATCH 019/160] Adding callback support to elements. You can use the 3rd parameter to control whether or not before/afterRender callbacks should be fired for a particular element. --- cake/libs/view/view.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index f0bdb4e4e..1f272dcb1 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -309,9 +309,11 @@ class View extends Object { * @param string $name Name of template file in the/app/views/elements/ folder * @param array $params Array of data to be made available to the for rendered * view (i.e. the Element) + * @param boolean $callbacks Set to true to fire beforeRender and afterRender helper callbacks for this element. + * Defaults to false. * @return string Rendered Element */ - public function element($name, $params = array(), $loadHelpers = false) { + public function element($name, $params = array(), $callbacks = false) { $file = $plugin = $key = null; if (isset($params['plugin'])) { @@ -355,7 +357,13 @@ class View extends Object { if (!$this->_helpersLoaded) { $this->loadHelpers(); } + if ($callbacks) { + $this->Helpers->trigger('beforeRender', array($file)); + } $element = $this->_render($file, array_merge($this->viewVars, $params), $loadHelpers); + if ($callbacks) { + $this->Helpers->trigger('afterRender', array($file, $element)); + } if (isset($params['cache']) && isset($cacheFile) && isset($expires)) { cache('views' . DS . $cacheFile, $element, $expires); } From 2e140a9fd3c48c82bfeb377c98c438a83a28bdfc Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Thu, 4 Nov 2010 23:45:07 -0400 Subject: [PATCH 020/160] Adding tests for element callbacks. --- cake/libs/view/view.php | 2 +- cake/tests/cases/libs/view/view.test.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 1f272dcb1..33df1c0df 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -360,7 +360,7 @@ class View extends Object { if ($callbacks) { $this->Helpers->trigger('beforeRender', array($file)); } - $element = $this->_render($file, array_merge($this->viewVars, $params), $loadHelpers); + $element = $this->_render($file, array_merge($this->viewVars, $params)); if ($callbacks) { $this->Helpers->trigger('afterRender', array($file, $element)); } diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index 5c303cf74..7c723a366 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -475,6 +475,21 @@ class ViewTest extends CakeTestCase { $this->assertPattern('/non_existant_element/', $result); } +/** + * test that elements can have callbacks + * + */ + function testElementCallbacks() { + $this->getMock('HtmlHelper', array(), array($this->View), 'ElementCallbackMockHtmlHelper'); + $this->View->helpers = array('ElementCallbackMockHtml'); + $this->View->loadHelpers(); + + $this->View->ElementCallbackMockHtml->expects($this->at(0))->method('beforeRender'); + $this->View->ElementCallbackMockHtml->expects($this->at(1))->method('afterRender'); + + $this->View->element('test_element', array(), true); + $this->mockObjects[] = $this->View->ElementCallbackMockHtml; + } /** * testElementCacheHelperNoCache method * From 2dff74d03705beb2f200d81bcf8910bf26fc90fc Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Thu, 4 Nov 2010 23:50:59 -0400 Subject: [PATCH 021/160] Removing local and using output property. --- cake/libs/view/view.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 33df1c0df..1a71fd9fd 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -392,7 +392,7 @@ class View extends Object { if (!$this->_helpersLoaded) { $this->loadHelpers(); } - $out = null; + $this->output = null; if ($file != null) { $action = $file; @@ -400,18 +400,18 @@ class View extends Object { if ($action !== false && $viewFileName = $this->_getViewFileName($action)) { $this->Helpers->trigger('beforeRender', array($viewFileName)); - $out = $this->_render($viewFileName); - $this->Helpers->trigger('afterRender', array($viewFileName, $out)); + $this->output = $this->_render($viewFileName); + $this->Helpers->trigger('afterRender', array($viewFileName, $this->output)); } if ($layout === null) { $layout = $this->layout; } - if ($out === false) { + if ($this->output === false) { throw new RuntimeException(sprintf(__("Error in view %s, got no content."), $viewFileName)); } if ($layout && $this->autoLayout) { - $out = $this->renderLayout($out, $layout); + $this->output = $this->renderLayout($this->output, $layout); $isCached = ( isset($this->Helpers->Cache) || Configure::read('Cache.check') === true @@ -419,11 +419,11 @@ class View extends Object { if ($isCached) { $replace = array('<cake:nocache>', '</cake:nocache>'); - $out = str_replace($replace, '', $out); + $this->output = str_replace($replace, '', $this->output); } } $this->hasRendered = true; - return $out; + return $this->output; } /** From aaff0591322204534d905814a0c207c8cee845d8 Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Thu, 4 Nov 2010 23:55:50 -0400 Subject: [PATCH 022/160] Moving output into a property, and removing extra arguments from helpers. Having a view property reduces the number of strings that are copied around. --- cake/libs/view/helper.php | 6 ++---- cake/libs/view/view.php | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/cake/libs/view/helper.php b/cake/libs/view/helper.php index e435ed067..2b0be4091 100644 --- a/cake/libs/view/helper.php +++ b/cake/libs/view/helper.php @@ -814,10 +814,9 @@ class Helper extends Object { * Overridden in subclasses. * * @param string $viewFile The view file that was rendered. - * @param string $content The content of the rendered view. * @return void */ - public function afterRender($viewFile, $content) { + public function afterRender($viewFile) { } /** @@ -837,10 +836,9 @@ class Helper extends Object { * Overridden in subclasses. * * @param string $layoutFile The layout file that was rendered. - * @param string $content The content of the rendered layout. * @return void */ - public function afterLayout($layoutFile, $content) { + public function afterLayout($layoutFile) { } /** diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 1a71fd9fd..425d35d7b 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -401,7 +401,7 @@ class View extends Object { if ($action !== false && $viewFileName = $this->_getViewFileName($action)) { $this->Helpers->trigger('beforeRender', array($viewFileName)); $this->output = $this->_render($viewFileName); - $this->Helpers->trigger('afterRender', array($viewFileName, $this->output)); + $this->Helpers->trigger('afterRender', array($viewFileName)); } if ($layout === null) { @@ -462,7 +462,7 @@ class View extends Object { throw new RuntimeException(sprintf(__("Error in layout %s, got no content."), $layoutFileName)); } - $this->Helpers->trigger('afterLayout', array($layoutFileName, $this->output)); + $this->Helpers->trigger('afterLayout', array($layoutFileName)); return $this->output; } From 23c69b2bfbc7f336b708579ac83aad547a05820a Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Fri, 5 Nov 2010 23:16:15 -0400 Subject: [PATCH 023/160] Adding an import, as I hit an error when trying to bake tests for models. --- cake/console/shells/tasks/test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/cake/console/shells/tasks/test.php b/cake/console/shells/tasks/test.php index ce300f058..9c8ff21db 100644 --- a/cake/console/shells/tasks/test.php +++ b/cake/console/shells/tasks/test.php @@ -19,6 +19,7 @@ */ include_once dirname(__FILE__) . DS . 'bake.php'; +App::import('Model', 'ClassRegistry'); /** * Task class for creating and updating test files. From 1bc6433ecd7c3506b1c7b560e0ee0d3a96656914 Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Fri, 5 Nov 2010 23:20:16 -0400 Subject: [PATCH 024/160] Removing duplicate import() and fixing missing dependency. --- cake/libs/controller/controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 5e6469dc7..a0cd556b9 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -22,8 +22,8 @@ * Include files */ App::import('Core', 'CakeResponse', false); +App::import('Core', 'ClassRegistry', false); App::import('Controller', 'Component', false); -App::import('Core', 'CakeResponse', false); App::import('View', 'View', false); /** From c92ecdcd1bd2c060180125ede9f19936f76ff0fc Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Sat, 6 Nov 2010 00:07:51 -0400 Subject: [PATCH 025/160] Initial pass at decoupling CacheHelper from View. CacheHelper does all caching using helper callbacks now. --- cake/libs/view/helpers/cache.php | 70 ++++++++++++++++++-------------- cake/libs/view/view.php | 23 +---------- 2 files changed, 41 insertions(+), 52 deletions(-) diff --git a/cake/libs/view/helpers/cache.php b/cake/libs/view/helpers/cache.php index fc0f6bff5..1e388f802 100644 --- a/cake/libs/view/helpers/cache.php +++ b/cake/libs/view/helpers/cache.php @@ -49,12 +49,28 @@ class CacheHelper extends AppHelper { private $__match = array(); /** - * cache action time + * Parses the view file and stores content for cache file building. * - * @var object - * @access public + * @return void */ - public $cacheAction; + public function afterRender($viewFile) { + $caching = (($this->_View->cacheAction != false)) && (Configure::read('Cache.check') === true); + if ($caching) { + $this->cache($viewFile, $this->_View->output, false); + } + } + +/** + * Parses the layout file and stores content for cache file building. + * + * @return void + */ + public function afterLayout($layoutFile) { + $caching = (($this->_View->cacheAction != false)) && (Configure::read('Cache.check') === true); + if ($caching) { + $this->cache($layoutFile, $this->_View->output, true); + } + } /** * Main method used to cache a view @@ -67,8 +83,10 @@ class CacheHelper extends AppHelper { function cache($file, $out, $cache = false) { $cacheTime = 0; $useCallbacks = false; - if (is_array($this->cacheAction)) { - $keys = array_keys($this->cacheAction); + $cacheAction = $this->_View->cacheAction; + + if (is_array($cacheAction)) { + $keys = array_keys($cacheAction); $index = null; foreach ($keys as $action) { @@ -82,12 +100,12 @@ class CacheHelper extends AppHelper { $index = 'index'; } - $options = $this->cacheAction; - if (isset($this->cacheAction[$index])) { - if (is_array($this->cacheAction[$index])) { - $options = array_merge(array('duration' => 0, 'callbacks' => false), $this->cacheAction[$index]); + $options = $cacheAction; + if (isset($cacheAction[$index])) { + if (is_array($cacheAction[$index])) { + $options = array_merge(array('duration' => 0, 'callbacks' => false), $cacheAction[$index]); } else { - $cacheTime = $this->cacheAction[$index]; + $cacheTime = $cacheAction[$index]; } } if (isset($options['duration'])) { @@ -97,7 +115,7 @@ class CacheHelper extends AppHelper { $useCallbacks = $options['callbacks']; } } else { - $cacheTime = $this->cacheAction; + $cacheTime = $cacheAction; } if ($cacheTime != '' && $cacheTime > 0) { @@ -213,36 +231,28 @@ class CacheHelper extends AppHelper { $cache = $cache . '.php'; $file = '<!--cachetime:' . $cacheTime . '--><?php'; - if (empty($this->plugin)) { + if (empty($this->_View->plugin)) { $file .= ' - App::import(\'Controller\', \'' . $this->controllerName. '\'); + App::import(\'Controller\', \'' . $this->_View->name. '\'); '; } else { $file .= ' - App::import(\'Controller\', \'' . $this->plugin . '.' . $this->controllerName. '\'); + App::import(\'Controller\', \'' . $this->_View->plugin . '.' . $this->_View->name. '\'); '; } - $file .= '$controller =& new ' . $this->controllerName . 'Controller(); - $controller->plugin = $this->plugin = \''.$this->plugin.'\'; - $controller->helpers = $this->helpers = unserialize(\'' . serialize($this->helpers) . '\'); - $controller->base = $this->base = \'' . $this->base . '\'; - $controller->layout = $this->layout = \'' . $this->layout. '\'; - $controller->webroot = $this->webroot = \'' . $this->webroot . '\'; - $controller->here = $this->here = \'' . $this->here . '\'; - $controller->params = $this->params = unserialize(\'' . str_replace("'", "\\'", serialize($this->params)) . '\'); + $file .= '$controller = new ' . $this->_View->name . 'Controller(); + $controller->plugin = $this->plugin = \'' . $this->_View->plugin . '\'; + $controller->helpers = $this->helpers = unserialize(\'' . serialize($this->_View->helpers) . '\'); + $controller->layout = $this->layout = \'' . $this->_View->layout. '\'; $controller->request = $this->request = unserialize(\'' . str_replace("'", "\\'", serialize($this->request)) . '\'); - $controller->action = $this->action = unserialize(\'' . serialize($this->action) . '\'); - $controller->data = $this->data = unserialize(\'' . str_replace("'", "\\'", serialize($this->data)) . '\'); - $controller->theme = $this->theme = \'' . $this->theme . '\'; - Router::setRequestInfo($this->params);'; + $controller->theme = $this->theme = \'' . $this->_View->theme . '\'; + Router::setRequestInfo($controller->request);'; if ($useCallbacks == true) { $file .= ' $controller->constructClasses(); - $controller->Component->initialize($controller); - $controller->beforeFilter(); - $controller->Component->startup($controller);'; + $controller->startupProcess();'; } $file .= ' diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 425d35d7b..43b74f852 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -463,7 +463,6 @@ class View extends Object { } $this->Helpers->trigger('afterLayout', array($layoutFileName)); - return $this->output; } @@ -670,27 +669,7 @@ class View extends Object { include $___viewFn; - $out = ob_get_clean(); - - $caching = ( - isset($this->Helpers->Cache) && - (($this->cacheAction != false)) && (Configure::read('Cache.check') === true) - ); - - if ($caching) { - if (isset($this->Helpers->Cache)) { - $cache =& $this->Helpers->Cache; - $cache->base = $this->request->base; - $cache->here = $this->request->here; - $cache->helpers = $this->helpers; - $cache->action = $this->request->action; - $cache->controllerName = $this->name; - $cache->layout = $this->layout; - $cache->cacheAction = $this->cacheAction; - $cache->cache($___viewFn, $out, $cached); - } - } - return $out; + return ob_get_clean(); } /** From f7f9c3f6a210f2aea58bc68b3ebd5d0e135df136 Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Sat, 6 Nov 2010 00:26:09 -0400 Subject: [PATCH 026/160] Removing a test case that doesn't need to exist anymore as the conditions for cache generation are now in CacheHelper. --- cake/tests/cases/libs/view/view.test.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index 7c723a366..88c821be7 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -711,30 +711,6 @@ class ViewTest extends CakeTestCase { $this->assertPattern("/<div id=\"content\">posts index<\/div>/", $result); } -/** - * test rendering layout with cache helper loaded - * - * @return void - */ - function testRenderLayoutWithMockCacheHelper() { - $_check = Configure::read('Cache.check'); - Configure::write('Cache.check', true); - - $Controller = new ViewPostsController($this->getMock('CakeRequest')); - $Controller->cacheAction = '1 day'; - $View = new View($Controller); - $View->helpers = array('Cache', 'Html', 'Session'); - $View->loadHelpers(); - - $View->Helpers->Cache = $this->getMock('CacheHelper', array(), array($View)); - $View->Helpers->Cache->expects($this->exactly(2))->method('cache'); - - $result = $View->render('index'); - $this->assertPattern('/posts index/', $result); - - Configure::write('Cache.check', $_check); - } - /** * test that view vars can replace the local helper variables * and not overwrite the $this->Helper references From 4739d7f955c0d86fc5f5ba6d5d5c9baab20059e0 Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Sat, 6 Nov 2010 00:32:20 -0400 Subject: [PATCH 027/160] Adding tests for CacheHelper callback methods. --- .../cases/libs/view/helpers/cache.test.php | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/cache.test.php b/cake/tests/cases/libs/view/helpers/cache.test.php index a27ada2ec..dc24ec5a1 100644 --- a/cake/tests/cases/libs/view/helpers/cache.test.php +++ b/cake/tests/cases/libs/view/helpers/cache.test.php @@ -75,11 +75,11 @@ class CacheHelperTest extends CakeTestCase { * @return void */ function setUp() { + parent::setUp(); $request = new CakeRequest(); $this->Controller = new CacheTestController($request); $View = new View($this->Controller); $this->Cache = new CacheHelper($View); - $this->_cacheSettings = Configure::read('Cache'); Configure::write('Cache.check', true); Configure::write('Cache.disable', false); App::build(array( @@ -96,8 +96,7 @@ class CacheHelperTest extends CakeTestCase { function tearDown() { clearCache(); unset($this->Cache); - Configure::write('Cache', $this->_cacheSettings); - App::build(); + parent::tearDown(); } /** @@ -470,6 +469,54 @@ class CacheHelperTest extends CakeTestCase { @unlink($filename); } +/** + * test that afterRender checks the conditions correctly. + * + * @return void + */ + function testAfterRenderConditions() { + Configure::write('Cache.check', true); + $View = new View($this->Controller); + $View->cacheAction = '+1 day'; + $View->output = 'test'; + + $Cache = $this->getMock('CacheHelper', array('cache'), array($View)); + $Cache->expects($this->once())->method('cache') + ->with('posts/index', $View->output, false); + $Cache->afterRender('posts/index'); + + Configure::write('Cache.check', false); + $Cache->afterRender('posts/index'); + + Configure::write('Cache.check', true); + $View->cacheAction = false; + $Cache->afterRender('posts/index'); + } + +/** + * test that afterRender checks the conditions correctly. + * + * @return void + */ + function testAfterLayoutConditions() { + Configure::write('Cache.check', true); + $View = new View($this->Controller); + $View->cacheAction = '+1 day'; + $View->output = 'test'; + + $Cache = $this->getMock('CacheHelper', array('cache'), array($View)); + $Cache->expects($this->once())->method('cache') + ->with('posts/index', $View->output, true); + $Cache->afterLayout('posts/index'); + + Configure::write('Cache.check', false); + $Cache->afterLayout('posts/index'); + + Configure::write('Cache.check', true); + $View->cacheAction = false; + $Cache->afterLayout('posts/index'); + } + /** * testCacheEmptySections method * From 4c0fd76a2efc3ae9bbbdd27ed38d7541d58d7969 Mon Sep 17 00:00:00 2001 From: mark_story <mark@mark-story.com> Date: Sat, 6 Nov 2010 01:18:23 -0400 Subject: [PATCH 028/160] Changing <cake:nocache></cake:nocache> into <!--nocache--><!--/nocache--> This makes no cache tags valid html/xml at all times, and will not interfere with validation. --- cake/libs/view/helpers/cache.php | 30 +++++++++---------- cake/libs/view/view.php | 2 +- .../cases/libs/view/helpers/cache.test.php | 2 +- .../elements/nocache/contains_nocache.ctp | 4 +-- .../test_app/views/elements/nocache/sub1.ctp | 4 +-- .../test_app/views/elements/nocache/sub2.ctp | 4 +-- .../views/layouts/cache_empty_sections.ctp | 8 ++--- .../test_app/views/layouts/cache_layout.ctp | 8 ++--- .../test_app/views/layouts/multi_cache.ctp | 18 +++++------ .../views/posts/cache_empty_sections.ctp | 2 +- .../tests/test_app/views/posts/cache_form.ctp | 4 +-- .../test_app/views/posts/multiple_nocache.ctp | 12 ++++---- .../views/posts/nocache_multiple_element.ctp | 8 ++--- .../views/posts/sequencial_nocache.ctp | 4 +-- .../views/posts/test_nocache_tags.ctp | 4 +-- 15 files changed, 56 insertions(+), 58 deletions(-) diff --git a/cake/libs/view/helpers/cache.php b/cake/libs/view/helpers/cache.php index 1e388f802..917128e31 100644 --- a/cake/libs/view/helpers/cache.php +++ b/cake/libs/view/helpers/cache.php @@ -32,21 +32,19 @@ class CacheHelper extends AppHelper { /** * Array of strings replaced in cached views. - * The strings are found between <cake:nocache><cake:nocache> in views + * The strings are found between `<!--nocache--><!--/nocache-->` in views * * @var array - * @access private */ - private $__replace = array(); + protected $_replace = array(); /** * Array of string that are replace with there var replace above. - * The strings are any content inside <cake:nocache><cake:nocache> and includes the tags in views + * The strings are any content inside `<!--nocache--><!--/nocache-->` and includes the tags in views * * @var array - * @access private */ - private $__match = array(); + protected $_match = array(); /** * Parses the view file and stores content for cache file building. @@ -143,14 +141,14 @@ class CacheHelper extends AppHelper { } elseif ($file = fileExistsInPath($file)) { $file = file_get_contents($file); } - preg_match_all('/(<cake:nocache>(?<=<cake:nocache>)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $outputResult, PREG_PATTERN_ORDER); - preg_match_all('/(?<=<cake:nocache>)([\\s\\S]*?)(?=<\/cake:nocache>)/i', $file, $fileResult, PREG_PATTERN_ORDER); + preg_match_all('/(<!--nocache-->(?<=<!--nocache-->)[\\s\\S]*?(?=<!--\/nocache-->)<!--\/nocache-->)/i', $cache, $outputResult, PREG_PATTERN_ORDER); + preg_match_all('/(?<=<!--nocache-->)([\\s\\S]*?)(?=<!--\/nocache-->)/i', $file, $fileResult, PREG_PATTERN_ORDER); $fileResult = $fileResult[0]; $outputResult = $outputResult[0]; - if (!empty($this->__replace)) { + if (!empty($this->_replace)) { foreach ($outputResult as $i => $element) { - $index = array_search($element, $this->__match); + $index = array_search($element, $this->_match); if ($index !== false) { unset($outputResult[$i]); } @@ -162,8 +160,8 @@ class CacheHelper extends AppHelper { $i = 0; foreach ($fileResult as $cacheBlock) { if (isset($outputResult[$i])) { - $this->__replace[] = $cacheBlock; - $this->__match[] = $outputResult[$i]; + $this->_replace[] = $cacheBlock; + $this->_match[] = $outputResult[$i]; } $i++; } @@ -174,13 +172,13 @@ class CacheHelper extends AppHelper { * Parse the output and replace cache tags * * @param string $cache Output to replace content in. - * @return string with all replacements made to <cake:nocache><cake:nocache> + * @return string with all replacements made to <!--nocache--><!--nocache--> * @access private */ function __parseOutput($cache) { $count = 0; - if (!empty($this->__match)) { - foreach ($this->__match as $found) { + if (!empty($this->_match)) { + foreach ($this->_match as $found) { $original = $cache; $length = strlen($found); $position = 0; @@ -190,7 +188,7 @@ class CacheHelper extends AppHelper { if ($position !== false) { $cache = substr($original, 0, $position); - $cache .= $this->__replace[$count]; + $cache .= $this->_replace[$count]; $cache .= substr($original, $position + $length); } else { break; diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 43b74f852..698b7fe4d 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -418,7 +418,7 @@ class View extends Object { ); if ($isCached) { - $replace = array('<cake:nocache>', '</cake:nocache>'); + $replace = array('<!--nocache-->', '<!--/nocache-->'); $this->output = str_replace($replace, '', $this->output); } } diff --git a/cake/tests/cases/libs/view/helpers/cache.test.php b/cake/tests/cases/libs/view/helpers/cache.test.php index dc24ec5a1..95d8e9a01 100644 --- a/cake/tests/cases/libs/view/helpers/cache.test.php +++ b/cake/tests/cases/libs/view/helpers/cache.test.php @@ -198,7 +198,7 @@ class CacheHelperTest extends CakeTestCase { } /** - * test that multiple <cake:nocache> tags function with multiple nocache tags in the layout. + * test that multiple <!--nocache--> tags function with multiple nocache tags in the layout. * * @return void */ diff --git a/cake/tests/test_app/views/elements/nocache/contains_nocache.ctp b/cake/tests/test_app/views/elements/nocache/contains_nocache.ctp index 588197e03..d44550ecc 100644 --- a/cake/tests/test_app/views/elements/nocache/contains_nocache.ctp +++ b/cake/tests/test_app/views/elements/nocache/contains_nocache.ctp @@ -1,5 +1,5 @@ <h2>Cache Me</h2> -<cake:nocache> +<!--nocache--> <p>F. In Element With No Cache Tags</p> <?php $this->log('6. In element with no cache tags') ?> -</cake:nocache> +<!--/nocache--> diff --git a/cake/tests/test_app/views/elements/nocache/sub1.ctp b/cake/tests/test_app/views/elements/nocache/sub1.ctp index ea85a9fd8..8557e05ce 100644 --- a/cake/tests/test_app/views/elements/nocache/sub1.ctp +++ b/cake/tests/test_app/views/elements/nocache/sub1.ctp @@ -1,8 +1,8 @@ <?php echo $this->element('nocache/sub2'); ?> -<cake:nocache> +<!--nocache--> <?php $foobar = 'in sub1'; ?> <?php echo $foobar; ?> -</cake:nocache> +<!--/nocache--> <?php echo 'printing: "' . $foobar . '"'; ?> \ No newline at end of file diff --git a/cake/tests/test_app/views/elements/nocache/sub2.ctp b/cake/tests/test_app/views/elements/nocache/sub2.ctp index 236cd75c5..991e3b17f 100644 --- a/cake/tests/test_app/views/elements/nocache/sub2.ctp +++ b/cake/tests/test_app/views/elements/nocache/sub2.ctp @@ -1,6 +1,6 @@ -<cake:nocache> +<!--nocache--> <?php $barfoo = 'in sub2'; ?> <?php echo $barfoo; ?> -</cake:nocache> +<!--/nocache--> <?php echo 'printing: "' . $barfoo . '"'; ?> \ No newline at end of file diff --git a/cake/tests/test_app/views/layouts/cache_empty_sections.ctp b/cake/tests/test_app/views/layouts/cache_empty_sections.ctp index 3b1777fd4..dae25af94 100644 --- a/cake/tests/test_app/views/layouts/cache_empty_sections.ctp +++ b/cake/tests/test_app/views/layouts/cache_empty_sections.ctp @@ -2,12 +2,12 @@ <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title><?php echo $title_for_layout; ?> - + - - + + - + \ No newline at end of file diff --git a/cake/tests/test_app/views/layouts/cache_layout.ctp b/cake/tests/test_app/views/layouts/cache_layout.ctp index a5b1704e7..1fd6ff624 100644 --- a/cake/tests/test_app/views/layouts/cache_layout.ctp +++ b/cake/tests/test_app/views/layouts/cache_layout.ctp @@ -18,15 +18,15 @@ */ ?>

This is regular text

- + - + - + - +

Additional regular text.

\ No newline at end of file diff --git a/cake/tests/test_app/views/layouts/multi_cache.ctp b/cake/tests/test_app/views/layouts/multi_cache.ctp index 2ed0dd1b8..d3bb46503 100644 --- a/cake/tests/test_app/views/layouts/multi_cache.ctp +++ b/cake/tests/test_app/views/layouts/multi_cache.ctp @@ -18,23 +18,23 @@ */ ?>

This is regular text

- +

A. Layout Before Content

log('1. layout before content') ?> -
-element('nocache/plain'); ?> - + +element('nocache/plain'); ?> +

C. Layout After Test Element But Before Content

log('3. layout after test element but before content') ?> -
+ - +

E. Layout After Content

log('5. layout after content') ?> -
+

Additional regular text.

element('nocache/contains_nocache'); stub?> - +

G. Layout After Content And After Element With No Cache Tags

log('7. layout after content and after element with no cache tags') ?> -
\ No newline at end of file + \ No newline at end of file diff --git a/cake/tests/test_app/views/posts/cache_empty_sections.ctp b/cake/tests/test_app/views/posts/cache_empty_sections.ctp index ab6fb3ae9..0bb2bc45b 100644 --- a/cake/tests/test_app/views/posts/cache_empty_sections.ctp +++ b/cake/tests/test_app/views/posts/cache_empty_sections.ctp @@ -1,2 +1,2 @@ View Content - + diff --git a/cake/tests/test_app/views/posts/cache_form.ctp b/cake/tests/test_app/views/posts/cache_form.ctp index 7cf121904..6f782af6d 100644 --- a/cake/tests/test_app/views/posts/cache_form.ctp +++ b/cake/tests/test_app/views/posts/cache_form.ctp @@ -1,5 +1,5 @@
- + Form->create('User');?>
@@ -10,5 +10,5 @@ ?>
Form->end('Submit');?> -
+
\ No newline at end of file diff --git a/cake/tests/test_app/views/posts/multiple_nocache.ctp b/cake/tests/test_app/views/posts/multiple_nocache.ctp index eb397e492..4ee095b36 100644 --- a/cake/tests/test_app/views/posts/multiple_nocache.ctp +++ b/cake/tests/test_app/views/posts/multiple_nocache.ctp @@ -1,15 +1,15 @@ --view start-- - + - + this view has 3 nocache blocks - + - + - + - + --view end-- \ No newline at end of file diff --git a/cake/tests/test_app/views/posts/nocache_multiple_element.ctp b/cake/tests/test_app/views/posts/nocache_multiple_element.ctp index a72788305..d6770e23b 100644 --- a/cake/tests/test_app/views/posts/nocache_multiple_element.ctp +++ b/cake/tests/test_app/views/posts/nocache_multiple_element.ctp @@ -1,9 +1,9 @@ - + - + - + - + element('nocache/sub1'); ?> \ No newline at end of file diff --git a/cake/tests/test_app/views/posts/sequencial_nocache.ctp b/cake/tests/test_app/views/posts/sequencial_nocache.ctp index 215f68a4e..7fa93fa5c 100644 --- a/cake/tests/test_app/views/posts/sequencial_nocache.ctp +++ b/cake/tests/test_app/views/posts/sequencial_nocache.ctp @@ -18,7 +18,7 @@ */ ?>

Content

- +

D. In View File

log('4. in view file') ?> -
\ No newline at end of file + \ No newline at end of file diff --git a/cake/tests/test_app/views/posts/test_nocache_tags.ctp b/cake/tests/test_app/views/posts/test_nocache_tags.ctp index 1692f1550..d489f6f78 100644 --- a/cake/tests/test_app/views/posts/test_nocache_tags.ctp +++ b/cake/tests/test_app/views/posts/test_nocache_tags.ctp @@ -18,7 +18,7 @@ */ ?>

- + - +

From 92fec4588ade8151a22b2c5166ceb9862ed6b21e Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 6 Nov 2010 01:23:08 -0400 Subject: [PATCH 029/160] Making private things protected. --- cake/libs/view/helpers/cache.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/cake/libs/view/helpers/cache.php b/cake/libs/view/helpers/cache.php index 917128e31..196fbf4e1 100644 --- a/cake/libs/view/helpers/cache.php +++ b/cake/libs/view/helpers/cache.php @@ -78,7 +78,7 @@ class CacheHelper extends AppHelper { * @param boolean $cache Whether or not a cache file should be written. * @return string view ouput */ - function cache($file, $out, $cache = false) { + public function cache($file, $out, $cache = false) { $cacheTime = 0; $useCallbacks = false; $cacheAction = $this->_View->cacheAction; @@ -117,10 +117,10 @@ class CacheHelper extends AppHelper { } if ($cacheTime != '' && $cacheTime > 0) { - $this->__parseFile($file, $out); + $this->_parseFile($file, $out); if ($cache === true) { - $cached = $this->__parseOutput($out); - $this->__writeFile($cached, $cacheTime, $useCallbacks); + $cached = $this->_parseOutput($out); + $this->_writeFile($cached, $cacheTime, $useCallbacks); } return $out; } else { @@ -133,9 +133,8 @@ class CacheHelper extends AppHelper { * * @param string $file The filename that needs to be parsed. * @param string $cache The cached content - * @access private */ - function __parseFile($file, $cache) { + protected function _parseFile($file, $cache) { if (is_file($file)) { $file = file_get_contents($file); } elseif ($file = fileExistsInPath($file)) { @@ -173,9 +172,8 @@ class CacheHelper extends AppHelper { * * @param string $cache Output to replace content in. * @return string with all replacements made to - * @access private */ - function __parseOutput($cache) { + protected function _parseOutput($cache) { $count = 0; if (!empty($this->_match)) { foreach ($this->_match as $found) { @@ -207,9 +205,8 @@ class CacheHelper extends AppHelper { * @param string $content view content to write to a cache file. * @param sting $timestamp Duration to set for cache file. * @return boolean success of caching view. - * @access private */ - function __writeFile($content, $timestamp, $useCallbacks = false) { + protected function _writeFile($content, $timestamp, $useCallbacks = false) { $now = time(); if (is_numeric($timestamp)) { From 1ba28c246b0f8da0624bbf385182f704e9ce1acb Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 6 Nov 2010 14:58:27 -0400 Subject: [PATCH 030/160] Adding settings['callbacks'] as a way to define enabled/disabled state of helpers in settings arrays. This should replace the separate parameter. Tests updated. --- cake/libs/view/helper_collection.php | 5 ++++- .../cases/libs/view/helper_collection.test.php | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cake/libs/view/helper_collection.php b/cake/libs/view/helper_collection.php index 27f9d00bb..6640bb8a2 100644 --- a/cake/libs/view/helper_collection.php +++ b/cake/libs/view/helper_collection.php @@ -38,6 +38,9 @@ class HelperCollection extends ObjectCollection { /** * Loads/constructs a helper. Will return the instance in the registry if it already exists. + * By setting `$enable` to false you can disable callbacks for a helper. Alternatively you + * can set `$settings['callbacks'] = false` to disable callbacks. This alias is provided so that when + * declaring $helpers arrays you can disable callbacks on helpers. * * @param string $helper Helper name to load * @param array $settings Settings for the helper. @@ -72,7 +75,7 @@ class HelperCollection extends ObjectCollection { foreach ($vars as $var) { $this->_loaded[$name]->{$var} = $this->_View->{$var}; } - + $enable = isset($settings['callbacks']) ? $settings['callbacks'] : $enable; if ($enable === true) { $this->_enabled[] = $name; } diff --git a/cake/tests/cases/libs/view/helper_collection.test.php b/cake/tests/cases/libs/view/helper_collection.test.php index e0b586e2a..5d6dda543 100644 --- a/cake/tests/cases/libs/view/helper_collection.test.php +++ b/cake/tests/cases/libs/view/helper_collection.test.php @@ -69,6 +69,20 @@ class HelperCollectionTest extends CakeTestCase { $this->assertFalse($this->Helpers->enabled('Html'), 'Html should be disabled'); } + +/** + * test that the callbacks setting disables the helper. + * + * @return void + */ + function testLoadWithCallbacksFalse() { + $result = $this->Helpers->load('Html', array('callbacks' => false)); + $this->assertType('HtmlHelper', $result); + $this->assertType('HtmlHelper', $this->Helpers->Html); + + $this->assertFalse($this->Helpers->enabled('Html'), 'Html should be disabled'); + } + /** * test missinghelper exception * From 88c717dbd8c886d31d9d2a4551e299f73fcbc4b6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 6 Nov 2010 23:48:27 -0400 Subject: [PATCH 031/160] Removing the 3rd param from ObjectCollection::load() and adding a uniform setting of 'callbacks'. This setting is used to disable callbacks on objects by convention. Test cases updated. --- cake/libs/controller/component_collection.php | 6 ++++-- cake/libs/model/behavior_collection.php | 8 ++++---- cake/libs/object_collection.php | 6 ++++-- cake/libs/view/helper_collection.php | 5 ++--- cake/libs/view/view.php | 7 ++++--- .../cases/libs/controller/component_collection.test.php | 2 +- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/cake/libs/controller/component_collection.php b/cake/libs/controller/component_collection.php index 2f8e6b286..af27989b1 100644 --- a/cake/libs/controller/component_collection.php +++ b/cake/libs/controller/component_collection.php @@ -56,14 +56,15 @@ class ComponentCollection extends ObjectCollection { /** * Loads/constructs a component. Will return the instance in the registry if it already exists. + * You can use `$settings['callbacks'] = false` to disable callbacks on a component when loading it. + * Callbacks default to on. * * @param string $component Component name to load * @param array $settings Settings for the component. - * @param boolean $enable Whether or not this component should be enabled by default * @return Component A component object, Either the existing loaded component or a new one. * @throws MissingComponentFileException, MissingComponentClassException when the component could not be found */ - public function load($component, $settings = array(), $enable = true) { + public function load($component, $settings = array()) { list($plugin, $name) = pluginSplit($component); if (isset($this->_loaded[$name])) { return $this->_loaded[$name]; @@ -84,6 +85,7 @@ class ComponentCollection extends ObjectCollection { } } $this->_loaded[$name] = new $componentClass($this, $settings); + $enable = isset($settings['callbacks']) ? $settings['callbacks'] : true; if ($enable === true) { $this->_enabled[] = $name; } diff --git a/cake/libs/model/behavior_collection.php b/cake/libs/model/behavior_collection.php index c339586ad..2df40a978 100644 --- a/cake/libs/model/behavior_collection.php +++ b/cake/libs/model/behavior_collection.php @@ -81,15 +81,15 @@ class BehaviorCollection extends ObjectCollection { } /** - * Loads a behavior into the collection. + * Loads a behavior into the collection. You can use use `$config['callbacks'] = false` + * to load a behavior with callbacks disabled. By default callbacks are enabled. * * @param string $behavior CamelCased name of the behavior to load * @param array $config Behavior configuration parameters - * @param boolean $enable Whether or not this helper should be enabled by default * @return boolean True on success, false on failure * @throws MissingBehaviorFileException or MissingBehaviorClassException when a behavior could not be found. */ - public function load($behavior, $config = array(), $enable = true) { + public function load($behavior, $config = array()) { list($plugin, $name) = pluginSplit($behavior); $class = $name . 'Behavior'; @@ -150,7 +150,7 @@ class BehaviorCollection extends ObjectCollection { } } - $configDisabled = isset($config['enabled']) && $config['enabled'] === false; + $configDisabled = isset($config['callbacks']) && $config['callbacks'] === false; if (!in_array($name, $this->_enabled) && !$configDisabled) { $this->enable($name); } elseif ($configDisabled) { diff --git a/cake/libs/object_collection.php b/cake/libs/object_collection.php index 26947641b..b2a6eb443 100644 --- a/cake/libs/object_collection.php +++ b/cake/libs/object_collection.php @@ -38,12 +38,14 @@ abstract class ObjectCollection { /** * Loads a new object onto the collection. Can throw a variety of exceptions * + * Implementations of this class support a `$options['callbacks']` flag which enables/disables + * a loaded object. + * * @param string $name Name of object to load. * @param array $options Array of configuration options for the object to be constructed. - * @param boolean $enable Whether or not this helper should be enabled by default * @return object the constructed object */ - abstract public function load($name, $options = array(), $enable = true); + abstract public function load($name, $options = array()); /** * Trigger a callback method on every object in the collection. diff --git a/cake/libs/view/helper_collection.php b/cake/libs/view/helper_collection.php index 6640bb8a2..61567c811 100644 --- a/cake/libs/view/helper_collection.php +++ b/cake/libs/view/helper_collection.php @@ -44,11 +44,10 @@ class HelperCollection extends ObjectCollection { * * @param string $helper Helper name to load * @param array $settings Settings for the helper. - * @param boolean $enable Whether or not this helper should be enabled by default * @return Helper A helper object, Either the existing loaded helper or a new one. * @throws MissingHelperFileException, MissingHelperClassException when the helper could not be found */ - public function load($helper, $settings = array(), $enable = true) { + public function load($helper, $settings = array()) { list($plugin, $name) = pluginSplit($helper, true); if (isset($this->_loaded[$name])) { @@ -75,7 +74,7 @@ class HelperCollection extends ObjectCollection { foreach ($vars as $var) { $this->_loaded[$name]->{$var} = $this->_View->{$var}; } - $enable = isset($settings['callbacks']) ? $settings['callbacks'] : $enable; + $enable = isset($settings['callbacks']) ? $settings['callbacks'] : false; if ($enable === true) { $this->_enabled[] = $name; } diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 698b7fe4d..c3343af5f 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -673,14 +673,15 @@ class View extends Object { } /** - * Loads a helper. Delegates to the HelperCollection to load the helper + * Loads a helper. Delegates to the `HelperCollection::load()` to load the helper * * @param string $helperName Name of the helper to load. * @param array $settings Settings for the helper * @return Helper a constructed helper object. + * @see HelperCollection::load() */ - public function loadHelper($helperName, $settings = array(), $attach = true) { - return $this->Helpers->load($helperName, $settings, $attach); + public function loadHelper($helperName, $settings = array()) { + return $this->Helpers->load($helperName, $settings); } /** diff --git a/cake/tests/cases/libs/controller/component_collection.test.php b/cake/tests/cases/libs/controller/component_collection.test.php index cb0e83b83..4e38e6938 100644 --- a/cake/tests/cases/libs/controller/component_collection.test.php +++ b/cake/tests/cases/libs/controller/component_collection.test.php @@ -65,7 +65,7 @@ class ComponentCollectionTest extends CakeTestCase { * @return void */ function testLoadWithEnableFalse() { - $result = $this->Components->load('Cookie', array(), false); + $result = $this->Components->load('Cookie', array('callbacks' => false)); $this->assertType('CookieComponent', $result); $this->assertType('CookieComponent', $this->Components->Cookie); From 22497eb41c45c91ff8850a674487094259fd50ea Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 6 Nov 2010 23:57:35 -0400 Subject: [PATCH 032/160] Fixing failing tests in controller test. --- cake/libs/controller/controller.php | 2 +- cake/tests/cases/libs/controller/controller.test.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index a0cd556b9..384220c4b 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -1039,7 +1039,7 @@ class Controller extends Object { ), E_USER_WARNING); return array(); } - $options = array_merge($this->request->params, $this->params['url'], $this->passedArgs); + $options = array_merge($this->request->params, $this->request->params['url'], $this->passedArgs); if (isset($this->paginate[$object->alias])) { $defaults = $this->paginate[$object->alias]; diff --git a/cake/tests/cases/libs/controller/controller.test.php b/cake/tests/cases/libs/controller/controller.test.php index 8bfcbe0d7..ae25b1c48 100644 --- a/cake/tests/cases/libs/controller/controller.test.php +++ b/cake/tests/cases/libs/controller/controller.test.php @@ -759,6 +759,7 @@ class ControllerTest extends CakeTestCase { function testPaginateFieldsDouble(){ $Controller =& new Controller(); $Controller->uses = array('ControllerPost'); + $Controller->request = $this->getMock('CakeRequest'); $Controller->request->params['url'] = array(); $Controller->constructClasses(); From 3216c902cd2bf679673404c12853fdda0f1a51fb Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 7 Nov 2010 00:07:27 -0400 Subject: [PATCH 033/160] Removing the enable parameter on HelperCollection, BehaviorCollection, and ComponentCollection. They all now support the enabled option that Behaviors have historically supported. This provides a simpler API with fewer arguments, and allows callbacks to be disabled on objects in their declared arrays. Test cases updated. --- cake/libs/controller/component.php | 5 ++--- cake/libs/controller/component_collection.php | 6 +++--- cake/libs/model/behavior_collection.php | 7 ++++--- cake/libs/view/helper.php | 5 ++--- cake/libs/view/helper_collection.php | 4 ++-- .../libs/view/helper_collection.test.php | 19 +++---------------- 6 files changed, 16 insertions(+), 30 deletions(-) diff --git a/cake/libs/controller/component.php b/cake/libs/controller/component.php index c426fd8b7..c0d4b57a6 100644 --- a/cake/libs/controller/component.php +++ b/cake/libs/controller/component.php @@ -93,9 +93,8 @@ class Component extends Object { */ public function __get($name) { if (isset($this->_componentMap[$name]) && !isset($this->{$name})) { - $this->{$name} = $this->_Collection->load( - $this->_componentMap[$name]['class'], $this->_componentMap[$name]['settings'], false - ); + $settings = array_merge((array)$this->_componentMap[$name]['settings'], array('enabled' => false)); + $this->{$name} = $this->_Collection->load($this->_componentMap[$name]['class'], $settings); } if (isset($this->{$name})) { return $this->{$name}; diff --git a/cake/libs/controller/component_collection.php b/cake/libs/controller/component_collection.php index af27989b1..90ec17f17 100644 --- a/cake/libs/controller/component_collection.php +++ b/cake/libs/controller/component_collection.php @@ -56,8 +56,8 @@ class ComponentCollection extends ObjectCollection { /** * Loads/constructs a component. Will return the instance in the registry if it already exists. - * You can use `$settings['callbacks'] = false` to disable callbacks on a component when loading it. - * Callbacks default to on. + * You can use `$settings['enabled'] = false` to disable callbacks on a component when loading it. + * Callbacks default to on. Disabled component methods work as normal, only callbacks are disabled. * * @param string $component Component name to load * @param array $settings Settings for the component. @@ -85,7 +85,7 @@ class ComponentCollection extends ObjectCollection { } } $this->_loaded[$name] = new $componentClass($this, $settings); - $enable = isset($settings['callbacks']) ? $settings['callbacks'] : true; + $enable = isset($settings['enabled']) ? $settings['enabled'] : true; if ($enable === true) { $this->_enabled[] = $name; } diff --git a/cake/libs/model/behavior_collection.php b/cake/libs/model/behavior_collection.php index 2df40a978..9820d568b 100644 --- a/cake/libs/model/behavior_collection.php +++ b/cake/libs/model/behavior_collection.php @@ -81,8 +81,9 @@ class BehaviorCollection extends ObjectCollection { } /** - * Loads a behavior into the collection. You can use use `$config['callbacks'] = false` - * to load a behavior with callbacks disabled. By default callbacks are enabled. + * Loads a behavior into the collection. You can use use `$config['enabled'] = false` + * to load a behavior with callbacks disabled. By default callbacks are enabled. Disable behaviors + * can still be used as normal. * * @param string $behavior CamelCased name of the behavior to load * @param array $config Behavior configuration parameters @@ -150,7 +151,7 @@ class BehaviorCollection extends ObjectCollection { } } - $configDisabled = isset($config['callbacks']) && $config['callbacks'] === false; + $configDisabled = isset($config['enabled']) && $config['enabled'] === false; if (!in_array($name, $this->_enabled) && !$configDisabled) { $this->enable($name); } elseif ($configDisabled) { diff --git a/cake/libs/view/helper.php b/cake/libs/view/helper.php index 2b0be4091..68466a25f 100644 --- a/cake/libs/view/helper.php +++ b/cake/libs/view/helper.php @@ -140,9 +140,8 @@ class Helper extends Object { */ public function __get($name) { if (isset($this->_helperMap[$name]) && !isset($this->{$name})) { - $this->{$name} = $this->_View->loadHelper( - $this->_helperMap[$name]['class'], $this->_helperMap[$name]['settings'], false - ); + $settings = array_merge((array)$this->_helperMap[$name]['settings'], array('enabled' => false)); + $this->{$name} = $this->_View->loadHelper($this->_helperMap[$name]['class'], $settings); } if (isset($this->{$name})) { return $this->{$name}; diff --git a/cake/libs/view/helper_collection.php b/cake/libs/view/helper_collection.php index 61567c811..18b700812 100644 --- a/cake/libs/view/helper_collection.php +++ b/cake/libs/view/helper_collection.php @@ -39,7 +39,7 @@ class HelperCollection extends ObjectCollection { /** * Loads/constructs a helper. Will return the instance in the registry if it already exists. * By setting `$enable` to false you can disable callbacks for a helper. Alternatively you - * can set `$settings['callbacks'] = false` to disable callbacks. This alias is provided so that when + * can set `$settings['enabled'] = false` to disable callbacks. This alias is provided so that when * declaring $helpers arrays you can disable callbacks on helpers. * * @param string $helper Helper name to load @@ -74,7 +74,7 @@ class HelperCollection extends ObjectCollection { foreach ($vars as $var) { $this->_loaded[$name]->{$var} = $this->_View->{$var}; } - $enable = isset($settings['callbacks']) ? $settings['callbacks'] : false; + $enable = isset($settings['enabled']) ? $settings['enabled'] : true; if ($enable === true) { $this->_enabled[] = $name; } diff --git a/cake/tests/cases/libs/view/helper_collection.test.php b/cake/tests/cases/libs/view/helper_collection.test.php index 5d6dda543..8d60f0109 100644 --- a/cake/tests/cases/libs/view/helper_collection.test.php +++ b/cake/tests/cases/libs/view/helper_collection.test.php @@ -58,25 +58,12 @@ class HelperCollectionTest extends CakeTestCase { } /** - * test load and enable = false + * test that the enabled setting disables the helper. * * @return void */ - function testLoadWithEnableFalse() { - $result = $this->Helpers->load('Html', array(), false); - $this->assertType('HtmlHelper', $result); - $this->assertType('HtmlHelper', $this->Helpers->Html); - - $this->assertFalse($this->Helpers->enabled('Html'), 'Html should be disabled'); - } - -/** - * test that the callbacks setting disables the helper. - * - * @return void - */ - function testLoadWithCallbacksFalse() { - $result = $this->Helpers->load('Html', array('callbacks' => false)); + function testLoadWithEnabledFalse() { + $result = $this->Helpers->load('Html', array('enabled' => false)); $this->assertType('HtmlHelper', $result); $this->assertType('HtmlHelper', $this->Helpers->Html); From e431e86aa4301ced4273dc7919b59362cbb353cb Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 7 Nov 2010 20:53:04 -0500 Subject: [PATCH 034/160] 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 035/160] 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 a9a9bc0e2eb5054e91a7d115ba03f5951bc94867 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 7 Nov 2010 23:48:14 -0500 Subject: [PATCH 036/160] Removing bogus crud in the test. --- cake/tests/cases/libs/view/view.test.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index 88c821be7..965aa0251 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -499,9 +499,7 @@ class ViewTest extends CakeTestCase { function testElementCacheHelperNoCache() { $Controller = new ViewPostsController(); $View = new TestView($Controller); - $empty = array(); - $helpers = $View->loadHelpers($empty, array('cache')); - $View->loaded = $helpers; + $helpers = $View->loadHelpers(); $result = $View->element('test_element', array('ram' => 'val', 'test' => array('foo', 'bar'))); $this->assertEqual($result, 'this is the test element'); } From dfefc2d97bcba274924d64f41d93283b02590bf5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 8 Nov 2010 00:05:44 -0500 Subject: [PATCH 037/160] Very initial pass at getting elements cached with Cache. Refs #1268 --- cake/libs/view/view.php | 33 ++++++++++++------------ cake/tests/cases/libs/view/view.test.php | 18 ++++++++++++- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index c3343af5f..6487997a4 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -325,23 +325,22 @@ class View extends Object { } if (isset($params['cache'])) { - $expires = '+1 day'; - if (is_array($params['cache'])) { - $expires = $params['cache']['time']; - $key = Inflector::slug($params['cache']['key']); - } elseif ($params['cache'] !== true) { - $expires = $params['cache']; - $key = implode('_', array_keys($params)); + $defaults = array( + 'config' => 'default', + 'key' => '', + ); + $caching = array_merge($defaults, $params['cache']); + } else { + $caching = array( + 'config' => 'default', + 'key' => implode('_', array_keys($params)) + ); } - - if ($expires) { - $cacheFile = 'element_' . $key . '_' . $plugin . Inflector::slug($name); - $cache = cache('views' . DS . $cacheFile, null, $expires); - - if (is_string($cache)) { - return $cache; - } + $key = 'element_' . $caching['key'] . '_' . $plugin . Inflector::slug($name); + $contents = Cache::read($key, $caching['config']); + if ($contents !== false) { + return $contents; } } $paths = $this->_paths($plugin); @@ -364,8 +363,8 @@ class View extends Object { if ($callbacks) { $this->Helpers->trigger('afterRender', array($file, $element)); } - if (isset($params['cache']) && isset($cacheFile) && isset($expires)) { - cache('views' . DS . $cacheFile, $element, $expires); + if (isset($params['cache'])) { + Cache::write($key, $element, $caching['config']); } return $element; } diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index 965aa0251..a8fdc6948 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -511,6 +511,22 @@ class ViewTest extends CakeTestCase { * @return void */ function testElementCache() { + Cache::drop('test_view'); + Cache::config('test_view', array( + 'engine' => 'File', + 'duration' => '+1 day', + 'path' => CACHE . 'views' . DS + )); + + $View = new TestView($this->PostsController); + $result = $View->element('test_element', array('cache' => array('config' => 'test_view'))); + $expected = 'this is the test element'; + $this->assertEquals($expected, $result); + + $result = Cache::read('element__test_element', 'test_view'); + $this->assertEquals($expected, $result); + +/* $writable = is_writable(CACHE . 'views' . DS); if ($this->skipIf(!$writable, 'CACHE/views dir is not writable, cannot test elementCache. %s')) { return; @@ -553,7 +569,7 @@ class ViewTest extends CakeTestCase { } $this->assertTrue($cached); $this->assertEqual($result, $expected); - + */ } /** From e8678b38acc898f0756fdf8875d6661c3020b87f Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 8 Nov 2010 21:50:45 -0500 Subject: [PATCH 038/160] 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 1cf5e720548f3956d6689ee42aad73d893ea90ca Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 9 Nov 2010 22:16:45 -0500 Subject: [PATCH 039/160] Removing duplicated calls to slug() Extracting getElementFilename() into a method, this should allow developers to more easily replace how elements are found. Refs #1268 --- cake/libs/view/view.php | 62 ++++++++++++++-------- cake/tests/cases/libs/view/view.test.php | 67 ++++++++---------------- 2 files changed, 62 insertions(+), 67 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 6487997a4..10b3c686c 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -240,6 +240,16 @@ class View extends Object { */ public $request; +/** + * The Cache configuration View will use to store cached elements. Changing this will change + * the default configuration elements are stored under. You can also choose a cache config + * per element. + * + * @var string + * @see View::element() + */ + public $elementCache = 'default'; + /** * List of variables to collect from the associated controller * @@ -300,10 +310,10 @@ class View extends Object { * * ### Special params * - * - `cache` - enable caching for this element accepts boolean or strtotime compatible string. - * Can also be an array. If `cache` is an array, - * `time` is used to specify duration of cache. - * `key` can be used to create unique cache files. + * - `cache` - Can either be `true`, to enable caching using the config in View::$elementCache. Or an array + * If an array, the following keys can be used: + * - `config` - Used to store the cached element in a custom cache configuration. + * - `key` - Used to define the key used in the Cache::write(). It will be prefixed with `element_` * - `plugin` - Load an element from a specific plugin. * * @param string $name Name of template file in the/app/views/elements/ folder @@ -319,7 +329,6 @@ class View extends Object { if (isset($params['plugin'])) { $plugin = $params['plugin']; } - if (isset($this->plugin) && !$plugin) { $plugin = $this->plugin; } @@ -327,32 +336,26 @@ class View extends Object { if (isset($params['cache'])) { if (is_array($params['cache'])) { $defaults = array( - 'config' => 'default', - 'key' => '', + 'config' => $this->elementCache, + 'key' => $plugin . '_' . $name, ); $caching = array_merge($defaults, $params['cache']); } else { + $keys = array_merge(array($plugin, $name), array_keys($params)); $caching = array( - 'config' => 'default', - 'key' => implode('_', array_keys($params)) + 'config' => $this->elementCache, + 'key' => implode('_', $keys) ); } - $key = 'element_' . $caching['key'] . '_' . $plugin . Inflector::slug($name); + $key = 'element_' . $caching['key']; $contents = Cache::read($key, $caching['config']); if ($contents !== false) { return $contents; } } - $paths = $this->_paths($plugin); + $file = $this->_getElementFilename($name, $plugin); - foreach ($paths as $path) { - if (file_exists($path . 'elements' . DS . $name . $this->ext)) { - $file = $path . 'elements' . DS . $name . $this->ext; - break; - } - } - - if (is_file($file)) { + if ($file) { if (!$this->_helpersLoaded) { $this->loadHelpers(); } @@ -368,10 +371,10 @@ class View extends Object { } return $element; } - $file = $paths[0] . 'elements' . DS . $name . $this->ext; + $file = 'elements' . DS . $name . $this->ext; if (Configure::read('debug') > 0) { - return "Not Found: " . $file; + return "Element Not Found: " . $file; } } @@ -778,6 +781,23 @@ class View extends Object { throw new MissingLayoutException(array('file' => $paths[0] . $file . $this->ext)); } +/** + * Finds an element filename, returns false on failure. + * + * @param string $name The name of the element to find. + * @param string $plugin The plugin name the element is in. + * @return mixed Either a string to the element filename or false when one can't be found. + */ + protected function _getElementFileName($name, $plugin = null) { + $paths = $this->_paths($plugin); + foreach ($paths as $path) { + if (file_exists($path . 'elements' . DS . $name . $this->ext)) { + return $path . 'elements' . DS . $name . $this->ext; + } + } + return false; + } + /** * Return all possible paths to find view files in order * diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index a8fdc6948..54072c5b3 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -515,61 +515,36 @@ class ViewTest extends CakeTestCase { Cache::config('test_view', array( 'engine' => 'File', 'duration' => '+1 day', - 'path' => CACHE . 'views' . DS + 'path' => CACHE . 'views' . DS, + 'prefix' => '' )); + Cache::clear('test_view'); $View = new TestView($this->PostsController); - $result = $View->element('test_element', array('cache' => array('config' => 'test_view'))); + $View->elementCache = 'test_view'; + + $result = $View->element('test_element', array('cache' => true)); $expected = 'this is the test element'; $this->assertEquals($expected, $result); - $result = Cache::read('element__test_element', 'test_view'); + $result = Cache::read('element_test_element_cache', 'test_view'); + $this->assertEquals($expected, $result); + + $result = $View->element('test_element', array('cache' => true, 'param' => 'one', 'foo' => 'two')); $this->assertEquals($expected, $result); -/* - $writable = is_writable(CACHE . 'views' . DS); - if ($this->skipIf(!$writable, 'CACHE/views dir is not writable, cannot test elementCache. %s')) { - return; - } - $View = new TestView($this->PostsController); - $element = 'test_element'; - $expected = 'this is the test element'; - $result = $View->element($element); - $this->assertEqual($result, $expected); + $result = Cache::read('element_test_element_cache_param_foo', 'test_view'); + $this->assertEquals($expected, $result); + + $result = $View->element('test_element', array( + 'cache' => array('key' => 'custom_key'), + 'param' => 'one', + 'foo' => 'two' + )); + $result = Cache::read('element_custom_key', 'test_view'); + $this->assertEquals($expected, $result); - $cached = false; - $result = $View->element($element, array('cache'=>'+1 second')); - if (file_exists(CACHE . 'views' . DS . 'element_cache_'.$element)) { - $cached = true; - unlink(CACHE . 'views' . DS . 'element_cache_'.$element); - } - $this->assertTrue($cached); - - $cached = false; - $result = $View->element($element, array('cache'=>'+1 second', 'other_param'=> true, 'anotherParam'=> true)); - if (file_exists(CACHE . 'views' . DS . 'element_cache_other_param_anotherParam_'.$element)) { - $cached = true; - unlink(CACHE . 'views' . DS . 'element_cache_other_param_anotherParam_'.$element); - } - $this->assertTrue($cached); - - $cached = false; - $result = $View->element($element, array('cache'=>array('time'=>'+1 second', 'key'=>'/whatever/here'))); - if (file_exists(CACHE . 'views' . DS . 'element_'.Inflector::slug('/whatever/here').'_'.$element)) { - $cached = true; - unlink(CACHE . 'views' . DS . 'element_'.Inflector::slug('/whatever/here').'_'.$element); - } - $this->assertTrue($cached); - - $cached = false; - $result = $View->element($element, array('cache'=>array('time'=>'+1 second', 'key'=>'whatever_here'))); - if (file_exists(CACHE . 'views' . DS . 'element_whatever_here_'.$element)) { - $cached = true; - unlink(CACHE . 'views' . DS . 'element_whatever_here_'.$element); - } - $this->assertTrue($cached); - $this->assertEqual($result, $expected); - */ + Cache::drop('test_view'); } /** From 7ad406808584e181d8db5d9c14b936dea796ee9d Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 9 Nov 2010 22:27:36 -0500 Subject: [PATCH 040/160] Refactoring to remove some duplication. --- cake/libs/view/view.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 10b3c686c..819830a4d 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -334,18 +334,17 @@ class View extends Object { } if (isset($params['cache'])) { + $keys = array_merge(array($plugin, $name), array_keys($params)); + $caching = array( + 'config' => $this->elementCache, + 'key' => implode('_', $keys) + ); if (is_array($params['cache'])) { $defaults = array( 'config' => $this->elementCache, - 'key' => $plugin . '_' . $name, + 'key' => $caching['key'] ); $caching = array_merge($defaults, $params['cache']); - } else { - $keys = array_merge(array($plugin, $name), array_keys($params)); - $caching = array( - 'config' => $this->elementCache, - 'key' => implode('_', $keys) - ); } $key = 'element_' . $caching['key']; $contents = Cache::read($key, $caching['config']); From 1f5999f38861f4b54c738b34700812753f049c03 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 9 Nov 2010 22:31:05 -0500 Subject: [PATCH 041/160] Adding some tests for element caching. --- cake/tests/cases/libs/view/view.test.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index 54072c5b3..6533ddba0 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -527,13 +527,13 @@ class ViewTest extends CakeTestCase { $expected = 'this is the test element'; $this->assertEquals($expected, $result); - $result = Cache::read('element_test_element_cache', 'test_view'); + $result = Cache::read('element__test_element_cache', 'test_view'); $this->assertEquals($expected, $result); $result = $View->element('test_element', array('cache' => true, 'param' => 'one', 'foo' => 'two')); $this->assertEquals($expected, $result); - $result = Cache::read('element_test_element_cache_param_foo', 'test_view'); + $result = Cache::read('element__test_element_cache_param_foo', 'test_view'); $this->assertEquals($expected, $result); $result = $View->element('test_element', array( @@ -543,6 +543,15 @@ class ViewTest extends CakeTestCase { )); $result = Cache::read('element_custom_key', 'test_view'); $this->assertEquals($expected, $result); + + $View->elementCache = 'default'; + $result = $View->element('test_element', array( + 'cache' => array('config' => 'test_view'), + 'param' => 'one', + 'foo' => 'two' + )); + $result = Cache::read('element__test_element_cache_param_foo', 'test_view'); + $this->assertEquals($expected, $result); Cache::drop('test_view'); } From ee0dc785b20c19c3ece9a9bf747856f4139cdbe9 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 9 Nov 2010 22:37:02 -0500 Subject: [PATCH 042/160] Removing cache comment stripping, they are harmless in html/xml. --- cake/libs/view/view.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 819830a4d..c7ff4de67 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -413,15 +413,6 @@ class View extends Object { } if ($layout && $this->autoLayout) { $this->output = $this->renderLayout($this->output, $layout); - $isCached = ( - isset($this->Helpers->Cache) || - Configure::read('Cache.check') === true - ); - - if ($isCached) { - $replace = array('', ''); - $this->output = str_replace($replace, '', $this->output); - } } $this->hasRendered = true; return $this->output; From 6c0dfe95926aafaa05ad4533562e9fb40007c73a Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 9 Nov 2010 23:40:15 -0500 Subject: [PATCH 043/160] Fixing error where params[url] has moved. --- .../controller/components/request_handler.php | 4 ++-- cake/libs/controller/controller.php | 2 +- .../cases/libs/controller/controller.test.php | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cake/libs/controller/components/request_handler.php b/cake/libs/controller/components/request_handler.php index 93f11814a..b68e5e33e 100644 --- a/cake/libs/controller/components/request_handler.php +++ b/cake/libs/controller/components/request_handler.php @@ -121,8 +121,8 @@ class RequestHandlerComponent extends Component { public function initialize(&$controller, $settings = array()) { $this->request = $controller->request; $this->response = $controller->response; - if (isset($controller->params['url']['ext'])) { - $this->ext = $controller->params['url']['ext']; + if (isset($this->request->params['url']['ext'])) { + $this->ext = $this->request->params['url']['ext']; } if (empty($this->ext)) { $accepts = $this->request->accepts(); diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 384220c4b..ee9065b6d 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -1039,7 +1039,7 @@ class Controller extends Object { ), E_USER_WARNING); return array(); } - $options = array_merge($this->request->params, $this->request->params['url'], $this->passedArgs); + $options = array_merge($this->request->params, $this->request->query, $this->passedArgs); if (isset($this->paginate[$object->alias])) { $defaults = $this->paginate[$object->alias]; diff --git a/cake/tests/cases/libs/controller/controller.test.php b/cake/tests/cases/libs/controller/controller.test.php index ae25b1c48..345ba8440 100644 --- a/cake/tests/cases/libs/controller/controller.test.php +++ b/cake/tests/cases/libs/controller/controller.test.php @@ -610,7 +610,7 @@ class ControllerTest extends CakeTestCase { $Controller = new Controller($request); $Controller->uses = array('ControllerPost', 'ControllerComment'); $Controller->passedArgs[] = '1'; - $Controller->params['url'] = array(); + $Controller->query = array(); $Controller->constructClasses(); $results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id'); @@ -700,7 +700,7 @@ class ControllerTest extends CakeTestCase { $Controller->uses = array('ControllerPost', 'ControllerComment'); $Controller->passedArgs[] = '1'; - $Controller->params['url'] = array(); + $Controller->query = array(); $Controller->constructClasses(); $Controller->passedArgs = array('page' => '-1', 'contain' => array('ControllerComment')); @@ -731,7 +731,7 @@ class ControllerTest extends CakeTestCase { $Controller = new Controller($request); $Controller->uses = array('ControllerPaginateModel'); - $Controller->params['url'] = array(); + $Controller->query = array(); $Controller->constructClasses(); $Controller->paginate = array( 'ControllerPaginateModel' => array('contain' => array('ControllerPaginateModel'), 'group' => 'Comment.author_id') @@ -760,7 +760,7 @@ class ControllerTest extends CakeTestCase { $Controller =& new Controller(); $Controller->uses = array('ControllerPost'); $Controller->request = $this->getMock('CakeRequest'); - $Controller->request->params['url'] = array(); + $Controller->request->query = array(); $Controller->constructClasses(); $Controller->paginate = array( @@ -801,7 +801,7 @@ class ControllerTest extends CakeTestCase { $Controller = new Controller($request); $Controller->uses = array('ControllerPost'); $Controller->passedArgs[] = array('1', '2', '3'); - $Controller->params['url'] = array(); + $Controller->query = array(); $Controller->constructClasses(); $Controller->paginate = array( @@ -837,7 +837,7 @@ class ControllerTest extends CakeTestCase { $Controller = new Controller($request); $Controller->uses = array('ControllerPost', 'ControllerComment'); $Controller->passedArgs[] = '1'; - $Controller->params['url'] = array(); + $Controller->query = array(); $Controller->constructClasses(); $Controller->paginate = array('ControllerPost' => array('popular', 'fields' => array('id', 'title'))); @@ -861,7 +861,7 @@ class ControllerTest extends CakeTestCase { $Controller = new Controller($request); $Controller->modelClass = 'ControllerPost'; - $Controller->params['url'] = array(); + $Controller->query = array(); $Controller->paginate = array('order' => 'ControllerPost.id DESC'); $Controller->constructClasses(); $results = Set::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id'); @@ -881,7 +881,7 @@ class ControllerTest extends CakeTestCase { $Controller = new Controller($request); $Controller->uses = array('ControllerPost', 'ControllerComment'); - $Controller->params['url'] = array(); + $Controller->query = array(); $Controller->constructClasses(); $Controller->ControllerPost->virtualFields = array( 'offset_test' => 'ControllerPost.id + 1' @@ -1499,7 +1499,7 @@ class ControllerTest extends CakeTestCase { $Controller->components = array("RequestHandler"); $Controller->modelClass='ControllerPost'; - $Controller->params['url'] = array('ext' => 'rss'); + $Controller->request->params['url'] = array('ext' => 'rss'); $Controller->constructClasses(); $Controller->Components->trigger('initialize', array(&$Controller)); $Controller->beforeFilter(); From 76c3e1a1120bed8c72155e3a218e34ab202afb0b Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 9 Nov 2010 23:55:30 -0500 Subject: [PATCH 044/160] Adding cache comment stripping to the CacheHelper, it was recently removed from View, and needed to be added here to fix failing tests. --- cake/libs/view/helpers/cache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/cake/libs/view/helpers/cache.php b/cake/libs/view/helpers/cache.php index 196fbf4e1..6a1c430ea 100644 --- a/cake/libs/view/helpers/cache.php +++ b/cake/libs/view/helpers/cache.php @@ -68,6 +68,7 @@ class CacheHelper extends AppHelper { if ($caching) { $this->cache($layoutFile, $this->_View->output, true); } + $this->_View->output = preg_replace('//', '', $this->_View->output); } /** From b297bf633d671f2f89bf06a7aef5e2699be13bea Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 9 Nov 2010 23:55:42 -0500 Subject: [PATCH 045/160] Updating test to be correct. --- .../cases/libs/controller/components/request_handler.test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/tests/cases/libs/controller/components/request_handler.test.php b/cake/tests/cases/libs/controller/components/request_handler.test.php index d58ca6688..a9fe81d81 100644 --- a/cake/tests/cases/libs/controller/components/request_handler.test.php +++ b/cake/tests/cases/libs/controller/components/request_handler.test.php @@ -277,7 +277,7 @@ class RequestHandlerComponentTest extends CakeTestCase { $this->assertEquals($this->Controller->layout, $this->RequestHandler->ajaxLayout); $this->_init(); - $this->Controller->request->query['ext'] = 'js'; + $this->Controller->request->params['url']['ext'] = 'js'; $this->RequestHandler->initialize($this->Controller); $this->RequestHandler->startup($this->Controller); $this->assertNotEqual($this->Controller->layout, 'ajax'); From a1467822fbb50d4b524e2a98560ff74783f8af70 Mon Sep 17 00:00:00 2001 From: Mariano Iglesias Date: Wed, 10 Nov 2010 15:35:00 -0300 Subject: [PATCH 046/160] 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 f4b0ec1d20aa2bdc5384e250b82e8356b17739f8 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 10 Nov 2010 23:40:56 -0500 Subject: [PATCH 047/160] Updating E_STRICT issues in view test. Removing dead methods and classes. --- cake/tests/cases/libs/view/view.test.php | 41 ++---------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index 6533ddba0..a4edb8ca2 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -71,25 +71,6 @@ class ViewPostsController extends Controller { } } -/** - * ViewTestErrorHandler class - * - * @package cake - * @subpackage cake.tests.cases.libs.view - */ -class ViewTestErrorHandler extends ErrorHandler { - -/** - * stop method - * - * @access public - * @return void - */ - function _stop() { - return; - } -} - /** * TestView class * @@ -146,24 +127,10 @@ class TestView extends View { return $this->_render($___viewFn, $___dataForView, $loadHelpers, $cached); } -/** - * cakeError method - * - * @param mixed $method - * @param mixed $messages - * @access public - * @return void - */ - function cakeError($method, $messages) { - $error = new ViewTestErrorHandler($method, $messages); - return $error; - } - /** * Test only function to return instance scripts. * * @return array Scripts - * @access public */ function scripts() { return $this->_scripts; @@ -182,7 +149,6 @@ class TestAfterHelper extends Helper { * property property * * @var string '' - * @access public */ public $property = ''; @@ -192,7 +158,7 @@ class TestAfterHelper extends Helper { * @access public * @return void */ - function beforeLayout() { + function beforeLayout($viewFile) { $this->property = 'Valuation'; } @@ -202,9 +168,8 @@ class TestAfterHelper extends Helper { * @access public * @return void */ - function afterLayout() { - $View = ClassRegistry::getObject('afterView'); - $View->output .= 'modified in the afterlife'; + function afterLayout($layoutFile) { + $this->_View->output .= 'modified in the afterlife'; } } From 4e3b62e466df9eaeec881833cd4e45b5e34f7756 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 10 Nov 2010 23:43:48 -0500 Subject: [PATCH 048/160] Removing vestigial method in App. Fixing E_STRICT error in Router. --- cake/libs/configure.php | 14 -------------- cake/libs/router.php | 3 +-- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/cake/libs/configure.php b/cake/libs/configure.php index ff8af76cd..7f962632a 100644 --- a/cake/libs/configure.php +++ b/cake/libs/configure.php @@ -863,8 +863,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); } @@ -904,7 +902,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); @@ -1046,17 +1043,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. diff --git a/cake/libs/router.php b/cake/libs/router.php index 70190bb4e..b51f02134 100644 --- a/cake/libs/router.php +++ b/cake/libs/router.php @@ -886,10 +886,9 @@ class Router { * * @param array $url A url that didn't match any routes * @return string A generated url for the array - * @access protected * @see Router::url() */ - function _handleNoRoute($url) { + protected static function _handleNoRoute($url) { $named = $args = array(); $skip = array_merge( array('bare', 'action', 'controller', 'plugin', 'prefix'), From ec2884f17cc905ba36875c063810775f45fd99ed Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 10 Nov 2010 23:50:01 -0500 Subject: [PATCH 049/160] Making routing suite include RedirectRoute. --- cake/tests/cases/libs/all_routing.test.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cake/tests/cases/libs/all_routing.test.php b/cake/tests/cases/libs/all_routing.test.php index 1f60002fc..a6a010bbb 100644 --- a/cake/tests/cases/libs/all_routing.test.php +++ b/cake/tests/cases/libs/all_routing.test.php @@ -34,12 +34,11 @@ class AllRoutingTest extends PHPUnit_Framework_TestSuite { * @return void */ public static function suite() { - $suite = new PHPUnit_Framework_TestSuite('All Router and Dispatcher class tests'); + $suite = new CakeTestSuite('All Router and Dispatcher class tests'); $suite->addTestFile(CORE_TEST_CASES . DS . 'dispatcher.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'router.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'route' . DS . 'cake_route.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'route' . DS . 'plugin_short_route.test.php'); + $suite->addTestDirectory(CORE_TEST_CASES . DS . 'libs' . DS . 'route' . DS); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_response.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_request.test.php'); return $suite; From d044cdd02f554a0517c5173e3e412efd91c28c27 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 22:50:15 -0500 Subject: [PATCH 050/160] Fixing test case that was missing request access. --- cake/tests/cases/libs/view/helpers/paginator.test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/paginator.test.php b/cake/tests/cases/libs/view/helpers/paginator.test.php index a2af0a5c5..3a3e81895 100644 --- a/cake/tests/cases/libs/view/helpers/paginator.test.php +++ b/cake/tests/cases/libs/view/helpers/paginator.test.php @@ -1574,7 +1574,7 @@ class PaginatorHelperTest extends CakeTestCase { ); $this->assertTags($result, $expected); - $this->Paginator->params['paging']['Client']['page'] = 3; + $this->Paginator->request->params['paging']['Client']['page'] = 3; $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2, 'separator' => ' - ', 'ellipsis' => ' ~~~ ')); $expected = array( array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span', @@ -1591,7 +1591,7 @@ class PaginatorHelperTest extends CakeTestCase { ); $this->assertTags($result, $expected); - $this->Paginator->params['paging']['Client']['page'] = 3; + $this->Paginator->request->params['paging']['Client']['page'] = 3; $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2, 'separator' => ' - ', 'ellipsis' => '...')); $expected = array( array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span', From 85e072a64b653c3d02653d4654bf9a3e4cde8f6d Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 22:51:53 -0500 Subject: [PATCH 051/160] Removing reference operators in view class constructors. --- cake/libs/view/theme.php | 2 +- cake/libs/view/view.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/libs/view/theme.php b/cake/libs/view/theme.php index 5e52c99c4..80e56ae42 100644 --- a/cake/libs/view/theme.php +++ b/cake/libs/view/theme.php @@ -38,7 +38,7 @@ class ThemeView extends View { * * @param Controller $controller Controller object to be rendered. */ - function __construct(&$controller) { + function __construct($controller) { parent::__construct($controller); $this->theme = $controller->theme; } diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index c7ff4de67..3db73cf3d 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -289,7 +289,7 @@ class View extends Object { * * @param Controller $controller A controller object to pull View::__passedArgs from. */ - function __construct(&$controller) { + function __construct($controller) { if (is_object($controller)) { $count = count($this->__passedVars); for ($j = 0; $j < $count; $j++) { From 47fa4713b1428c2d81e23d499ae009202b07606d Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 22:53:40 -0500 Subject: [PATCH 052/160] Pulling ScaffoldView into a separate file. --- cake/libs/controller/scaffold.php | 76 +------------------------- cake/libs/view/scaffold.php | 89 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 75 deletions(-) create mode 100644 cake/libs/view/scaffold.php diff --git a/cake/libs/controller/scaffold.php b/cake/libs/controller/scaffold.php index 6bf6246a5..581d788c0 100644 --- a/cake/libs/controller/scaffold.php +++ b/cake/libs/controller/scaffold.php @@ -19,6 +19,7 @@ * @since Cake v 0.10.0.1076 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::import('View', 'Scaffold'); /** * Scaffolding is a set of automatic actions for starting web development work faster. @@ -455,78 +456,3 @@ class Scaffold { return $associations; } } - -/** - * Scaffold View. - * - * @package cake - * @subpackage cake.cake.libs.controller -*/ -App::import('View', 'Theme'); - -/** - * ScaffoldView provides specific view file loading features for scaffolded views. - * - * @package cake.libs.view - */ -class ScaffoldView extends ThemeView { - -/** - * Override _getViewFileName Appends special scaffolding views in. - * - * @param string $name name of the view file to get. - * @return string action - */ - protected function _getViewFileName($name = null) { - if ($name === null) { - $name = $this->action; - } - $name = Inflector::underscore($name); - $prefixes = Configure::read('Routing.prefixes'); - - if (!empty($prefixes)) { - foreach ($prefixes as $prefix) { - if (strpos($name, $prefix . '_') !== false) { - $name = substr($name, strlen($prefix) + 1); - break; - } - } - } - - if ($name === 'add') { - $name = 'edit'; - } - - $scaffoldAction = 'scaffold.' . $name; - - if (!is_null($this->subDir)) { - $subDir = strtolower($this->subDir) . DS; - } else { - $subDir = null; - } - - $names[] = $this->viewPath . DS . $subDir . $scaffoldAction; - $names[] = 'scaffolds' . DS . $subDir . $name; - - $paths = $this->_paths($this->plugin); - $exts = array($this->ext); - if ($this->ext !== '.ctp') { - array_push($exts, '.ctp'); - } - foreach ($exts as $ext) { - foreach ($paths as $path) { - foreach ($names as $name) { - if (file_exists($path . $name . $ext)) { - return $path . $name . $ext; - } - } - } - } - - if ($name === 'scaffolds' . DS . $subDir . 'error') { - return LIBS . 'view' . DS . 'errors' . DS . 'scaffold_error.ctp'; - } - - throw new MissingViewException($paths[0] . $name . $this->ext); - } -} diff --git a/cake/libs/view/scaffold.php b/cake/libs/view/scaffold.php new file mode 100644 index 000000000..032676985 --- /dev/null +++ b/cake/libs/view/scaffold.php @@ -0,0 +1,89 @@ +action; + } + $name = Inflector::underscore($name); + $prefixes = Configure::read('Routing.prefixes'); + + if (!empty($prefixes)) { + foreach ($prefixes as $prefix) { + if (strpos($name, $prefix . '_') !== false) { + $name = substr($name, strlen($prefix) + 1); + break; + } + } + } + + if ($name === 'add') { + $name = 'edit'; + } + + $scaffoldAction = 'scaffold.' . $name; + + if (!is_null($this->subDir)) { + $subDir = strtolower($this->subDir) . DS; + } else { + $subDir = null; + } + + $names[] = $this->viewPath . DS . $subDir . $scaffoldAction; + $names[] = 'scaffolds' . DS . $subDir . $name; + + $paths = $this->_paths($this->plugin); + $exts = array($this->ext); + if ($this->ext !== '.ctp') { + array_push($exts, '.ctp'); + } + foreach ($exts as $ext) { + foreach ($paths as $path) { + foreach ($names as $name) { + if (file_exists($path . $name . $ext)) { + return $path . $name . $ext; + } + } + } + } + + if ($name === 'scaffolds' . DS . $subDir . 'error') { + return LIBS . 'view' . DS . 'errors' . DS . 'scaffold_error.ctp'; + } + + throw new MissingViewException($paths[0] . $name . $this->ext); + } +} From 18bb5f6b8b9d8f98fdbc42d652637430c8ee867b Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 23:05:44 -0500 Subject: [PATCH 053/160] Removing =& operators for construction of objects. --- cake/console/shells/acl.php | 2 +- cake/console/shells/console.php | 8 ++++---- cake/console/shells/schema.php | 18 +++++++++--------- cake/console/shells/tasks/controller.php | 2 +- cake/console/shells/tasks/fixture.php | 4 ++-- cake/console/shells/tasks/model.php | 8 ++++---- cake/console/shells/tasks/plugin.php | 4 ++-- cake/console/shells/tasks/template.php | 6 +++--- cake/console/shells/tasks/test.php | 6 +++--- cake/console/shells/tasks/view.php | 4 ++-- .../console/templates/default/classes/test.ctp | 2 +- cake/libs/cache/memcache.php | 2 +- cake/libs/controller/components/acl.php | 4 ++-- cake/libs/controller/components/auth.php | 2 +- cake/libs/controller/controller.php | 2 +- cake/libs/file.php | 2 +- cake/libs/http_socket.php | 4 ++-- cake/libs/magic_db.php | 6 +++--- cake/libs/model/behaviors/containable.php | 4 ++-- cake/libs/model/behaviors/translate.php | 6 +++--- cake/libs/model/datasources/dbo_source.php | 2 +- cake/libs/view/helpers/cache.php | 2 +- cake/tests/cases/console/libs/shell.test.php | 2 +- .../tests/cases/console/shells/schema.test.php | 4 ++-- .../cases/console/shells/tasks/test.test.php | 2 +- cake/tests/cases/libs/cache/file.test.php | 4 ++-- cake/tests/cases/libs/cache/memcache.test.php | 10 +++++----- cake/tests/cases/libs/cake_request.test.php | 2 +- .../cases/libs/controller/component.test.php | 2 +- .../libs/controller/components/email.test.php | 2 +- .../cases/libs/controller/controller.test.php | 6 +++--- .../controller/controller_merge_vars.test.php | 10 +++++----- .../cases/libs/controller/scaffold.test.php | 2 +- cake/tests/cases/libs/file.test.php | 2 +- cake/tests/cases/libs/l10n.test.php | 8 ++++---- cake/tests/cases/libs/log/file_log.test.php | 4 ++-- cake/tests/cases/libs/magic_db.test.php | 2 +- .../libs/model/behaviors/containable.test.php | 2 +- .../cases/libs/model/cake_schema.test.php | 10 +++++----- .../model/datasources/dbo/dbo_mysql.test.php | 10 +++++----- .../model/datasources/dbo/dbo_mysqli.test.php | 2 +- .../model/datasources/dbo/dbo_oracle.test.php | 2 +- .../datasources/dbo/dbo_postgres.test.php | 6 +++--- .../libs/model/datasources/dbo_source.test.php | 6 +++--- cake/tests/cases/libs/model/db_acl.test.php | 12 ++++++------ .../cases/libs/model/model_delete.test.php | 4 ++-- .../tests/cases/libs/model/model_read.test.php | 10 +++++----- .../cases/libs/model/model_validation.test.php | 16 ++++++++-------- .../cases/libs/model/model_write.test.php | 8 ++++---- cake/tests/cases/libs/object.test.php | 2 +- .../tests/cases/libs/route/cake_route.test.php | 2 +- cake/tests/cases/libs/sanitize.test.php | 4 ++-- .../cases/libs/view/helpers/html.test.php | 2 +- cake/tests/cases/libs/view/view.test.php | 4 ++-- cake/tests/lib/templates/footer.php | 2 +- 55 files changed, 133 insertions(+), 133 deletions(-) diff --git a/cake/console/shells/acl.php b/cake/console/shells/acl.php index 169bd14d2..2ffaa4609 100644 --- a/cake/console/shells/acl.php +++ b/cake/console/shells/acl.php @@ -94,7 +94,7 @@ class AclShell extends Shell { if (!in_array($this->command, array('initdb'))) { $collection = new ComponentCollection(); - $this->Acl =& new AclComponent($collection); + $this->Acl = new AclComponent($collection); $controller = null; $this->Acl->startup($controller); } diff --git a/cake/console/shells/console.php b/cake/console/shells/console.php index 6e635d238..20ab1615d 100644 --- a/cake/console/shells/console.php +++ b/cake/console/shells/console.php @@ -61,7 +61,7 @@ class ConsoleShell extends Shell { foreach ($this->models as $model) { $class = Inflector::camelize(str_replace('.php', '', $model)); $this->models[$model] = $class; - $this->{$class} =& new $class(); + $this->{$class} = new $class(); } $this->out('Model classes:'); $this->out('--------------'); @@ -290,7 +290,7 @@ class ConsoleShell extends Shell { } break; case (preg_match("/^routes\s+reload/i", $command, $tmp) == true): - $router =& Router::getInstance(); + $router = Router::getInstance(); if (!$this->_loadRoutes()) { $this->out("There was an error loading the routes config. Please check that the file"); $this->out("exists and is free of parse errors."); @@ -299,7 +299,7 @@ class ConsoleShell extends Shell { $this->out("Routes configuration reloaded, " . count($router->routes) . " routes connected"); break; case (preg_match("/^routes\s+show/i", $command, $tmp) == true): - $router =& Router::getInstance(); + $router = Router::getInstance(); $this->out(implode("\n", Set::extract($router->routes, '{n}.0'))); break; case (preg_match("/^route\s+(\(.*\))$/i", $command, $tmp) == true): @@ -335,7 +335,7 @@ class ConsoleShell extends Shell { * @return boolean True if config reload was a success, otherwise false */ protected function _loadRoutes() { - $router =& Router::getInstance(); + $router = Router::getInstance(); $router->reload(); extract($router->getNamedExpressions()); diff --git a/cake/console/shells/schema.php b/cake/console/shells/schema.php index 612e57e45..dc863f6e5 100644 --- a/cake/console/shells/schema.php +++ b/cake/console/shells/schema.php @@ -99,7 +99,7 @@ class SchemaShell extends Shell { $name = $plugin; } } - $this->Schema =& new CakeSchema(compact('name', 'path', 'file', 'connection', 'plugin')); + $this->Schema = new CakeSchema(compact('name', 'path', 'file', 'connection', 'plugin')); } /** @@ -151,7 +151,7 @@ class SchemaShell extends Shell { $content['file'] = $this->params['file']; if ($snapshot === true) { - $Folder =& new Folder($this->Schema->path); + $Folder = new Folder($this->Schema->path); $result = $Folder->read(); $numToUse = false; @@ -209,7 +209,7 @@ class SchemaShell extends Shell { $write = $this->params['write']; } } - $db =& ConnectionManager::getDataSource($this->Schema->connection); + $db = ConnectionManager::getDataSource($this->Schema->connection); $contents = "#" . $Schema->name . " sql generated on: " . date('Y-m-d H:i:s') . " : " . time() . "\n\n"; $contents .= $db->dropSchema($Schema) . "\n\n". $db->createSchema($Schema); @@ -218,9 +218,9 @@ class SchemaShell extends Shell { $write .= '.sql'; } if (strpos($write, DS) !== false) { - $File =& new File($write, true); + $File = new File($write, true); } else { - $File =& new File($this->Schema->path . DS . $write, true); + $File = new File($this->Schema->path . DS . $write, true); } if ($File->write($contents)) { @@ -280,7 +280,7 @@ class SchemaShell extends Shell { $options['file'] = $fileName . '_' . $this->params['snapshot'] . '.php'; } - $Schema =& $this->Schema->load($options); + $Schema = $this->Schema->load($options); if (!$Schema) { $this->err(sprintf(__('%s could not be loaded'), $this->Schema->path . DS . $this->Schema->file)); @@ -300,7 +300,7 @@ class SchemaShell extends Shell { * @access private */ function __create(&$Schema, $table = null) { - $db =& ConnectionManager::getDataSource($this->Schema->connection); + $db = ConnectionManager::getDataSource($this->Schema->connection); $drop = $create = array(); @@ -343,7 +343,7 @@ class SchemaShell extends Shell { * @access private */ function __update(&$Schema, $table = null) { - $db =& ConnectionManager::getDataSource($this->Schema->connection); + $db = ConnectionManager::getDataSource($this->Schema->connection); $this->out(__('Comparing Database to Schema...')); $options = array(); @@ -390,7 +390,7 @@ class SchemaShell extends Shell { return; } Configure::write('debug', 2); - $db =& ConnectionManager::getDataSource($this->Schema->connection); + $db = ConnectionManager::getDataSource($this->Schema->connection); foreach ($contents as $table => $sql) { if (empty($sql)) { diff --git a/cake/console/shells/tasks/controller.php b/cake/console/shells/tasks/controller.php index 2d7433936..e88dc2059 100644 --- a/cake/console/shells/tasks/controller.php +++ b/cake/console/shells/tasks/controller.php @@ -278,7 +278,7 @@ class ControllerTask extends BakeTask { $this->_stop(); } - $modelObj =& ClassRegistry::init($currentModelName); + $modelObj = ClassRegistry::init($currentModelName); $controllerPath = $this->_controllerPath($controllerName); $pluralName = $this->_pluralName($currentModelName); $singularName = Inflector::variable($currentModelName); diff --git a/cake/console/shells/tasks/fixture.php b/cake/console/shells/tasks/fixture.php index d26144549..1313ab1dd 100644 --- a/cake/console/shells/tasks/fixture.php +++ b/cake/console/shells/tasks/fixture.php @@ -394,12 +394,12 @@ class FixtureTask extends BakeTask { $condition = 'WHERE 1=1 LIMIT ' . (isset($this->params['count']) ? $this->params['count'] : 10); } App::import('Model', 'Model', false); - $modelObject =& new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection)); + $modelObject = new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection)); $records = $modelObject->find('all', array( 'conditions' => $condition, 'recursive' => -1 )); - $db =& ConnectionManager::getDataSource($modelObject->useDbConfig); + $db = ConnectionManager::getDataSource($modelObject->useDbConfig); $schema = $modelObject->schema(true); $out = array(); foreach ($records as $record) { diff --git a/cake/console/shells/tasks/model.php b/cake/console/shells/tasks/model.php index 6bc7c5c6a..7e8de3e36 100644 --- a/cake/console/shells/tasks/model.php +++ b/cake/console/shells/tasks/model.php @@ -131,7 +131,7 @@ class ModelTask extends BakeTask { if (!$table) { $table = Inflector::tableize($className); } - $object =& new Model(array('name' => $className, 'table' => $table, 'ds' => $this->connection)); + $object = new Model(array('name' => $className, 'table' => $table, 'ds' => $this->connection)); return $object; } @@ -180,7 +180,7 @@ class ModelTask extends BakeTask { } $currentModelName = $this->getName(); $useTable = $this->getTable($currentModelName); - $db =& ConnectionManager::getDataSource($this->connection); + $db = ConnectionManager::getDataSource($this->connection); $fullTableName = $db->fullTableName($useTable); if (in_array($useTable, $this->_tables)) { @@ -793,7 +793,7 @@ class ModelTask extends BakeTask { } App::import('Model', 'ConnectionManager', false); - $db =& ConnectionManager::getDataSource($useDbConfig); + $db = ConnectionManager::getDataSource($useDbConfig); $useTable = Inflector::tableize($modelName); $fullTableName = $db->fullTableName($useTable, false); $tableIsGood = false; @@ -823,7 +823,7 @@ class ModelTask extends BakeTask { App::import('Model', 'ConnectionManager', false); $tables = array(); - $db =& ConnectionManager::getDataSource($useDbConfig); + $db = ConnectionManager::getDataSource($useDbConfig); $db->cacheSources = false; $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix']; if ($usePrefix) { diff --git a/cake/console/shells/tasks/plugin.php b/cake/console/shells/tasks/plugin.php index 4fca522dc..de0d4713a 100644 --- a/cake/console/shells/tasks/plugin.php +++ b/cake/console/shells/tasks/plugin.php @@ -104,7 +104,7 @@ class PluginTask extends Shell { $looksGood = $this->in(__('Look okay?'), array('y', 'n', 'q'), 'y'); if (strtolower($looksGood) == 'y') { - $Folder =& new Folder($this->path . $pluginPath); + $Folder = new Folder($this->path . $pluginPath); $directories = array( 'config' . DS . 'schema', 'models' . DS . 'behaviors', @@ -127,7 +127,7 @@ class PluginTask extends Shell { foreach ($directories as $directory) { $dirPath = $this->path . $pluginPath . DS . $directory; $Folder->create($dirPath); - $File =& new File($dirPath . DS . 'empty', true); + $File = new File($dirPath . DS . 'empty', true); } foreach ($Folder->messages() as $message) { diff --git a/cake/console/shells/tasks/template.php b/cake/console/shells/tasks/template.php index b9e267087..be892c87c 100644 --- a/cake/console/shells/tasks/template.php +++ b/cake/console/shells/tasks/template.php @@ -59,7 +59,7 @@ class TemplateTask extends Shell { $separator = DS === '/' ? '/' : '\\\\'; $core = preg_replace('#shells' . $separator . '$#', '', $core); $paths[] = $core; - $Folder =& new Folder($core . 'templates' . DS . 'default'); + $Folder = new Folder($core . 'templates' . DS . 'default'); $contents = $Folder->read(); $themeFolders = $contents[0]; @@ -76,14 +76,14 @@ class TemplateTask extends Shell { $themes = array(); foreach ($paths as $path) { - $Folder =& new Folder($path . 'templates', false); + $Folder = new Folder($path . 'templates', false); $contents = $Folder->read(); $subDirs = $contents[0]; foreach ($subDirs as $dir) { if (empty($dir) || preg_match('@^skel$|_skel$@', $dir)) { continue; } - $Folder =& new Folder($path . 'templates' . DS . $dir); + $Folder = new Folder($path . 'templates' . DS . $dir); $contents = $Folder->read(); $subDirs = $contents[0]; if (array_intersect($contents[0], $themeFolders)) { diff --git a/cake/console/shells/tasks/test.php b/cake/console/shells/tasks/test.php index ce300f058..eca2aab95 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..')); - $testSubject =& $this->buildTestSubject($type, $className); + $testSubject = $this->buildTestSubject($type, $className); $this->generateFixtureList($testSubject); } elseif ($this->interactive) { $this->getUserFixtures(); @@ -228,9 +228,9 @@ class TestTask extends BakeTask { App::import($type, $class); $class = $this->getRealClassName($type, $class); if (strtolower($type) == 'model') { - $instance =& ClassRegistry::init($class); + $instance = ClassRegistry::init($class); } else { - $instance =& new $class(); + $instance = new $class(); } return $instance; } diff --git a/cake/console/shells/tasks/view.php b/cake/console/shells/tasks/view.php index c166a003d..2acbfdeaa 100644 --- a/cake/console/shells/tasks/view.php +++ b/cake/console/shells/tasks/view.php @@ -282,11 +282,11 @@ class ViewTask extends BakeTask { $this->_stop(); } $controllerClassName = $this->controllerName . 'Controller'; - $controllerObj =& new $controllerClassName(); + $controllerObj = new $controllerClassName(); $controllerObj->plugin = $this->plugin; $controllerObj->constructClasses(); $modelClass = $controllerObj->modelClass; - $modelObj =& $controllerObj->{$controllerObj->modelClass}; + $modelObj = $controllerObj->{$controllerObj->modelClass}; if ($modelObj) { $primaryKey = $modelObj->primaryKey; diff --git a/cake/console/templates/default/classes/test.ctp b/cake/console/templates/default/classes/test.ctp index af78691b2..5811e8446 100644 --- a/cake/console/templates/default/classes/test.ctp +++ b/cake/console/templates/default/classes/test.ctp @@ -39,7 +39,7 @@ class TestCase extends CakeTestCase { public function startTest() { - $this-> + $this-> } public function endTest() { diff --git a/cake/libs/cache/memcache.php b/cake/libs/cache/memcache.php index 7314fca0b..b478a75d0 100644 --- a/cake/libs/cache/memcache.php +++ b/cake/libs/cache/memcache.php @@ -78,7 +78,7 @@ class MemcacheEngine extends CacheEngine { } if (!isset($this->__Memcache)) { $return = false; - $this->__Memcache =& new Memcache(); + $this->__Memcache = new Memcache(); foreach ($this->settings['servers'] as $server) { list($host, $port) = $this->_parseServerString($server); if ($this->__Memcache->addServer($host, $port)) { diff --git a/cake/libs/controller/components/acl.php b/cake/libs/controller/components/acl.php index d8e42b583..49fc77aa3 100644 --- a/cake/libs/controller/components/acl.php +++ b/cake/libs/controller/components/acl.php @@ -280,8 +280,8 @@ class DbAcl extends Object implements AclInterface { * @return void */ public function initialize($component) { - $component->Aro =& $this->Aro; - $component->Aco =& $this->Aco; + $component->Aro = $this->Aro; + $component->Aco = $this->Aco; } /** diff --git a/cake/libs/controller/components/auth.php b/cake/libs/controller/components/auth.php index 07675353a..993cecf44 100644 --- a/cake/libs/controller/components/auth.php +++ b/cake/libs/controller/components/auth.php @@ -322,7 +322,7 @@ class AuthComponent extends Component { if (!$this->__setDefaults()) { return false; } - $request =& $controller->request; + $request = $controller->request; $this->request->data = $controller->request->data = $this->hashPasswords($request->data); $url = ''; diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 5e6469dc7..775618240 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -627,7 +627,7 @@ class Controller extends Object { if ($this->persistModel === true) { $this->_persist($modelClass, true, $this->{$modelClass}); - $registry =& ClassRegistry::getInstance(); + $registry = ClassRegistry::getInstance(); $this->_persist($modelClass . 'registry', true, $registry->__objects, 'registry'); } } else { diff --git a/cake/libs/file.php b/cake/libs/file.php index fbd305082..663004840 100644 --- a/cake/libs/file.php +++ b/cake/libs/file.php @@ -93,7 +93,7 @@ class File { * @access private */ function __construct($path, $create = false, $mode = 0755) { - $this->Folder =& new Folder(dirname($path), $create, $mode); + $this->Folder = new Folder(dirname($path), $create, $mode); if (!is_dir($path)) { $this->name = basename($path); } diff --git a/cake/libs/http_socket.php b/cake/libs/http_socket.php index 9848446c4..91b18d4d2 100644 --- a/cake/libs/http_socket.php +++ b/cake/libs/http_socket.php @@ -146,12 +146,12 @@ class HttpSocket extends CakeSocket { * You can use a url string to set the url and use default configurations for * all other options: * - * `$http =& new HttpSockect('http://cakephp.org/');` + * `$http = new HttpSockect('http://cakephp.org/');` * * Or use an array to configure multiple options: * * {{{ - * $http =& new HttpSocket(array( + * $http = new HttpSocket(array( * 'host' => 'cakephp.org', * 'timeout' => 20 * )); diff --git a/cake/libs/magic_db.php b/cake/libs/magic_db.php index eca8b1af8..1a3143b4e 100644 --- a/cake/libs/magic_db.php +++ b/cake/libs/magic_db.php @@ -53,7 +53,7 @@ class MagicDb extends Object { if (is_array($magicDb) || strpos($magicDb, '# FILE_ID DB') === 0) { $data = $magicDb; } else { - $File =& new File($magicDb); + $File = new File($magicDb); if (!$File->exists()) { return false; } @@ -155,7 +155,7 @@ class MagicDb extends Object { } $matches = array(); - $MagicFileResource =& new MagicFileResource($file); + $MagicFileResource = new MagicFileResource($file); foreach ($this->db['database'] as $format) { $magic = $format[0]; $match = $MagicFileResource->test($magic); @@ -201,7 +201,7 @@ class MagicFileResource extends Object{ */ public function __construct($file) { if (file_exists($file)) { - $this->resource =& new File($file); + $this->resource = new File($file); } else { $this->resource = $file; } diff --git a/cake/libs/model/behaviors/containable.php b/cake/libs/model/behaviors/containable.php index 870a29375..8e4f87ab2 100644 --- a/cake/libs/model/behaviors/containable.php +++ b/cake/libs/model/behaviors/containable.php @@ -121,7 +121,7 @@ class ContainableBehavior extends ModelBehavior { $mandatory = array(); foreach ($containments['models'] as $name => $model) { - $instance =& $model['instance']; + $instance = $model['instance']; $needed = $this->fieldDependencies($instance, $map, false); if (!empty($needed)) { $mandatory = array_merge($mandatory, $needed); @@ -431,7 +431,7 @@ class ContainableBehavior extends ModelBehavior { public function containmentsMap($containments) { $map = array(); foreach ($containments['models'] as $name => $model) { - $instance =& $model['instance']; + $instance = $model['instance']; foreach ($this->types as $type) { foreach ($instance->{$type} as $assoc => $options) { if (isset($model['keep'][$assoc])) { diff --git a/cake/libs/model/behaviors/translate.php b/cake/libs/model/behaviors/translate.php index 99f4004e9..9e5a3c799 100644 --- a/cake/libs/model/behaviors/translate.php +++ b/cake/libs/model/behaviors/translate.php @@ -52,7 +52,7 @@ class TranslateBehavior extends ModelBehavior { * @return mixed */ public function setup(&$model, $config = array()) { - $db =& ConnectionManager::getDataSource($model->useDbConfig); + $db = ConnectionManager::getDataSource($model->useDbConfig); if (!$db->connected) { trigger_error( sprintf(__('Datasource %s for TranslateBehavior of model %s is not connected'), $model->useDbConfig, $model->alias), @@ -91,8 +91,8 @@ class TranslateBehavior extends ModelBehavior { if (empty($locale)) { return $query; } - $db =& ConnectionManager::getDataSource($model->useDbConfig); - $RuntimeModel =& $this->translateModel($model); + $db = ConnectionManager::getDataSource($model->useDbConfig); + $RuntimeModel = $this->translateModel($model); if (!empty($RuntimeModel->tablePrefix)) { $tablePrefix = $RuntimeModel->tablePrefix; } else { diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 4e8ad2a2e..cb5e8d4be 100755 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -612,7 +612,7 @@ class DboSource extends DataSource { if (PHP_SAPI != 'cli') { App::import('Core', 'View'); $controller = null; - $View =& new View($controller, false); + $View = new View($controller, false); $View->set('logs', array($this->configKeyName => $log)); echo $View->element('sql_dump', array('_forced_from_dbo_' => true)); } else { diff --git a/cake/libs/view/helpers/cache.php b/cake/libs/view/helpers/cache.php index fc0f6bff5..a4718b166 100644 --- a/cake/libs/view/helpers/cache.php +++ b/cake/libs/view/helpers/cache.php @@ -223,7 +223,7 @@ class CacheHelper extends AppHelper { '; } - $file .= '$controller =& new ' . $this->controllerName . 'Controller(); + $file .= '$controller = new ' . $this->controllerName . 'Controller(); $controller->plugin = $this->plugin = \''.$this->plugin.'\'; $controller->helpers = $this->helpers = unserialize(\'' . serialize($this->helpers) . '\'); $controller->base = $this->base = \'' . $this->base . '\'; diff --git a/cake/tests/cases/console/libs/shell.test.php b/cake/tests/cases/console/libs/shell.test.php index f76d07623..51a3479d3 100644 --- a/cake/tests/cases/console/libs/shell.test.php +++ b/cake/tests/cases/console/libs/shell.test.php @@ -119,7 +119,7 @@ class ShellTest extends CakeTestCase { $output = $this->getMock('ConsoleOutput', array(), array(), '', false); $error = $this->getMock('ConsoleOutput', array(), array(), '', false); $in = $this->getMock('ConsoleInput', array(), array(), '', false); - $this->Shell =& new TestShell($output, $error, $in); + $this->Shell = new TestShell($output, $error, $in); } /** diff --git a/cake/tests/cases/console/shells/schema.test.php b/cake/tests/cases/console/shells/schema.test.php index 5fd76e63d..611928e53 100644 --- a/cake/tests/cases/console/shells/schema.test.php +++ b/cake/tests/cases/console/shells/schema.test.php @@ -220,7 +220,7 @@ class SchemaShellTest extends CakeTestCase { $this->Shell->startup(); $this->Shell->dump(); - $this->file =& new File(TMP . 'tests' . DS . 'i18n.sql'); + $this->file = new File(TMP . 'tests' . DS . 'i18n.sql'); $contents = $this->file->read(); $this->assertPattern('/DROP TABLE/', $contents); $this->assertPattern('/CREATE TABLE `i18n`/', $contents); @@ -250,7 +250,7 @@ class SchemaShellTest extends CakeTestCase { $this->Shell->expects($this->once())->method('_stop'); $this->Shell->dump(); - $this->file =& new File(TMP . 'tests' . DS . 'dump_test.sql'); + $this->file = new File(TMP . 'tests' . DS . 'dump_test.sql'); $contents = $this->file->read(); $this->assertPattern('/CREATE TABLE `test_plugin_acos`/', $contents); diff --git a/cake/tests/cases/console/shells/tasks/test.test.php b/cake/tests/cases/console/shells/tasks/test.test.php index d8fa87ead..484838eb4 100644 --- a/cake/tests/cases/console/shells/tasks/test.test.php +++ b/cake/tests/cases/console/shells/tasks/test.test.php @@ -479,7 +479,7 @@ class TestTaskTest extends CakeTestCase { $this->assertContains('function redirect($url, $status = null, $exit = true)', $result); $this->assertContains('function startTest()', $result); - $this->assertContains("\$this->TestTaskComments =& new TestTestTaskCommentsController()", $result); + $this->assertContains("\$this->TestTaskComments = new TestTestTaskCommentsController()", $result); $this->assertContains("\$this->TestTaskComments->constructClasses()", $result); $this->assertContains('function endTest()', $result); diff --git a/cake/tests/cases/libs/cache/file.test.php b/cake/tests/cases/libs/cache/file.test.php index 56dfcf340..33361f040 100644 --- a/cake/tests/cases/libs/cache/file.test.php +++ b/cake/tests/cases/libs/cache/file.test.php @@ -280,12 +280,12 @@ class FileEngineTest extends CakeTestCase { * @return void */ function testClearWithPrefixes() { - $FileOne =& new FileEngine(); + $FileOne = new FileEngine(); $FileOne->init(array( 'prefix' => 'prefix_one_', 'duration' => DAY )); - $FileTwo =& new FileEngine(); + $FileTwo = new FileEngine(); $FileTwo->init(array( 'prefix' => 'prefix_two_', 'duration' => DAY diff --git a/cake/tests/cases/libs/cache/memcache.test.php b/cake/tests/cases/libs/cache/memcache.test.php index 7b55ceee2..0eb11e71a 100644 --- a/cake/tests/cases/libs/cache/memcache.test.php +++ b/cake/tests/cases/libs/cache/memcache.test.php @@ -101,7 +101,7 @@ class MemcacheEngineTest extends CakeTestCase { function testMultipleServers() { $servers = array('127.0.0.1:11211', '127.0.0.1:11222'); $available = true; - $Memcache =& new Memcache(); + $Memcache = new Memcache(); foreach($servers as $server) { list($host, $port) = explode(':', $server); @@ -113,7 +113,7 @@ class MemcacheEngineTest extends CakeTestCase { if ($this->skipIf(!$available, '%s Need memcache servers at ' . implode(', ', $servers) . ' to run this test')) { return; } - $Memcache =& new MemcacheEngine(); + $Memcache = new MemcacheEngine(); $Memcache->init(array('engine' => 'Memcache', 'servers' => $servers)); $servers = array_keys($Memcache->__Memcache->getExtendedStats()); @@ -129,7 +129,7 @@ class MemcacheEngineTest extends CakeTestCase { * @return void */ function testConnect() { - $Memcache =& new MemcacheEngine(); + $Memcache = new MemcacheEngine(); $Memcache->init(Cache::settings('memcache')); $result = $Memcache->connect('127.0.0.1'); $this->assertTrue($result); @@ -141,7 +141,7 @@ class MemcacheEngineTest extends CakeTestCase { * @return void */ function testConnectIpv6() { - $Memcache =& new MemcacheEngine(); + $Memcache = new MemcacheEngine(); $result = $Memcache->init(array( 'prefix' => 'cake_', 'duration' => 200, @@ -159,7 +159,7 @@ class MemcacheEngineTest extends CakeTestCase { * @return void */ function testParseServerStringNonLatin() { - $Memcache =& new TestMemcacheEngine(); + $Memcache = new TestMemcacheEngine(); $result = $Memcache->parseServerString('schülervz.net:13211'); $this->assertEqual($result, array('schülervz.net', '13211')); diff --git a/cake/tests/cases/libs/cake_request.test.php b/cake/tests/cases/libs/cake_request.test.php index f452631c1..c9892e62b 100644 --- a/cake/tests/cases/libs/cake_request.test.php +++ b/cake/tests/cases/libs/cake_request.test.php @@ -967,7 +967,7 @@ class CakeRequestTestCase extends CakeTestCase { * @return void */ public function testEnvironmentDetection() { - $dispatcher =& new Dispatcher(); + $dispatcher = new Dispatcher(); $environments = array( 'IIS' => array( diff --git a/cake/tests/cases/libs/controller/component.test.php b/cake/tests/cases/libs/controller/component.test.php index a48da4b2a..923e86868 100644 --- a/cake/tests/cases/libs/controller/component.test.php +++ b/cake/tests/cases/libs/controller/component.test.php @@ -406,7 +406,7 @@ class ComponentTest extends CakeTestCase { return; } - $Controller =& new ComponentTestController(); + $Controller = new ComponentTestController(); $Controller->uses = false; $Controller->components = array('Session'); $Controller->constructClasses(); diff --git a/cake/tests/cases/libs/controller/components/email.test.php b/cake/tests/cases/libs/controller/components/email.test.php index f3dcce8bb..f8fd2e4a5 100755 --- a/cake/tests/cases/libs/controller/components/email.test.php +++ b/cake/tests/cases/libs/controller/components/email.test.php @@ -363,7 +363,7 @@ TEMPDOC; return; } - $connection =& new CakeSocket(array('protocol'=>'smtp', 'host' => 'localhost', 'port' => 25)); + $connection = new CakeSocket(array('protocol'=>'smtp', 'host' => 'localhost', 'port' => 25)); $this->Controller->EmailTest->setConnectionSocket($connection); $this->Controller->EmailTest->smtpOptions['timeout'] = 10; $this->assertTrue($connection->connect()); diff --git a/cake/tests/cases/libs/controller/controller.test.php b/cake/tests/cases/libs/controller/controller.test.php index 8bfcbe0d7..489db1fa9 100644 --- a/cake/tests/cases/libs/controller/controller.test.php +++ b/cake/tests/cases/libs/controller/controller.test.php @@ -757,7 +757,7 @@ class ControllerTest extends CakeTestCase { * @access public */ function testPaginateFieldsDouble(){ - $Controller =& new Controller(); + $Controller = new Controller(); $Controller->uses = array('ControllerPost'); $Controller->request->params['url'] = array(); $Controller->constructClasses(); @@ -1042,7 +1042,7 @@ class ControllerTest extends CakeTestCase { $core[0] ) ), true); - $Controller =& new Controller($this->getMock('CakeRequest')); + $Controller = new Controller($this->getMock('CakeRequest')); $Controller->uses = array(); $Controller->components = array('Test'); $Controller->constructClasses(); @@ -1406,7 +1406,7 @@ class ControllerTest extends CakeTestCase { * @return void */ function testValidateErrorsOnArbitraryModels() { - $TestController =& new TestController(); + $TestController = new TestController(); $Post = new ControllerPost(); $Post->validate = array('title' => 'notEmpty'); 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 2838bd7af..c09392908 100644 --- a/cake/tests/cases/libs/controller/controller_merge_vars.test.php +++ b/cake/tests/cases/libs/controller/controller_merge_vars.test.php @@ -145,7 +145,7 @@ class ControllerMergeVarsTest extends CakeTestCase { function testComponentParamMergingNoDuplication() { $this->skipIf(defined('APP_CONTROLLER_EXISTS'), "APP_CONTROLLER_EXISTS cannot run {$this->name}"); - $Controller =& new MergeVariablesController(); + $Controller = new MergeVariablesController(); $Controller->constructClasses(); $expected = array('MergeVar' => array('flag', 'otherFlag', 'redirect' => false)); @@ -160,7 +160,7 @@ class ControllerMergeVarsTest extends CakeTestCase { function testComponentMergingWithRedeclarations() { $this->skipIf(defined('APP_CONTROLLER_EXISTS'), "APP_CONTROLLER_EXISTS cannot run {$this->name}"); - $Controller =& new MergeVariablesController(); + $Controller = new MergeVariablesController(); $Controller->components['MergeVar'] = array('remote', 'redirect' => true); $Controller->constructClasses(); @@ -176,7 +176,7 @@ class ControllerMergeVarsTest extends CakeTestCase { function testHelperSettingMergingNoDuplication() { $this->skipIf(defined('APP_CONTROLLER_EXISTS'), "APP_CONTROLLER_EXISTS cannot run {$this->name}"); - $Controller =& new MergeVariablesController(); + $Controller = new MergeVariablesController(); $Controller->constructClasses(); $expected = array('MergeVar' => array('format' => 'html', 'terse')); @@ -191,7 +191,7 @@ class ControllerMergeVarsTest extends CakeTestCase { function testMergeVarsWithPlugin() { $this->skipIf(defined('APP_CONTROLLER_EXISTS'), "APP_CONTROLLER_EXISTS cannot run {$this->name}"); - $Controller =& new MergePostsController(); + $Controller = new MergePostsController(); $Controller->components = array('Email' => array('ports' => 'open')); $Controller->plugin = 'MergeVarPlugin'; $Controller->constructClasses(); @@ -209,7 +209,7 @@ class ControllerMergeVarsTest extends CakeTestCase { ); $this->assertEqual($Controller->helpers, $expected, 'Helpers are unexpected %s'); - $Controller =& new MergePostsController(); + $Controller = new MergePostsController(); $Controller->components = array(); $Controller->plugin = 'MergeVarPlugin'; $Controller->constructClasses(); diff --git a/cake/tests/cases/libs/controller/scaffold.test.php b/cake/tests/cases/libs/controller/scaffold.test.php index 4d42d9c47..415ac6ce2 100644 --- a/cake/tests/cases/libs/controller/scaffold.test.php +++ b/cake/tests/cases/libs/controller/scaffold.test.php @@ -784,7 +784,7 @@ class ScaffoldTest extends CakeTestCase { $this->Controller->theme = 'test_theme'; $this->Controller->view = 'Theme'; $this->Controller->constructClasses(); - $Scaffold =& new TestScaffoldMock($this->Controller, $this->Controller->request); + $Scaffold = new TestScaffoldMock($this->Controller, $this->Controller->request); $this->assertEqual($this->Controller->view, 'Scaffold'); } diff --git a/cake/tests/cases/libs/file.test.php b/cake/tests/cases/libs/file.test.php index 00dd79910..f0e71a10d 100644 --- a/cake/tests/cases/libs/file.test.php +++ b/cake/tests/cases/libs/file.test.php @@ -126,7 +126,7 @@ class FileTest extends CakeTestCase { */ function testRead() { $file = __FILE__; - $this->File =& new File($file); + $this->File = new File($file); $result = $this->File->read(); $expecting = file_get_contents(__FILE__); diff --git a/cake/tests/cases/libs/l10n.test.php b/cake/tests/cases/libs/l10n.test.php index 9375ed7d6..a1b35aee1 100644 --- a/cake/tests/cases/libs/l10n.test.php +++ b/cake/tests/cases/libs/l10n.test.php @@ -34,7 +34,7 @@ class L10nTest extends CakeTestCase { * @return void */ function testGet() { - $l10n =& new L10n(); + $l10n = new L10n(); // Catalog Entry $l10n->get('en'); @@ -90,7 +90,7 @@ class L10nTest extends CakeTestCase { $__SERVER = $_SERVER; $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'inexistent,en-ca'; - $l10n =& new L10n(); + $l10n = new L10n(); $l10n->get(); $this->assertEqual($l10n->language, 'English (Canadian)'); @@ -121,7 +121,7 @@ class L10nTest extends CakeTestCase { * @return void */ function testMap() { - $l10n =& new L10n(); + $l10n = new L10n(); $result = $l10n->map(array('afr', 'af')); $expected = array('afr' => 'af', 'af' => 'afr'); @@ -451,7 +451,7 @@ class L10nTest extends CakeTestCase { * @return void */ function testCatalog() { - $l10n =& new L10n(); + $l10n = new L10n(); $result = $l10n->catalog(array('af')); $expected = array( diff --git a/cake/tests/cases/libs/log/file_log.test.php b/cake/tests/cases/libs/log/file_log.test.php index a43ca9041..f07ab9771 100644 --- a/cake/tests/cases/libs/log/file_log.test.php +++ b/cake/tests/cases/libs/log/file_log.test.php @@ -35,7 +35,7 @@ class FileLogTest extends CakeTestCase { */ function testLogFileWriting() { @unlink(LOGS . 'error.log'); - $log =& new FileLog(); + $log = new FileLog(); $log->write('warning', 'Test warning'); $this->assertTrue(file_exists(LOGS . 'error.log')); @@ -69,7 +69,7 @@ class FileLogTest extends CakeTestCase { $path = TMP . 'tests' . DS; @unlink($path . 'error.log'); - $log =& new FileLog(compact('path')); + $log = new FileLog(compact('path')); $log->write('warning', 'Test warning'); $this->assertTrue(file_exists($path . 'error.log')); unlink($path . 'error.log'); diff --git a/cake/tests/cases/libs/magic_db.test.php b/cake/tests/cases/libs/magic_db.test.php index 4ba5c1ef1..e871a541d 100644 --- a/cake/tests/cases/libs/magic_db.test.php +++ b/cake/tests/cases/libs/magic_db.test.php @@ -39,7 +39,7 @@ class MagicDbTest extends UnitTestCase { * */ public function setUp() { - $this->Db =& new MagicDb(); + $this->Db = new MagicDb(); } /** * MagicDb::analyze should properly detect the file type and output additional info as requested. diff --git a/cake/tests/cases/libs/model/behaviors/containable.test.php b/cake/tests/cases/libs/model/behaviors/containable.test.php index 6ff304262..10ea65fb5 100644 --- a/cake/tests/cases/libs/model/behaviors/containable.test.php +++ b/cake/tests/cases/libs/model/behaviors/containable.test.php @@ -3189,7 +3189,7 @@ class ContainableBehaviorTest extends CakeTestCase { * @return void */ function testPaginate() { - $Controller =& new Controller(); + $Controller = new Controller(); $Controller->uses = array('Article'); $Controller->passedArgs[] = '1'; $Controller->params['url'] = array(); diff --git a/cake/tests/cases/libs/model/cake_schema.test.php b/cake/tests/cases/libs/model/cake_schema.test.php index 5750054f5..1eb8e7228 100644 --- a/cake/tests/cases/libs/model/cake_schema.test.php +++ b/cake/tests/cases/libs/model/cake_schema.test.php @@ -614,7 +614,7 @@ class CakeSchemaTest extends CakeTestCase { function testSchemaReadWithTablePrefix() { $model =& new SchemaPrefixAuthUser(); - $Schema =& new CakeSchema(); + $Schema = new CakeSchema(); $read = $Schema->read(array( 'connection' => 'test', 'name' => 'TestApp', @@ -650,7 +650,7 @@ class CakeSchemaTest extends CakeTestCase { 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS) )); - $Schema =& new CakeSchema(); + $Schema = new CakeSchema(); $Schema->plugin = 'TestPlugin'; $read = $Schema->read(array( 'connection' => 'test', @@ -832,13 +832,13 @@ class CakeSchemaTest extends CakeTestCase { * @return void */ function testCompareEmptyStringAndNull() { - $One =& new CakeSchema(array( + $One = new CakeSchema(array( 'posts' => array( 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'), 'name' => array('type' => 'string', 'null' => false, 'default' => '') ) )); - $Two =& new CakeSchema(array( + $Two = new CakeSchema(array( 'posts' => array( 'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'), 'name' => array('type' => 'string', 'null' => false, 'default' => null) @@ -984,7 +984,7 @@ class CakeSchemaTest extends CakeTestCase { $db =& ConnectionManager::getDataSource('test'); $db->cacheSources = false; - $Schema =& new CakeSchema(array( + $Schema = new CakeSchema(array( 'connection' => 'test', 'testdescribes' => array( 'id' => array('type' => 'integer', 'key' => 'primary'), 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 82ac17c23..25b10af5f 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 @@ -696,7 +696,7 @@ class DboMysqlTest extends CakeTestCase { * @return void */ function testAlteringTwoTables() { - $schema1 =& new CakeSchema(array( + $schema1 = new CakeSchema(array( 'name' => 'AlterTest1', 'connection' => 'test', 'altertest' => array( @@ -708,7 +708,7 @@ class DboMysqlTest extends CakeTestCase { 'name' => array('type' => 'string', 'null' => false, 'length' => 50), ) )); - $schema2 =& new CakeSchema(array( + $schema2 = new CakeSchema(array( 'name' => 'AlterTest1', 'connection' => 'test', 'altertest' => array( @@ -792,7 +792,7 @@ class DboMysqlTest extends CakeTestCase { * @return void */ function testVirtualFieldSeparators() { - $model =& new CakeTestModel(array('table' => 'binary_tests', 'ds' => 'test', 'name' => 'BinaryTest')); + $model = new CakeTestModel(array('table' => 'binary_tests', 'ds' => 'test', 'name' => 'BinaryTest')); $model->virtualFields = array( 'other__field' => 'SUM(id)' ); @@ -809,7 +809,7 @@ class DboMysqlTest extends CakeTestCase { * @return void */ function testDescribeGettingFieldParameters() { - $schema =& new CakeSchema(array( + $schema = new CakeSchema(array( 'connection' => 'test', 'testdescribes' => array( 'id' => array('type' => 'integer', 'key' => 'primary'), @@ -829,7 +829,7 @@ class DboMysqlTest extends CakeTestCase { )); $this->db->execute($this->db->createSchema($schema)); - $model =& new CakeTestModel(array('table' => 'testdescribes', 'name' => 'Testdescribes')); + $model = new CakeTestModel(array('table' => 'testdescribes', 'name' => 'Testdescribes')); $result = $this->db->describe($model); $this->assertEqual($result['stringy']['collate'], 'cp1250_general_ci'); $this->assertEqual($result['stringy']['charset'], 'cp1250'); 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 3a162f9ee..82591a8b1 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 @@ -295,7 +295,7 @@ class DboMysqliTest extends CakeTestCase { * @return void */ function testFloatParsing() { - $model =& new Model(array('ds' => 'test', 'table' => 'datatypes', 'name' => 'Datatype')); + $model = new Model(array('ds' => 'test', 'table' => 'datatypes', 'name' => 'Datatype')); $result = $this->Dbo->describe($model); $this->assertEqual((string)$result['float_field']['length'], '5,2'); } 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 0dab1d96a..5a36e3899 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 @@ -105,7 +105,7 @@ class DboOracleTest extends CakeTestCase { */ function testName() { $Db = $this->db; - #$Db =& new DboOracle($config = null, $autoConnect = false); + #$Db = new DboOracle($config = null, $autoConnect = false); $r = $Db->name($Db->name($Db->name('foo.last_update_date'))); $e = 'foo.last_update_date'; diff --git a/cake/tests/cases/libs/model/datasources/dbo/dbo_postgres.test.php b/cake/tests/cases/libs/model/datasources/dbo/dbo_postgres.test.php index 2dff85b3e..bf3ebd77c 100644 --- a/cake/tests/cases/libs/model/datasources/dbo/dbo_postgres.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo/dbo_postgres.test.php @@ -807,7 +807,7 @@ class DboPostgresTest extends CakeTestCase { */ function testUpdateAllWithNonQualifiedConditions() { $this->loadFixtures('Article'); - $Article =& new Article(); + $Article = new Article(); $result = $Article->updateAll(array('title' => "'Awesome'"), array('title' => 'Third Article')); $this->assertTrue($result); @@ -823,7 +823,7 @@ class DboPostgresTest extends CakeTestCase { * @return void */ function testAlteringTwoTables() { - $schema1 =& new CakeSchema(array( + $schema1 = new CakeSchema(array( 'name' => 'AlterTest1', 'connection' => 'test', 'altertest' => array( @@ -835,7 +835,7 @@ class DboPostgresTest extends CakeTestCase { 'name' => array('type' => 'string', 'null' => false, 'length' => 50), ) )); - $schema2 =& new CakeSchema(array( + $schema2 = new CakeSchema(array( 'name' => 'AlterTest1', 'connection' => 'test', 'altertest' => array( 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 3992485b0..df2baad64 100644 --- a/cake/tests/cases/libs/model/datasources/dbo_source.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo_source.test.php @@ -2048,7 +2048,7 @@ class DboSourceTest extends CakeTestCase { * @return void */ function testGenerateAssociationQueryHasManyAndAggregateFunction() { - $this->Model =& new TestModel5(); + $this->Model = new TestModel5(); $this->Model->schema(); $this->_buildRelatedModels($this->Model); @@ -4478,7 +4478,7 @@ class DboSourceTest extends CakeTestCase { * @return void */ function testFieldsWithComplexVirtualFields() { - $Article =& new Article(); + $Article = new Article(); $Article->virtualFields = array( 'distance' => 'ACOS(SIN(20 * PI() / 180) * SIN(Article.latitude * PI() / 180) @@ -4505,7 +4505,7 @@ class DboSourceTest extends CakeTestCase { * @return void */ function testReadVirtualFieldsWithNewLines() { - $Article =& new Article(); + $Article = new Article(); $Article->recursive = 1; $Article->virtualFields = array( 'test' => ' diff --git a/cake/tests/cases/libs/model/db_acl.test.php b/cake/tests/cases/libs/model/db_acl.test.php index d9f7d7562..fb0a9f3f3 100644 --- a/cake/tests/cases/libs/model/db_acl.test.php +++ b/cake/tests/cases/libs/model/db_acl.test.php @@ -239,10 +239,10 @@ class TestDbAcl extends DbAcl { * @return void */ function __construct() { - $this->Aro =& new DbAroTest(); - $this->Aro->Permission =& new DbPermissionTest(); - $this->Aco =& new DbAcoTest(); - $this->Aro->Permission =& new DbPermissionTest(); + $this->Aro = new DbAroTest(); + $this->Aro->Permission = new DbPermissionTest(); + $this->Aco = new DbAcoTest(); + $this->Aro->Permission = new DbPermissionTest(); } } @@ -280,7 +280,7 @@ class AclNodeTest extends CakeTestCase { * @return void */ function testNode() { - $Aco =& new DbAcoTest(); + $Aco = new DbAcoTest(); $result = Set::extract($Aco->node('Controller1'), '{n}.DbAcoTest.id'); $expected = array(2, 1); $this->assertEqual($result, $expected); @@ -321,7 +321,7 @@ class AclNodeTest extends CakeTestCase { * @return void */ function testNodeWithDuplicatePathSegments() { - $Aco =& new DbAcoTest(); + $Aco = new DbAcoTest(); $nodes = $Aco->node('ROOT/Users'); $this->assertEqual($nodes[0]['DbAcoTest']['parent_id'], 1, 'Parent id does not point at ROOT. %s'); } diff --git a/cake/tests/cases/libs/model/model_delete.test.php b/cake/tests/cases/libs/model/model_delete.test.php index be790427f..e61865e57 100644 --- a/cake/tests/cases/libs/model/model_delete.test.php +++ b/cake/tests/cases/libs/model/model_delete.test.php @@ -718,7 +718,7 @@ class ModelDeleteTest extends BaseModelTest { function testBeforeDeleteWipingTable() { $this->loadFixtures('Comment'); - $Comment =& new BeforeDeleteComment(); + $Comment = new BeforeDeleteComment(); // Delete 3 records. $Comment->delete(4); $result = $Comment->find('count'); @@ -746,7 +746,7 @@ class ModelDeleteTest extends BaseModelTest { function testBeforeDeleteWipingTableWithDuplicateDelete() { $this->loadFixtures('Comment'); - $Comment =& new BeforeDeleteComment(); + $Comment = new BeforeDeleteComment(); $Comment->delete(1); $result = $Comment->find('count'); diff --git a/cake/tests/cases/libs/model/model_read.test.php b/cake/tests/cases/libs/model/model_read.test.php index 1eb3b13f6..1a3118763 100755 --- a/cake/tests/cases/libs/model/model_read.test.php +++ b/cake/tests/cases/libs/model/model_read.test.php @@ -4744,7 +4744,7 @@ class ModelReadTest extends BaseModelTest { */ function testBindModelMultipleTimesResetCorrectly() { $this->loadFixtures('User', 'Comment', 'Article'); - $TestModel =& new User(); + $TestModel = new User(); $TestModel->bindModel(array('hasMany' => array('Comment'))); $TestModel->bindModel(array('hasMany' => array('Comment'))); @@ -4761,7 +4761,7 @@ class ModelReadTest extends BaseModelTest { */ function testBindMultipleTimesWithDifferentResetSettings() { $this->loadFixtures('User', 'Comment', 'Article'); - $TestModel =& new User(); + $TestModel = new User(); $result = $TestModel->hasMany; $expected = array(); @@ -4815,7 +4815,7 @@ class ModelReadTest extends BaseModelTest { */ function testUnbindMultipleTimesResetCorrectly() { $this->loadFixtures('User', 'Comment', 'Article'); - $TestModel =& new Article10(); + $TestModel = new Article10(); $TestModel->unbindModel(array('hasMany' => array('Comment'))); $TestModel->unbindModel(array('hasMany' => array('Comment'))); @@ -4832,7 +4832,7 @@ class ModelReadTest extends BaseModelTest { */ function testUnBindMultipleTimesWithDifferentResetSettings() { $this->loadFixtures('User', 'Comment', 'Article'); - $TestModel =& new Comment(); + $TestModel = new Comment(); $result = array_keys($TestModel->belongsTo); $expected = array('Article', 'User'); @@ -6526,7 +6526,7 @@ class ModelReadTest extends BaseModelTest { ); $this->assertEqual($result, $expected); - $TestModel =& new Article(); + $TestModel = new Article(); $TestModel->displayField = 'title'; $result = $TestModel->find('list', array( 'conditions' => array('User.user' => 'mariano'), diff --git a/cake/tests/cases/libs/model/model_validation.test.php b/cake/tests/cases/libs/model/model_validation.test.php index 1481c0bfc..d921618c0 100644 --- a/cake/tests/cases/libs/model/model_validation.test.php +++ b/cake/tests/cases/libs/model/model_validation.test.php @@ -36,7 +36,7 @@ class ModelValidationTest extends BaseModelTest { * @return void */ function testValidationParams() { - $TestModel =& new ValidationTest1(); + $TestModel = new ValidationTest1(); $TestModel->validate['title'] = array( 'rule' => 'customValidatorWithParams', 'required' => true @@ -128,7 +128,7 @@ class ModelValidationTest extends BaseModelTest { * @return void */ function testInvalidFieldsWithFieldListParams() { - $TestModel =& new ValidationTest1(); + $TestModel = new ValidationTest1(); $TestModel->validate = $validate = array( 'title' => array( 'rule' => 'customValidator', @@ -174,7 +174,7 @@ class ModelValidationTest extends BaseModelTest { * @return void */ function testInvalidFieldsWhitelist() { - $TestModel =& new ValidationTest1(); + $TestModel = new ValidationTest1(); $TestModel->validate = $validate = array( 'title' => array( 'rule' => 'customValidator', @@ -199,7 +199,7 @@ class ModelValidationTest extends BaseModelTest { * @return void */ function testValidates() { - $TestModel =& new TestValidate(); + $TestModel = new TestValidate(); $TestModel->validate = array( 'user_id' => 'numeric', @@ -565,7 +565,7 @@ class ModelValidationTest extends BaseModelTest { ) ); - $Something =& new Something(); + $Something = new Something(); $JoinThing =& $Something->JoinThing; $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty')); @@ -618,7 +618,7 @@ class ModelValidationTest extends BaseModelTest { array('something_else_id' => 1, 'doomed' => '') ) ); - $Something =& new Something(); + $Something = new Something(); $JoinThing =& $Something->JoinThing; $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty')); @@ -652,7 +652,7 @@ class ModelValidationTest extends BaseModelTest { function testMissingValidationErrorTriggering() { Configure::write('debug', 2); - $TestModel =& new ValidationTest1(); + $TestModel = new ValidationTest1(); $TestModel->create(array('title' => 'foo')); $TestModel->validate = array( 'title' => array( @@ -671,7 +671,7 @@ class ModelValidationTest extends BaseModelTest { */ function testMissingValidationErrorNoTriggering() { Configure::write('debug', 0); - $TestModel =& new ValidationTest1(); + $TestModel = new ValidationTest1(); $TestModel->create(array('title' => 'foo')); $TestModel->validate = array( 'title' => array( diff --git a/cake/tests/cases/libs/model/model_write.test.php b/cake/tests/cases/libs/model/model_write.test.php index 545c3fecc..d27b3e4d9 100644 --- a/cake/tests/cases/libs/model/model_write.test.php +++ b/cake/tests/cases/libs/model/model_write.test.php @@ -2171,7 +2171,7 @@ class ModelWriteTest extends BaseModelTest { */ function testUpdateSavingBlankValues() { $this->loadFixtures('Article'); - $Article =& new Article(); + $Article = new Article(); $Article->validate = array(); $Article->create(); $result = $Article->save(array( @@ -3037,7 +3037,7 @@ class ModelWriteTest extends BaseModelTest { 'published' => array('type' => 'string') ))); - $Post =& new Post(); + $Post = new Post(); $Post->useDbConfig = 'mock_transaction_assoc'; $Post->Author->useDbConfig = 'mock_transaction_assoc'; @@ -3589,7 +3589,7 @@ class ModelWriteTest extends BaseModelTest { * @return void */ function testSaveAllValidateFirstAtomicFalse() { - $Something =& new Something(); + $Something = new Something(); $invalidData = array( array( 'title' => 'foo', @@ -3620,7 +3620,7 @@ class ModelWriteTest extends BaseModelTest { $expected = array(true, false); $this->assertEqual($result, $expected); - $Something =& new Something(); + $Something = new Something(); $validData = array( array( 'title' => 'title value', diff --git a/cake/tests/cases/libs/object.test.php b/cake/tests/cases/libs/object.test.php index 9d49537c6..fe903a8fc 100644 --- a/cake/tests/cases/libs/object.test.php +++ b/cake/tests/cases/libs/object.test.php @@ -447,7 +447,7 @@ class ObjectTest extends CakeTestCase { @unlink(CACHE . 'persistent' . DS . 'testmodel.php'); - $model =& new ObjectTestModel(); + $model = new ObjectTestModel(); $expected = ClassRegistry::keys(); ClassRegistry::flush(); diff --git a/cake/tests/cases/libs/route/cake_route.test.php b/cake/tests/cases/libs/route/cake_route.test.php index 178af1f73..dae305b23 100644 --- a/cake/tests/cases/libs/route/cake_route.test.php +++ b/cake/tests/cases/libs/route/cake_route.test.php @@ -399,7 +399,7 @@ class CakeRouteTestCase extends CakeTestCase { * @return void */ function testPatternOnAction() { - $route =& new CakeRoute( + $route = new CakeRoute( '/blog/:action/*', array('controller' => 'blog_posts'), array('action' => 'other|actions') diff --git a/cake/tests/cases/libs/sanitize.test.php b/cake/tests/cases/libs/sanitize.test.php index 311964fba..35013ca53 100644 --- a/cake/tests/cases/libs/sanitize.test.php +++ b/cake/tests/cases/libs/sanitize.test.php @@ -481,7 +481,7 @@ HTML; $this->fixtureManager->load($this); $this->loadFixtures('DataTest', 'Article'); - $this->DataTest =& new SanitizeDataTest(array('alias' => 'DataTest')); + $this->DataTest = new SanitizeDataTest(array('alias' => 'DataTest')); $data = array('DataTest' => array( 'id' => 'z', 'count' => '12a', @@ -500,7 +500,7 @@ HTML; $result = $this->DataTest->data; $this->assertEqual($result, $expected); - $this->Article =& new SanitizeArticle(array('alias' => 'Article')); + $this->Article = new SanitizeArticle(array('alias' => 'Article')); $data = array('Article' => array( 'id' => 'ZB', 'user_id' => '12', diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index a9b76e263..dd4e85708 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -601,7 +601,7 @@ class HtmlHelperTest extends CakeTestCase { App::import('Core', 'File'); $testfile = WWW_ROOT . 'theme' . DS . 'test_theme' . DS . 'js' . DS . '__test_js.js'; - $file =& new File($testfile, true); + $file = new File($testfile, true); App::build(array( 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS) diff --git a/cake/tests/cases/libs/view/view.test.php b/cake/tests/cases/libs/view/view.test.php index d6295f74f..2b0bb3252 100644 --- a/cake/tests/cases/libs/view/view.test.php +++ b/cake/tests/cases/libs/view/view.test.php @@ -806,7 +806,7 @@ class ViewTest extends CakeTestCase { */ function testRenderStrippingNoCacheTagsOnlyCacheHelper() { Configure::write('Cache.check', false); - $View =& new View($this->PostsController); + $View = new View($this->PostsController); $View->set(array('superman' => 'clark', 'variable' => 'var')); $View->helpers = array('Html', 'Form', 'Cache'); $View->layout = 'cache_layout'; @@ -821,7 +821,7 @@ class ViewTest extends CakeTestCase { */ function testRenderStrippingNoCacheTagsOnlyCacheCheck() { Configure::write('Cache.check', true); - $View =& new View($this->PostsController); + $View = new View($this->PostsController); $View->set(array('superman' => 'clark', 'variable' => 'var')); $View->helpers = array('Html', 'Form'); $View->layout = 'cache_layout'; diff --git a/cake/tests/lib/templates/footer.php b/cake/tests/lib/templates/footer.php index 15147985f..e9b6c6746 100644 --- a/cake/tests/lib/templates/footer.php +++ b/cake/tests/lib/templates/footer.php @@ -29,7 +29,7 @@ element('sql_dump'); ?> From 01894b315fde9a2fadcc458e4c4ec9db61ec44a6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 23:14:34 -0500 Subject: [PATCH 054/160] Fixing issues caused by not accessing the request object correctly. --- cake/libs/controller/controller.php | 10 +++++----- cake/tests/cases/libs/controller/controller.test.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 775618240..196873dc3 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -1039,7 +1039,7 @@ class Controller extends Object { ), E_USER_WARNING); return array(); } - $options = array_merge($this->request->params, $this->params['url'], $this->passedArgs); + $options = array_merge($this->request->params, $this->request->params['url'], $this->passedArgs); if (isset($this->paginate[$object->alias])) { $defaults = $this->paginate[$object->alias]; @@ -1170,11 +1170,11 @@ class Controller extends Object { 'defaults' => array_merge(array('limit' => 20, 'step' => 1), $defaults), 'options' => $options ); - if (!isset($this->request['paging'])) { - $this->request['paging'] = array(); + if (!isset($this->request->params['paging'])) { + $this->request->params['paging'] = array(); } - $this->request['paging'] = array_merge( - (array)$this->request['paging'], + $this->request->params['paging'] = array_merge( + (array)$this->request->params['paging'], array($object->alias => $paging) ); diff --git a/cake/tests/cases/libs/controller/controller.test.php b/cake/tests/cases/libs/controller/controller.test.php index 489db1fa9..4d4df9fda 100644 --- a/cake/tests/cases/libs/controller/controller.test.php +++ b/cake/tests/cases/libs/controller/controller.test.php @@ -773,7 +773,7 @@ class ControllerTest extends CakeTestCase { 'recursive' => -1 ); $conditions = array(); - $result = $Controller->paginate('ControllerPost',$conditions); + $result = $Controller->paginate('ControllerPost', $conditions); $expected = array( array( 'ControllerPost' => array( From faa23e8d510e3eecc7b698120c0588e77cd8c66a Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 23:22:48 -0500 Subject: [PATCH 055/160] Updating tests to reflect changes in bake templates. --- cake/tests/cases/console/shells/tasks/controller.test.php | 8 ++++---- cake/tests/cases/console/shells/tasks/test.test.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cake/tests/cases/console/shells/tasks/controller.test.php b/cake/tests/cases/console/shells/tasks/controller.test.php index ba8ef1fef..61d00b4f1 100644 --- a/cake/tests/cases/console/shells/tasks/controller.test.php +++ b/cake/tests/cases/console/shells/tasks/controller.test.php @@ -344,8 +344,8 @@ class ControllerTaskTest extends CakeTestCase { $this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result); $this->assertContains('function add()', $result); - $this->assertContains('if (!empty($this->data))', $result); - $this->assertContains('if ($this->BakeArticle->save($this->data))', $result); + $this->assertContains("if (\$this->request->is('post'))", $result); + $this->assertContains('if ($this->BakeArticle->save($this->request->data))', $result); $this->assertContains("\$this->Session->setFlash(__('The bake article has been saved'));", $result); $this->assertContains('function edit($id = null)', $result); @@ -386,8 +386,8 @@ class ControllerTaskTest extends CakeTestCase { $this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result); $this->assertContains('function add()', $result); - $this->assertContains('if (!empty($this->data))', $result); - $this->assertContains('if ($this->BakeArticle->save($this->data))', $result); + $this->assertContains("if (\$this->request->is('post'))", $result); + $this->assertContains('if ($this->BakeArticle->save($this->request->data))', $result); $this->assertContains("\$this->flash(__('The bake article has been saved.'), array('action' => 'index'))", $result); diff --git a/cake/tests/cases/console/shells/tasks/test.test.php b/cake/tests/cases/console/shells/tasks/test.test.php index 484838eb4..14b603e54 100644 --- a/cake/tests/cases/console/shells/tasks/test.test.php +++ b/cake/tests/cases/console/shells/tasks/test.test.php @@ -363,7 +363,7 @@ class TestTaskTest extends CakeTestCase { )); $keys = ClassRegistry::keys(); $this->assertTrue(in_array('test_task_comment', $keys)); - $object =& $this->Task->buildTestSubject('Model', 'TestTaskComment'); + $object = $this->Task->buildTestSubject('Model', 'TestTaskComment'); $keys = ClassRegistry::keys(); $this->assertFalse(in_array('random', $keys)); @@ -444,7 +444,7 @@ class TestTaskTest extends CakeTestCase { $this->assertContains('class TestTaskArticleTestCase extends CakeTestCase', $result); $this->assertContains('function startTest()', $result); - $this->assertContains("\$this->TestTaskArticle =& ClassRegistry::init('TestTaskArticle')", $result); + $this->assertContains("\$this->TestTaskArticle = ClassRegistry::init('TestTaskArticle')", $result); $this->assertContains('function endTest()', $result); $this->assertContains('unset($this->TestTaskArticle)', $result); From e63f81c12a29b8db0021786fec75336e7123c868 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 22:50:15 -0500 Subject: [PATCH 056/160] Fixing test case that was missing request access. --- cake/tests/cases/libs/view/helpers/paginator.test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/paginator.test.php b/cake/tests/cases/libs/view/helpers/paginator.test.php index bc30867bc..88d31ad6d 100644 --- a/cake/tests/cases/libs/view/helpers/paginator.test.php +++ b/cake/tests/cases/libs/view/helpers/paginator.test.php @@ -1574,7 +1574,7 @@ class PaginatorHelperTest extends CakeTestCase { ); $this->assertTags($result, $expected); - $this->Paginator->params['paging']['Client']['page'] = 3; + $this->Paginator->request->params['paging']['Client']['page'] = 3; $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2, 'separator' => ' - ', 'ellipsis' => ' ~~~ ')); $expected = array( array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span', @@ -1591,7 +1591,7 @@ class PaginatorHelperTest extends CakeTestCase { ); $this->assertTags($result, $expected); - $this->Paginator->params['paging']['Client']['page'] = 3; + $this->Paginator->request->params['paging']['Client']['page'] = 3; $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2, 'separator' => ' - ', 'ellipsis' => '...')); $expected = array( array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span', From 8e1dd9e89230263643b1c97c05e872d74a4b6d3e Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 23:34:52 -0500 Subject: [PATCH 057/160] Adding __get() to access protected properties of ConsoleOptionParser components for upcoming changes. --- cake/console/libs/console_input_argument.php | 13 +++++++++++++ cake/console/libs/console_input_option.php | 13 +++++++++++++ cake/console/libs/console_input_subcommand.php | 17 ++++++++++++++--- cake/console/libs/help_formatter.php | 2 +- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/cake/console/libs/console_input_argument.php b/cake/console/libs/console_input_argument.php index 3e8d1eb7d..fbd05548f 100644 --- a/cake/console/libs/console_input_argument.php +++ b/cake/console/libs/console_input_argument.php @@ -50,6 +50,19 @@ class ConsoleInputArgument { } } +/** + * Protected attribute accessor. + * + * @param string $name Name of attribute to read. + * @return mixed. + */ + public function __get($name) { + if (isset($this->{'_' . $name})) { + return $this->{'_' . $name}; + } + return null; + } + /** * Get the name of the argument * diff --git a/cake/console/libs/console_input_option.php b/cake/console/libs/console_input_option.php index 173e19cdc..d47bcb956 100644 --- a/cake/console/libs/console_input_option.php +++ b/cake/console/libs/console_input_option.php @@ -55,6 +55,19 @@ class ConsoleInputOption { } } +/** + * Protected attribute accessor. + * + * @param string $name Name of attribute to read. + * @return mixed. + */ + public function __get($name) { + if (isset($this->{'_' . $name})) { + return $this->{'_' . $name}; + } + return null; + } + /** * Get the name of the argument * diff --git a/cake/console/libs/console_input_subcommand.php b/cake/console/libs/console_input_subcommand.php index 514c5a1b9..f6b80bfdd 100644 --- a/cake/console/libs/console_input_subcommand.php +++ b/cake/console/libs/console_input_subcommand.php @@ -27,9 +27,7 @@ */ class ConsoleInputSubcommand { - protected $_name; - protected $_help; - protected $_parser; + protected $_name, $_help, $_parser; /** * Make a new Subcommand @@ -55,6 +53,19 @@ class ConsoleInputSubcommand { } } +/** + * Protected attribute accessor. + * + * @param string $name Name of attribute to read. + * @return mixed. + */ + public function __get($name) { + if (isset($this->{'_' . $name})) { + return $this->{'_' . $name}; + } + return null; + } + /** * Get the name of the subcommand * diff --git a/cake/console/libs/help_formatter.php b/cake/console/libs/help_formatter.php index 7af4cadf1..754a1865c 100644 --- a/cake/console/libs/help_formatter.php +++ b/cake/console/libs/help_formatter.php @@ -141,7 +141,7 @@ class HelpFormatter { protected function _getMaxLength($collection) { $max = 0; foreach ($collection as $item) { - $max = (strlen($item->name()) > $max) ? strlen($item->name()) : $max; + $max = (strlen($item->name) > $max) ? strlen($item->name) : $max; } return $max; } From f9b7cbcb96ee80c0f57e665d444a0603ad926920 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 23:52:33 -0500 Subject: [PATCH 058/160] Making ConsoleOptionParser allow subclasses of the option, argument and subcommand classes to be supplied as arguments to the builder methods. Adding tests. --- cake/console/libs/console_input_argument.php | 11 +-- cake/console/libs/console_input_option.php | 9 -- .../console/libs/console_input_subcommand.php | 9 -- cake/console/libs/console_option_parser.php | 83 +++++++++++-------- .../libs/console_option_parser.test.php | 38 +++++++++ 5 files changed, 89 insertions(+), 61 deletions(-) diff --git a/cake/console/libs/console_input_argument.php b/cake/console/libs/console_input_argument.php index fbd05548f..ce28446cf 100644 --- a/cake/console/libs/console_input_argument.php +++ b/cake/console/libs/console_input_argument.php @@ -63,15 +63,6 @@ class ConsoleInputArgument { return null; } -/** - * Get the name of the argument - * - * @return string - */ - public function name() { - return $this->_name; - } - /** * Generate the help for this this argument. * @@ -154,4 +145,4 @@ class ConsoleInputArgument { } return $parent; } -} \ No newline at end of file +} diff --git a/cake/console/libs/console_input_option.php b/cake/console/libs/console_input_option.php index d47bcb956..d55847fe4 100644 --- a/cake/console/libs/console_input_option.php +++ b/cake/console/libs/console_input_option.php @@ -68,15 +68,6 @@ class ConsoleInputOption { return null; } -/** - * Get the name of the argument - * - * @return string - */ - public function name() { - return $this->_name; - } - /** * Generate the help for this this option. * diff --git a/cake/console/libs/console_input_subcommand.php b/cake/console/libs/console_input_subcommand.php index f6b80bfdd..0b9097107 100644 --- a/cake/console/libs/console_input_subcommand.php +++ b/cake/console/libs/console_input_subcommand.php @@ -66,15 +66,6 @@ class ConsoleInputSubcommand { return null; } -/** - * Get the name of the subcommand - * - * @return string - */ - public function name() { - return $this->_name; - } - /** * Generate the help for this this subcommand. * diff --git a/cake/console/libs/console_option_parser.php b/cake/console/libs/console_option_parser.php index c1779d828..70009f2c1 100644 --- a/cake/console/libs/console_option_parser.php +++ b/cake/console/libs/console_option_parser.php @@ -265,18 +265,24 @@ class ConsoleOptionParser { * @return returns $this. */ public function addOption($name, $params = array()) { - $defaults = array( - 'name' => $name, - 'short' => null, - 'help' => '', - 'default' => null, - 'boolean' => false, - 'choices' => array() - ); - $options = array_merge($defaults, $params); - $this->_options[$name] = new ConsoleInputOption($options); - if (!empty($options['short'])) { - $this->_shortOptions[$options['short']] = $name; + if (is_object($name) && $name instanceof ConsoleInputOption) { + $option = $name; + $name = $option->name; + } else { + $defaults = array( + 'name' => $name, + 'short' => null, + 'help' => '', + 'default' => null, + 'boolean' => false, + 'choices' => array() + ); + $options = array_merge($defaults, $params); + $option = new ConsoleInputOption($options); + } + $this->_options[$name] = $option; + if ($option->short !== null) { + $this->_shortOptions[$option->short] = $name; } return $this; } @@ -299,18 +305,23 @@ class ConsoleOptionParser { * @return $this. */ public function addArgument($name, $params = array()) { - $defaults = array( - 'name' => $name, - 'help' => '', - 'index' => count($this->_args), - 'required' => false, - 'choices' => array() - ); - $options = array_merge($defaults, $params); - $index = $options['index']; - unset($options['index']); - - $this->_args[$index] = new ConsoleInputArgument($options); + if (is_object($name) && $name instanceof ConsoleInputArgument) { + $arg = $name; + $index = count($this->_args); + } else { + $defaults = array( + 'name' => $name, + 'help' => '', + 'index' => count($this->_args), + 'required' => false, + 'choices' => array() + ); + $options = array_merge($defaults, $params); + $index = $options['index']; + unset($options['index']); + $arg = new ConsoleInputArgument($options); + } + $this->_args[$index] = $arg; return $this; } @@ -361,13 +372,19 @@ class ConsoleOptionParser { * @return $this. */ public function addSubcommand($name, $params = array()) { - $defaults = array( - 'name' => $name, - 'help' => '', - 'parser' => null - ); - $options = array_merge($defaults, $params); - $this->_subcommands[$name] = new ConsoleInputSubcommand($options); + if (is_object($name) && $name instanceof ConsoleInputSubcommand) { + $command = $name; + $name = $command->name; + } else { + $defaults = array( + 'name' => $name, + 'help' => '', + 'parser' => null + ); + $options = array_merge($defaults, $params); + $command = new ConsoleInputSubcommand($options); + } + $this->_subcommands[$name] = $command; return $this; } @@ -441,12 +458,12 @@ class ConsoleOptionParser { foreach ($this->_args as $i => $arg) { if ($arg->isRequired() && !isset($args[$i]) && empty($params['help'])) { throw new RuntimeException( - sprintf(__('Missing required arguments. %s is required.'), $arg->name()) + sprintf(__('Missing required arguments. %s is required.'), $arg->name) ); } } foreach ($this->_options as $option) { - $name = $option->name(); + $name = $option->name; $isBoolean = $option->isBoolean(); $default = $option->defaultValue(); diff --git a/cake/tests/cases/console/libs/console_option_parser.test.php b/cake/tests/cases/console/libs/console_option_parser.test.php index 2b46cd00b..605ed281f 100644 --- a/cake/tests/cases/console/libs/console_option_parser.test.php +++ b/cake/tests/cases/console/libs/console_option_parser.test.php @@ -79,6 +79,18 @@ class ConsoleOptionParserTest extends CakeTestCase { $this->assertEquals(array('test' => 'value', 'help' => false), $result[0], 'Long parameter did not parse out'); } +/** + * test addOption with an object. + * + * @return void + */ + function testAddOptionObject() { + $parser = new ConsoleOptionParser('test', false); + $parser->addOption(new ConsoleInputOption('test', 't')); + $result = $parser->parse(array('--test=value')); + $this->assertEquals(array('test' => 'value', 'help' => false), $result[0], 'Long parameter did not parse out'); + } + /** * test adding an option and using the long value for parsing. * @@ -255,6 +267,19 @@ class ConsoleOptionParserTest extends CakeTestCase { $this->assertEquals($parser, $result, 'Should returnn this'); } +/** + * test addOption with an object. + * + * @return void + */ + function testAddArgumentObject() { + $parser = new ConsoleOptionParser('test', false); + $parser->addArgument(new ConsoleInputArgument('test')); + $result = $parser->arguments(); + $this->assertEquals(1, count($result)); + $this->assertEquals('test', $result[0]->name); + } + /** * test overwriting positional arguments. * @@ -350,6 +375,19 @@ class ConsoleOptionParserTest extends CakeTestCase { $this->assertEquals($parser, $result, 'Adding a subcommand is not chainable'); } +/** + * test addSubcommand with an object. + * + * @return void + */ + function testAddSubcommandObject() { + $parser = new ConsoleOptionParser('test', false); + $parser->addSubcommand(new ConsoleInputSubcommand('test')); + $result = $parser->subcommands(); + $this->assertEquals(1, count($result)); + $this->assertEquals('test', $result['test']->name); + } + /** * test adding multiple subcommands * From 6c8c7ca4a5ed26f0d492ab921609569aadfd8c81 Mon Sep 17 00:00:00 2001 From: mark_story Date: Fri, 12 Nov 2010 23:57:55 -0500 Subject: [PATCH 059/160] Turning __get() back into methods. There were so few properties being accessed that it didn't make sense to have __get(), over a handful of methods. Tests updated. --- cake/console/libs/console_input_argument.php | 12 ++++------- cake/console/libs/console_input_option.php | 21 ++++++++++++------- .../console/libs/console_input_subcommand.php | 12 ++++------- cake/console/libs/console_option_parser.php | 12 +++++------ cake/console/libs/help_formatter.php | 2 +- .../libs/console_option_parser.test.php | 4 ++-- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/cake/console/libs/console_input_argument.php b/cake/console/libs/console_input_argument.php index ce28446cf..0a82bc425 100644 --- a/cake/console/libs/console_input_argument.php +++ b/cake/console/libs/console_input_argument.php @@ -51,16 +51,12 @@ class ConsoleInputArgument { } /** - * Protected attribute accessor. + * Get the value of the name attribute. * - * @param string $name Name of attribute to read. - * @return mixed. + * @return string Value of this->_name. */ - public function __get($name) { - if (isset($this->{'_' . $name})) { - return $this->{'_' . $name}; - } - return null; + public function name() { + return $this->_name; } /** diff --git a/cake/console/libs/console_input_option.php b/cake/console/libs/console_input_option.php index d55847fe4..3d8267277 100644 --- a/cake/console/libs/console_input_option.php +++ b/cake/console/libs/console_input_option.php @@ -56,16 +56,21 @@ class ConsoleInputOption { } /** - * Protected attribute accessor. + * Get the value of the name attribute. * - * @param string $name Name of attribute to read. - * @return mixed. + * @return string Value of this->_name. */ - public function __get($name) { - if (isset($this->{'_' . $name})) { - return $this->{'_' . $name}; - } - return null; + public function name() { + return $this->_name; + } + +/** + * Get the value of the short attribute. + * + * @return string Value of this->_short. + */ + public function short() { + return $this->_short; } /** diff --git a/cake/console/libs/console_input_subcommand.php b/cake/console/libs/console_input_subcommand.php index 0b9097107..76bd19d2f 100644 --- a/cake/console/libs/console_input_subcommand.php +++ b/cake/console/libs/console_input_subcommand.php @@ -54,16 +54,12 @@ class ConsoleInputSubcommand { } /** - * Protected attribute accessor. + * Get the value of the name attribute. * - * @param string $name Name of attribute to read. - * @return mixed. + * @return string Value of this->_name. */ - public function __get($name) { - if (isset($this->{'_' . $name})) { - return $this->{'_' . $name}; - } - return null; + public function name() { + return $this->_name; } /** diff --git a/cake/console/libs/console_option_parser.php b/cake/console/libs/console_option_parser.php index 70009f2c1..d6cccba1e 100644 --- a/cake/console/libs/console_option_parser.php +++ b/cake/console/libs/console_option_parser.php @@ -267,7 +267,7 @@ class ConsoleOptionParser { public function addOption($name, $params = array()) { if (is_object($name) && $name instanceof ConsoleInputOption) { $option = $name; - $name = $option->name; + $name = $option->name(); } else { $defaults = array( 'name' => $name, @@ -281,8 +281,8 @@ class ConsoleOptionParser { $option = new ConsoleInputOption($options); } $this->_options[$name] = $option; - if ($option->short !== null) { - $this->_shortOptions[$option->short] = $name; + if ($option->short() !== null) { + $this->_shortOptions[$option->short()] = $name; } return $this; } @@ -374,7 +374,7 @@ class ConsoleOptionParser { public function addSubcommand($name, $params = array()) { if (is_object($name) && $name instanceof ConsoleInputSubcommand) { $command = $name; - $name = $command->name; + $name = $command->name(); } else { $defaults = array( 'name' => $name, @@ -458,12 +458,12 @@ class ConsoleOptionParser { foreach ($this->_args as $i => $arg) { if ($arg->isRequired() && !isset($args[$i]) && empty($params['help'])) { throw new RuntimeException( - sprintf(__('Missing required arguments. %s is required.'), $arg->name) + sprintf(__('Missing required arguments. %s is required.'), $arg->name()) ); } } foreach ($this->_options as $option) { - $name = $option->name; + $name = $option->name(); $isBoolean = $option->isBoolean(); $default = $option->defaultValue(); diff --git a/cake/console/libs/help_formatter.php b/cake/console/libs/help_formatter.php index 754a1865c..7af4cadf1 100644 --- a/cake/console/libs/help_formatter.php +++ b/cake/console/libs/help_formatter.php @@ -141,7 +141,7 @@ class HelpFormatter { protected function _getMaxLength($collection) { $max = 0; foreach ($collection as $item) { - $max = (strlen($item->name) > $max) ? strlen($item->name) : $max; + $max = (strlen($item->name()) > $max) ? strlen($item->name()) : $max; } return $max; } diff --git a/cake/tests/cases/console/libs/console_option_parser.test.php b/cake/tests/cases/console/libs/console_option_parser.test.php index 605ed281f..656f3317a 100644 --- a/cake/tests/cases/console/libs/console_option_parser.test.php +++ b/cake/tests/cases/console/libs/console_option_parser.test.php @@ -277,7 +277,7 @@ class ConsoleOptionParserTest extends CakeTestCase { $parser->addArgument(new ConsoleInputArgument('test')); $result = $parser->arguments(); $this->assertEquals(1, count($result)); - $this->assertEquals('test', $result[0]->name); + $this->assertEquals('test', $result[0]->name()); } /** @@ -385,7 +385,7 @@ class ConsoleOptionParserTest extends CakeTestCase { $parser->addSubcommand(new ConsoleInputSubcommand('test')); $result = $parser->subcommands(); $this->assertEquals(1, count($result)); - $this->assertEquals('test', $result['test']->name); + $this->assertEquals('test', $result['test']->name()); } /** From 76a80c262e519bf256884de72f9a0909b04d9fca Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 13 Nov 2010 12:04:22 -0500 Subject: [PATCH 060/160] 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 061/160] 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 c7fed2ecba1f0db47fecf0fb4009c4afe9a68a5e Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 13 Nov 2010 21:08:26 -0500 Subject: [PATCH 062/160] Removing duplicate calls to Inflector. --- cake/libs/view/view.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 3db73cf3d..557c69674 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -711,7 +711,7 @@ class View extends Object { $name = $this->viewPath . DS . $subDir . $name; } } - $paths = $this->_paths(Inflector::underscore($this->plugin)); + $paths = $this->_paths($this->plugin); $exts = array($this->ext); if ($this->ext !== '.ctp') { @@ -754,7 +754,7 @@ class View extends Object { if (!is_null($this->layoutPath)) { $subDir = $this->layoutPath . DS; } - $paths = $this->_paths(Inflector::underscore($this->plugin)); + $paths = $this->_paths($this->plugin); $file = 'layouts' . DS . $subDir . $name; $exts = array($this->ext); From 6073ac5dfa72b66747ebf7f1e8f3c9452b7d493d Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 13 Nov 2010 23:55:24 -0500 Subject: [PATCH 063/160] Fixing errors caused by accessing things that don't exist. --- cake/libs/controller/controller.php | 2 +- cake/tests/cases/libs/controller/controller.test.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cake/libs/controller/controller.php b/cake/libs/controller/controller.php index 196873dc3..1e5eeef04 100644 --- a/cake/libs/controller/controller.php +++ b/cake/libs/controller/controller.php @@ -1039,7 +1039,7 @@ class Controller extends Object { ), E_USER_WARNING); return array(); } - $options = array_merge($this->request->params, $this->request->params['url'], $this->passedArgs); + $options = array_merge($this->request->params, $this->request->query, $this->passedArgs); if (isset($this->paginate[$object->alias])) { $defaults = $this->paginate[$object->alias]; diff --git a/cake/tests/cases/libs/controller/controller.test.php b/cake/tests/cases/libs/controller/controller.test.php index 4d4df9fda..d3ad1276a 100644 --- a/cake/tests/cases/libs/controller/controller.test.php +++ b/cake/tests/cases/libs/controller/controller.test.php @@ -757,9 +757,9 @@ class ControllerTest extends CakeTestCase { * @access public */ function testPaginateFieldsDouble(){ - $Controller = new Controller(); + $Controller = new Controller($this->getMock('CakeRequest')); $Controller->uses = array('ControllerPost'); - $Controller->request->params['url'] = array(); + $Controller->request->query = array(); $Controller->constructClasses(); $Controller->paginate = array( From dad7963ea43b1d474903c83ada79620bc81fd2e4 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 00:00:23 -0500 Subject: [PATCH 064/160] Moving Dispatcher inside libs directory, as it is part of CakePHP's libs. --- cake/{ => libs}/dispatcher.php | 0 cake/tests/cases/libs/all_routing.test.php | 14 ++++++++------ cake/tests/cases/{ => libs}/dispatcher.test.php | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) rename cake/{ => libs}/dispatcher.php (100%) rename cake/tests/cases/{ => libs}/dispatcher.test.php (99%) diff --git a/cake/dispatcher.php b/cake/libs/dispatcher.php similarity index 100% rename from cake/dispatcher.php rename to cake/libs/dispatcher.php diff --git a/cake/tests/cases/libs/all_routing.test.php b/cake/tests/cases/libs/all_routing.test.php index 1f60002fc..6e32f472b 100644 --- a/cake/tests/cases/libs/all_routing.test.php +++ b/cake/tests/cases/libs/all_routing.test.php @@ -36,12 +36,14 @@ class AllRoutingTest extends PHPUnit_Framework_TestSuite { public static function suite() { $suite = new PHPUnit_Framework_TestSuite('All Router and Dispatcher class tests'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'dispatcher.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'router.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'route' . DS . 'cake_route.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'route' . DS . 'plugin_short_route.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_response.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_request.test.php'); + $libs = CORE_TEST_CASES . DS . 'libs' . DS; + + $suite->addTestFile($libs . 'dispatcher.test.php'); + $suite->addTestFile($libs . 'router.test.php'); + $suite->addTestFile($libs . 'route' . DS . 'cake_route.test.php'); + $suite->addTestFile($libs . 'route' . DS . 'plugin_short_route.test.php'); + $suite->addTestFile($libs . 'cake_response.test.php'); + $suite->addTestFile($libs . 'cake_request.test.php'); return $suite; } } diff --git a/cake/tests/cases/dispatcher.test.php b/cake/tests/cases/libs/dispatcher.test.php similarity index 99% rename from cake/tests/cases/dispatcher.test.php rename to cake/tests/cases/libs/dispatcher.test.php index c81639108..b16d4cd9b 100644 --- a/cake/tests/cases/dispatcher.test.php +++ b/cake/tests/cases/libs/dispatcher.test.php @@ -17,7 +17,7 @@ * @since CakePHP(tm) v 1.2.0.4206 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -require_once CAKE . 'dispatcher.php'; +App::import('Core', 'Dispatcher', false); App::import('Core', 'CakeResponse', false); if (!class_exists('AppController')) { From 1fe84c00ddce6dc0328ef20dda5ec6f37d327767 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 00:06:01 -0500 Subject: [PATCH 065/160] Starting to try and simplify the bootstrap process, and give a choice over which GET param is used for cake's url. --- app/webroot/index.php | 13 ++++--------- cake/libs/dispatcher.php | 7 ++++--- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/app/webroot/index.php b/app/webroot/index.php index b2ddf4020..8763a4f7a 100644 --- a/app/webroot/index.php +++ b/app/webroot/index.php @@ -65,13 +65,8 @@ define('WWW_ROOT', dirname(__FILE__) . DS); } if (!defined('CORE_PATH')) { - if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) { - define('APP_PATH', null); - define('CORE_PATH', null); - } else { - define('APP_PATH', ROOT . DS . APP_DIR . DS); - define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); - } + define('APP_PATH', ROOT . DS . APP_DIR . DS); + define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); } if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) { trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); @@ -79,7 +74,7 @@ if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') { return; } else { - require CAKE . 'dispatcher.php'; + App::import('Core', 'Dispatcher'); $Dispatcher = new Dispatcher(); - $Dispatcher->dispatch(); + $Dispatcher->dispatch(new CakeRequest($_GET['url'])); } diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index 000ece29e..b5e376f55 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -104,14 +104,14 @@ class Dispatcher { * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called * Actions). * - * @param mixed $url Either a string url or a CakeRequest object information to work on. If $url is a string - * It will be used to create the request object. + * @param CakeRequest $request Request object to dispatch. * @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params * @return boolean Success * @throws MissingControllerException, MissingActionException, PrivateActionException if any of those error states * are encountered. */ - public function dispatch($url = null, $additionalParams = array()) { + public function dispatch(CakeRequest $request, $additionalParams = array()) { + /* Should move to Object::requestAction() if (is_array($url)) { $url = $this->_extractParams($url, $additionalParams); } @@ -120,6 +120,7 @@ class Dispatcher { } else { $request = new CakeRequest($url); } + */ $this->here = $request->here; From ea80a6dbbbb8e74ce8b301b4db6ad609b39f05cb Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 00:16:07 -0500 Subject: [PATCH 066/160] Removing instance variables that were no longer needed, as they weren't actually being used for much. --- cake/libs/dispatcher.php | 37 +++++-------------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index b5e376f55..67b31de0b 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -24,7 +24,7 @@ /** * List of helpers to include */ -App::import('Core', array('Router', 'CakeRequest', 'CakeResponse')); +App::import('Core', array('Router', 'CakeRequest', 'CakeResponse'), false); App::import('Controller', 'Controller', false); /** @@ -37,22 +37,6 @@ App::import('Controller', 'Controller', false); */ class Dispatcher { -/** - * Base URL - * - * @var string - * @access public - */ - public $base = false; - -/** - * webroot path - * - * @var string - * @access public - */ - public $webroot = '/'; - /** * Current URL * @@ -61,14 +45,6 @@ class Dispatcher { */ public $here = false; -/** - * the params for this request - * - * @var string - * @access public - */ - public $params = null; - /** * The request object * @@ -129,9 +105,7 @@ class Dispatcher { } $request = $this->parseParams($request, $additionalParams); - $this->request = $request; - - $controller = $this->_getController(); + $controller = $this->_getController($request); if (!is_object($controller)) { Router::setRequestInfo($request); @@ -217,7 +191,6 @@ class Dispatcher { protected function _extractParams($url, $additionalParams = array()) { $defaults = array('pass' => array(), 'named' => array(), 'form' => array()); $params = array_merge($defaults, $url, $additionalParams); - $this->params = $params; $params += array('base' => false, 'url' => array()); return ltrim(Router::reverse($params), '/'); @@ -249,15 +222,15 @@ class Dispatcher { * @param array $params Array of parameters * @return mixed name of controller if not loaded, or object if loaded */ - protected function &_getController() { + protected function &_getController($request) { $controller = false; - $ctrlClass = $this->__loadController($this->request); + $ctrlClass = $this->__loadController($request); if (!$ctrlClass) { return $controller; } $ctrlClass .= 'Controller'; if (class_exists($ctrlClass)) { - $controller = new $ctrlClass($this->request); + $controller = new $ctrlClass($request); } return $controller; } From 557d7972971a75dfebe4a0a6e84627321ad1294d Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 00:29:56 -0500 Subject: [PATCH 067/160] Making Dispatcher test cases pass when Dispatcher expects a CakeRequest instead of a string. --- cake/tests/cases/libs/dispatcher.test.php | 141 +++++++++------------- 1 file changed, 55 insertions(+), 86 deletions(-) diff --git a/cake/tests/cases/libs/dispatcher.test.php b/cake/tests/cases/libs/dispatcher.test.php index b16d4cd9b..35f161e7a 100644 --- a/cake/tests/cases/libs/dispatcher.test.php +++ b/cake/tests/cases/libs/dispatcher.test.php @@ -717,7 +717,7 @@ class DispatcherTest extends CakeTestCase { try { $Dispatcher = new TestDispatcher(); Configure::write('App.baseUrl', '/index.php'); - $url = 'some_controller/home/param:value/param2:value2'; + $url = new CakeRequest('some_controller/home/param:value/param2:value2'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->fail('No exception thrown'); } catch (MissingControllerException $e) { @@ -733,7 +733,7 @@ class DispatcherTest extends CakeTestCase { public function testPrivate() { $Dispatcher = new TestDispatcher(); Configure::write('App.baseUrl','/index.php'); - $url = 'some_pages/_protected/param:value/param2:value2'; + $url = new CakeRequest('some_pages/_protected/param:value/param2:value2'); try { $controller = $Dispatcher->dispatch($url, array('return' => 1)); @@ -753,7 +753,7 @@ class DispatcherTest extends CakeTestCase { public function testMissingAction() { $Dispatcher = new TestDispatcher(); Configure::write('App.baseUrl', '/index.php'); - $url = 'some_pages/home/param:value/param2:value2'; + $url = new CakeRequest('some_pages/home/param:value/param2:value2'); try { $controller = $Dispatcher->dispatch($url, array('return'=> 1)); @@ -771,7 +771,7 @@ class DispatcherTest extends CakeTestCase { function testMissingActionFromBaseClassMethods() { $Dispatcher = new TestDispatcher(); Configure::write('App.baseUrl','/index.php'); - $url = 'some_pages/redirect/param:value/param2:value2'; + $url = new CakeRequest('some_pages/redirect/param:value/param2:value2'); try { $controller = $Dispatcher->dispatch($url, array('return'=> 1)); @@ -792,7 +792,7 @@ class DispatcherTest extends CakeTestCase { )); $Dispatcher = new TestDispatcher(); Configure::write('App.baseUrl', '/index.php'); - $url = 'pages/home/param:value/param2:value2'; + $url = new CakeRequest('pages/home/param:value/param2:value2'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $expected = 'Pages'; @@ -803,16 +803,15 @@ class DispatcherTest extends CakeTestCase { Configure::write('App.baseUrl','/pages/index.php'); - $url = 'pages/home'; + $url = new CakeRequest('pages/home'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $expected = 'Pages'; $this->assertEqual($expected, $controller->name); - $url = 'pages/home/'; + $url = new CakeRequest('pages/home/'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertNull($controller->plugin); - $this->assertNull($Dispatcher->params['plugin']); $expected = 'Pages'; $this->assertEqual($expected, $controller->name); @@ -822,55 +821,27 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); Configure::write('App.baseUrl', '/timesheets/index.php'); - $url = 'timesheets'; + $url = new CakeRequest('timesheets'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $expected = 'Timesheets'; $this->assertEqual($expected, $controller->name); - $url = 'timesheets/'; + $url = new CakeRequest('timesheets/'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual('Timesheets', $controller->name); - $this->assertEqual('/timesheets/index.php', $Dispatcher->request->base); + $this->assertEqual('/timesheets/index.php', $url->base); - $url = 'test_dispatch_pages/camelCased'; + $url = new CakeRequest('test_dispatch_pages/camelCased'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual('TestDispatchPages', $controller->name); - $url = 'test_dispatch_pages/camelCased/something. .'; + $url = new CakeRequest('test_dispatch_pages/camelCased/something. .'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual($controller->params['pass'][0], 'something. .', 'Period was chopped off. %s'); } -/** - * testDispatchWithArray method - * - * @return void - */ - public function testDispatchWithArray() { - App::build(array( - 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS) - )); - Router::reload(); - Configure::write('App.baseUrl', '/index.php'); - $Dispatcher = new TestDispatcher(); - - $url = array('controller' => 'pages', 'action' => 'display'); - $controller = $Dispatcher->dispatch($url, array( - 'pass' => array('home'), - 'named' => array('param' => 'value', 'param2' => 'value2'), - 'return' => 1 - )); - $expected = 'Pages'; - $this->assertEqual($expected, $controller->name); - - $expected = array('0' => 'home', 'param' => 'value', 'param2' => 'value2'); - $this->assertIdentical($expected, $controller->passedArgs); - - $this->assertEqual($Dispatcher->request->base . '/pages/display/home/param:value/param2:value2', $Dispatcher->request->here); - } - /** * testAdminDispatch method * @@ -881,7 +852,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); Configure::write('Routing.prefixes', array('admin')); Configure::write('App.baseUrl','/cake/repo/branches/1.2.x.x/index.php'); - $url = 'admin/test_dispatch_pages/index/param:value/param2:value2'; + $url = new CakeRequest('admin/test_dispatch_pages/index/param:value/param2:value2'); Router::reload(); $controller = $Dispatcher->dispatch($url, array('return' => 1)); @@ -914,10 +885,10 @@ class DispatcherTest extends CakeTestCase { array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'display') ); - $url = 'my_plugin/some_pages/home/param:value/param2:value2'; + $url = new CakeRequest('my_plugin/some_pages/home/param:value/param2:value2'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); - $result = $Dispatcher->parseParams(new CakeRequest($url)); + $result = $Dispatcher->parseParams($url); $expected = array( 'pass' => array('home'), 'named' => array('param'=> 'value', 'param2'=> 'value2'), 'plugin'=> 'my_plugin', @@ -958,7 +929,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher->base = false; - $url = 'my_plugin/other_pages/index/param:value/param2:value2'; + $url = new CakeRequest('my_plugin/other_pages/index/param:value/param2:value2'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertIdentical($controller->plugin, 'my_plugin'); @@ -992,7 +963,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); $Dispatcher->base = false; - $url = 'my_plugin/my_plugin/add/param:value/param2:value2'; + $url = new CakeRequest('my_plugin/my_plugin/add/param:value/param2:value2'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); @@ -1012,7 +983,7 @@ class DispatcherTest extends CakeTestCase { $plugin = 'MyPlugin'; $pluginUrl = Inflector::underscore($plugin); - $url = $pluginUrl; + $url = new CakeRequest($pluginUrl); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertIdentical($controller->plugin, 'my_plugin'); $this->assertIdentical($controller->name, 'MyPlugin'); @@ -1027,7 +998,7 @@ class DispatcherTest extends CakeTestCase { Router::reload(); $Dispatcher = new TestDispatcher(); - $url = 'admin/my_plugin/my_plugin/add/5/param:value/param2:value2'; + $url = new CakeRequest('admin/my_plugin/my_plugin/add/5/param:value/param2:value2'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual($controller->params['plugin'], 'my_plugin'); @@ -1047,7 +1018,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); - $controller = $Dispatcher->dispatch('admin/articles_test', array('return' => 1)); + $controller = $Dispatcher->dispatch(new CakeRequest('admin/articles_test'), array('return' => 1)); $this->assertIdentical($controller->plugin, 'articles_test'); $this->assertIdentical($controller->name, 'ArticlesTest'); $this->assertIdentical($controller->action, 'admin_index'); @@ -1087,7 +1058,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); $Dispatcher->base = false; - $url = 'my_plugin/'; + $url = new CakeRequest('my_plugin/'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual($controller->params['controller'], 'my_plugin'); $this->assertEqual($controller->params['plugin'], 'my_plugin'); @@ -1115,21 +1086,21 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); $Dispatcher->base = false; - $url = 'test_plugin/'; + $url = new CakeRequest('test_plugin/'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual($controller->params['controller'], 'test_plugin'); $this->assertEqual($controller->params['plugin'], 'test_plugin'); $this->assertEqual($controller->params['action'], 'index'); $this->assertFalse(isset($controller->params['pass'][0])); - $url = '/test_plugin/tests/index'; + $url = new CakeRequest('/test_plugin/tests/index'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual($controller->params['controller'], 'tests'); $this->assertEqual($controller->params['plugin'], 'test_plugin'); $this->assertEqual($controller->params['action'], 'index'); $this->assertFalse(isset($controller->params['pass'][0])); - $url = '/test_plugin/tests/index/some_param'; + $url = new CakeRequest('/test_plugin/tests/index/some_param'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual($controller->params['controller'], 'tests'); $this->assertEqual($controller->params['plugin'], 'test_plugin'); @@ -1152,7 +1123,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); $Dispatcher->base = false; - $url = 'my_plugin/not_here/param:value/param2:value2'; + $url = new CakeRequest('my_plugin/not_here/param:value/param2:value2'); try { $controller = $Dispatcher->dispatch($url, array('return'=> 1)); @@ -1165,7 +1136,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); $Dispatcher->base = false; - $url = 'my_plugin/param:value/param2:value2'; + $url = new CakeRequest('my_plugin/param:value/param2:value2'); try { $controller = $Dispatcher->dispatch($url, array('return'=> 1)); $this->fail('No exception.'); @@ -1188,7 +1159,7 @@ class DispatcherTest extends CakeTestCase { $Dispatcher = new TestDispatcher(); - $url = 'test_dispatch_pages/admin_index/param:value/param2:value2'; + $url = new CakeRequest('test_dispatch_pages/admin_index/param:value/param2:value2'); try { $controller = $Dispatcher->dispatch($url, array('return'=> 1)); $this->fail('No exception.'); @@ -1214,7 +1185,7 @@ class DispatcherTest extends CakeTestCase { Router::reload(); Router::parse('/'); - $url = '/test_plugin/tests/index'; + $url = new CakeRequest('/test_plugin/tests/index'); $result = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertTrue(class_exists('TestsController')); $this->assertTrue(class_exists('TestPluginAppController')); @@ -1235,7 +1206,7 @@ class DispatcherTest extends CakeTestCase { public function testChangingParamsFromBeforeFilter() { $_SERVER['PHP_SELF'] = '/cake/repo/branches/1.2.x.x/index.php'; $Dispatcher = new TestDispatcher(); - $url = 'some_posts/index/param:value/param2:value2'; + $url = new CakeRequest('some_posts/index/param:value/param2:value2'); try { $controller = $Dispatcher->dispatch($url, array('return'=> 1)); @@ -1244,7 +1215,7 @@ class DispatcherTest extends CakeTestCase { $this->assertEquals('Action SomePostsController::view() could not be found.', $e->getMessage()); } - $url = 'some_posts/something_else/param:value/param2:value2'; + $url = new CakeRequest('some_posts/something_else/param:value/param2:value2'); $controller = $Dispatcher->dispatch($url, array('return' => 1)); $expected = 'SomePosts'; @@ -1275,21 +1246,21 @@ class DispatcherTest extends CakeTestCase { $Dispatcher->response = $this->getMock('CakeResponse', array('_sendHeader')); try { - $Dispatcher->dispatch('theme/test_theme/../webroot/css/test_asset.css'); + $Dispatcher->dispatch(new CakeRequest('theme/test_theme/../webroot/css/test_asset.css')); $this->fail('No exception'); } catch (MissingControllerException $e) { $this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage()); } try { - $Dispatcher->dispatch('theme/test_theme/pdfs'); + $Dispatcher->dispatch(new CakeRequest('theme/test_theme/pdfs')); $this->fail('No exception'); } catch (MissingControllerException $e) { $this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage()); } ob_start(); - $Dispatcher->dispatch('theme/test_theme/flash/theme_test.swf'); + $Dispatcher->dispatch(new CakeRequest('theme/test_theme/flash/theme_test.swf')); $result = ob_get_clean(); $file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS . 'webroot' . DS . 'flash' . DS . 'theme_test.swf'); @@ -1297,14 +1268,14 @@ class DispatcherTest extends CakeTestCase { $this->assertEqual('this is just a test to load swf file from the theme.', $result); ob_start(); - $Dispatcher->dispatch('theme/test_theme/pdfs/theme_test.pdf'); + $Dispatcher->dispatch(new CakeRequest('theme/test_theme/pdfs/theme_test.pdf')); $result = ob_get_clean(); $file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS . 'webroot' . DS . 'pdfs' . DS . 'theme_test.pdf'); $this->assertEqual($file, $result); $this->assertEqual('this is just a test to load pdf file from the theme.', $result); ob_start(); - $Dispatcher->dispatch('theme/test_theme/img/test.jpg'); + $Dispatcher->dispatch(new CakeRequest('theme/test_theme/img/test.jpg')); $result = ob_get_clean(); $file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS . 'webroot' . DS . 'img' . DS . 'test.jpg'); $this->assertEqual($file, $result); @@ -1331,14 +1302,14 @@ class DispatcherTest extends CakeTestCase { $this->assertEqual($result, $expected); ob_start(); - $Dispatcher->dispatch('test_plugin/flash/plugin_test.swf'); + $Dispatcher->dispatch(new CakeRequest('test_plugin/flash/plugin_test.swf')); $result = ob_get_clean(); $file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS . 'webroot' . DS . 'flash' . DS . 'plugin_test.swf'); $this->assertEqual($file, $result); $this->assertEqual('this is just a test to load swf file from the plugin.', $result); ob_start(); - $Dispatcher->dispatch('test_plugin/pdfs/plugin_test.pdf'); + $Dispatcher->dispatch(new CakeRequest('test_plugin/pdfs/plugin_test.pdf')); $result = ob_get_clean(); $file = file_get_contents(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS . 'webroot' . DS . 'pdfs' . DS . 'plugin_test.pdf'); $this->assertEqual($file, $result); @@ -1411,8 +1382,6 @@ class DispatcherTest extends CakeTestCase { $Dispatcher->asset('ccss/cake.generic.css'); $result = ob_get_clean(); $this->assertTrue($Dispatcher->stopped); - - } /** @@ -1471,14 +1440,14 @@ class DispatcherTest extends CakeTestCase { ), true); $dispatcher = new TestDispatcher(); - $url = '/'; + $request = new CakeRequest('/'); ob_start(); - $dispatcher->dispatch($url); + $dispatcher->dispatch($request); $out = ob_get_clean(); ob_start(); - $dispatcher->cached($url); + $dispatcher->cached($request); $cached = ob_get_clean(); $result = str_replace(array("\t", "\r\n", "\n"), "", $out); @@ -1490,17 +1459,17 @@ class DispatcherTest extends CakeTestCase { $filename = $this->__cachePath($dispatcher->here); unlink($filename); - $url = 'test_cached_pages/index'; + $request = new CakeRequest('test_cached_pages/index'); $_POST = array( 'slasher' => "Up in your's grill \ '" ); ob_start(); - $dispatcher->dispatch($url); + $dispatcher->dispatch($request); $out = ob_get_clean(); ob_start(); - $dispatcher->cached($url); + $dispatcher->cached($request); $cached = ob_get_clean(); $result = str_replace(array("\t", "\r\n", "\n"), "", $out); @@ -1511,14 +1480,14 @@ class DispatcherTest extends CakeTestCase { $filename = $this->__cachePath($dispatcher->here); unlink($filename); - $url = 'TestCachedPages/index'; + $request = new CakeRequest('TestCachedPages/index'); ob_start(); - $dispatcher->dispatch($url); + $dispatcher->dispatch($request); $out = ob_get_clean(); ob_start(); - $dispatcher->cached($url); + $dispatcher->cached($request); $cached = ob_get_clean(); $result = str_replace(array("\t", "\r\n", "\n"), "", $out); @@ -1529,14 +1498,14 @@ class DispatcherTest extends CakeTestCase { $filename = $this->__cachePath($dispatcher->here); unlink($filename); - $url = 'TestCachedPages/test_nocache_tags'; + $request = new CakeRequest('TestCachedPages/test_nocache_tags'); ob_start(); - $dispatcher->dispatch($url); + $dispatcher->dispatch($request); $out = ob_get_clean(); ob_start(); - $dispatcher->cached($url); + $dispatcher->cached($request); $cached = ob_get_clean(); $result = str_replace(array("\t", "\r\n", "\n"), "", $out); @@ -1547,14 +1516,14 @@ class DispatcherTest extends CakeTestCase { $filename = $this->__cachePath($dispatcher->here); unlink($filename); - $url = 'test_cached_pages/view/param/param'; + $request = new CakeRequest('test_cached_pages/view/param/param'); ob_start(); - $dispatcher->dispatch($url); + $dispatcher->dispatch($request); $out = ob_get_clean(); ob_start(); - $dispatcher->cached($url); + $dispatcher->cached($request); $cached = ob_get_clean(); $result = str_replace(array("\t", "\r\n", "\n"), "", $out); @@ -1565,14 +1534,14 @@ class DispatcherTest extends CakeTestCase { $filename = $this->__cachePath($dispatcher->here); unlink($filename); - $url = 'test_cached_pages/view/foo:bar/value:goo'; + $request = new CakeRequest('test_cached_pages/view/foo:bar/value:goo'); ob_start(); - $dispatcher->dispatch($url); + $dispatcher->dispatch($request); $out = ob_get_clean(); ob_start(); - $dispatcher->cached($url); + $dispatcher->cached($request); $cached = ob_get_clean(); $result = str_replace(array("\t", "\r\n", "\n"), "", $out); From 55cc3296abc6ca018b48bf798ed0f17bf5a37f1c Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 00:59:45 -0500 Subject: [PATCH 068/160] Making the Debugger tests pass when you have debug = 0 in your config file. Tests are runnable while debug = 0 from CLI. --- cake/tests/cases/libs/debugger.test.php | 1 + 1 file changed, 1 insertion(+) diff --git a/cake/tests/cases/libs/debugger.test.php b/cake/tests/cases/libs/debugger.test.php index 245b128cd..d29ee6093 100644 --- a/cake/tests/cases/libs/debugger.test.php +++ b/cake/tests/cases/libs/debugger.test.php @@ -47,6 +47,7 @@ class DebuggerTest extends CakeTestCase { */ function setUp() { parent::setup(); + Configure::write('debug', 2); Configure::write('log', false); } From f02e0483ee5202aa26bfa857deaae078837d0e35 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 01:01:11 -0500 Subject: [PATCH 069/160] Reworking parameter munging specific to requestAction into requestAction. Updating tests cases for Object. As request->data is an array() not null. And leading / is trimmed off of [url][url]. --- cake/libs/dispatcher.php | 27 --------------------------- cake/libs/object.php | 20 ++++++++++++++++---- cake/tests/cases/libs/object.test.php | 11 +++++++---- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index 67b31de0b..db0a31f91 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -87,19 +87,8 @@ class Dispatcher { * are encountered. */ public function dispatch(CakeRequest $request, $additionalParams = array()) { - /* Should move to Object::requestAction() - if (is_array($url)) { - $url = $this->_extractParams($url, $additionalParams); - } - if ($url instanceof CakeRequest) { - $request = $url; - } else { - $request = new CakeRequest($url); - } - */ $this->here = $request->here; - if ($this->asset($request->url) || $this->cached($request->url)) { return; } @@ -180,22 +169,6 @@ class Dispatcher { $response->send(); } -/** - * Sets the params when $url is passed as an array to Object::requestAction(); - * Merges the $url and $additionalParams and creates a string url. - * - * @param array $url Array or request parameters - * @param array $additionalParams Array of additional parameters. - * @return string $url The generated url string. - */ - protected function _extractParams($url, $additionalParams = array()) { - $defaults = array('pass' => array(), 'named' => array(), 'form' => array()); - $params = array_merge($defaults, $url, $additionalParams); - - $params += array('base' => false, 'url' => array()); - return ltrim(Router::reverse($params), '/'); - } - /** * Returns array of GET and POST parameters. GET parameters are taken from given URL. * diff --git a/cake/libs/object.php b/cake/libs/object.php index 82ed11fe7..036917c1c 100644 --- a/cake/libs/object.php +++ b/cake/libs/object.php @@ -67,7 +67,7 @@ class Object { return false; } if (!class_exists('dispatcher')) { - require CAKE . 'dispatcher.php'; + require LIBS . 'dispatcher.php'; } if (in_array('return', $extra, true)) { $extra = array_merge($extra, array('return' => 0, 'autoRender' => 1)); @@ -75,9 +75,21 @@ class Object { if (is_array($url) && !isset($extra['url'])) { $extra['url'] = array(); } - $params = array_merge(array('autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1), $extra); - $dispatcher = new Dispatcher; - return $dispatcher->dispatch($url, $params); + $extra = array_merge(array('autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1), $extra); + + if (is_string($url)) { + $request = new CakeRequest($url); + } elseif (is_array($url)) { + $params = $url + array('pass' => array(), 'named' => array(), 'base' => false); + $params = array_merge($params, $extra); + $request = new CakeRequest(Router::reverse($params), false); + if (isset($params['data'])) { + $request->data = $params['data']; + } + } + + $dispatcher = new Dispatcher(); + return $dispatcher->dispatch($request, $extra); } /** diff --git a/cake/tests/cases/libs/object.test.php b/cake/tests/cases/libs/object.test.php index fe903a8fc..a371cf9f2 100644 --- a/cake/tests/cases/libs/object.test.php +++ b/cake/tests/cases/libs/object.test.php @@ -716,7 +716,7 @@ class ObjectTest extends CakeTestCase { $result = $this->object->requestAction('/request_action/normal_request_action'); $expected = 'Hello World'; $this->assertEqual($result, $expected); - + App::build(); } @@ -824,7 +824,7 @@ class ObjectTest extends CakeTestCase { function testRequestActionParamParseAndPass() { $result = $this->object->requestAction('/request_action/params_pass'); $this->assertTrue(isset($result['url']['url'])); - $this->assertEqual($result['url']['url'], '/request_action/params_pass'); + $this->assertEqual($result['url']['url'], 'request_action/params_pass'); $this->assertEqual($result['controller'], 'request_action'); $this->assertEqual($result['action'], 'params_pass'); $this->assertEqual($result['form'], array()); @@ -855,9 +855,12 @@ class ObjectTest extends CakeTestCase { )); $result = $this->object->requestAction(array('controller' => 'request_action', 'action' => 'post_pass')); $expected = null; - $this->assertEqual($expected, $result); + $this->assertEmpty($result); - $result = $this->object->requestAction(array('controller' => 'request_action', 'action' => 'post_pass'), array('data' => $_POST['data'])); + $result = $this->object->requestAction( + array('controller' => 'request_action', 'action' => 'post_pass'), + array('data' => $_POST['data']) + ); $expected = $_POST['data']; $this->assertEqual($expected, $result); From f36f38e7f671363caabb69b88993d6093e1f1543 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 01:05:42 -0500 Subject: [PATCH 070/160] Adding doc blocks and adding type hints for _invoke(). --- cake/libs/dispatcher.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index db0a31f91..0485b1c5c 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -131,12 +131,12 @@ class Dispatcher { * Triggers the controller action, and invokes the rendering if Controller::$autoRender is true and echo's the output. * Otherwise the return value of the controller action are returned. * - * @param object $controller Controller to invoke - * @param array $params Parameters with at least the 'action' to invoke - * @param boolean $missingAction Set to true if missing action should be rendered, false otherwise + * @param Controller $controller Controller to invoke + * @param CakeRequest $request The request object to invoke the controller for. * @return string Output as sent by controller + * @throws MissingActionException when the action being called is missing. */ - protected function _invoke(&$controller, $request) { + protected function _invoke(Controller $controller, CakeRequest $request) { $controller->constructClasses(); $controller->startupProcess(); From f27566336c10af82d198d71ae51bb567cd89da81 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 01:08:13 -0500 Subject: [PATCH 071/160] Renaming private method to protected. Removing return by reference operator. --- cake/libs/dispatcher.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index 0485b1c5c..95ea8055f 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -195,9 +195,9 @@ class Dispatcher { * @param array $params Array of parameters * @return mixed name of controller if not loaded, or object if loaded */ - protected function &_getController($request) { + protected function _getController($request) { $controller = false; - $ctrlClass = $this->__loadController($request); + $ctrlClass = $this->_loadController($request); if (!$ctrlClass) { return $controller; } @@ -213,9 +213,8 @@ class Dispatcher { * * @param array $params Array of parameters * @return string|bool Name of controller class name - * @access private */ - function __loadController($request) { + protected function _loadController($request) { $pluginName = $pluginPath = $controller = null; if (!empty($request->params['plugin'])) { $pluginName = $controller = Inflector::camelize($request->params['plugin']); From afd2683602029bcb0361a369a60031223b6714df Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 01:12:39 -0500 Subject: [PATCH 072/160] Adding a check for loaded routes. This prevents routes being loaded on each dispatched action, such as when requestAction is called. --- cake/libs/dispatcher.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index 95ea8055f..e9aff026a 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -176,9 +176,11 @@ class Dispatcher { * @return array Parameters found in POST and GET. */ public function parseParams(CakeRequest $request, $additionalParams = array()) { - $namedExpressions = Router::getNamedExpressions(); - extract($namedExpressions); - include CONFIGS . 'routes.php'; + if (count(Router::$routes) > 0) { + $namedExpressions = Router::getNamedExpressions(); + extract($namedExpressions); + include CONFIGS . 'routes.php'; + } $params = Router::parse($request->url); $request->addParams($params); From cb4dfc4ee0bd0446e7725b9d3f71cdab1c61dcc6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 11:34:10 -0500 Subject: [PATCH 073/160] Changing import() to require, as its a fraction faster. --- app/webroot/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/webroot/index.php b/app/webroot/index.php index 8763a4f7a..35ebed025 100644 --- a/app/webroot/index.php +++ b/app/webroot/index.php @@ -74,7 +74,7 @@ if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') { return; } else { - App::import('Core', 'Dispatcher'); + require LIBS . 'dispatcher.php'; $Dispatcher = new Dispatcher(); $Dispatcher->dispatch(new CakeRequest($_GET['url'])); } From 8e29595b638216f46b07b1dfae4eb2b6fc47f409 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 12:48:52 -0500 Subject: [PATCH 074/160] Updating test.php to bootstrap like index.php Updating skel file to match app one. --- app/webroot/test.php | 9 ++------- cake/console/templates/skel/webroot/index.php | 13 ++++--------- cake/console/templates/skel/webroot/test.php | 9 ++------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/app/webroot/test.php b/app/webroot/test.php index b04b4a463..7a27e8e29 100644 --- a/app/webroot/test.php +++ b/app/webroot/test.php @@ -65,13 +65,8 @@ if (!defined('WWW_ROOT')) { define('WWW_ROOT', dirname(__FILE__) . DS); } if (!defined('CORE_PATH')) { - if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) { - define('APP_PATH', null); - define('CORE_PATH', null); - } else { - define('APP_PATH', ROOT . DS . APP_DIR . DS); - define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); - } + define('APP_PATH', ROOT . DS . APP_DIR . DS); + define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); } if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) { trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); diff --git a/cake/console/templates/skel/webroot/index.php b/cake/console/templates/skel/webroot/index.php index b2ddf4020..35ebed025 100644 --- a/cake/console/templates/skel/webroot/index.php +++ b/cake/console/templates/skel/webroot/index.php @@ -65,13 +65,8 @@ define('WWW_ROOT', dirname(__FILE__) . DS); } if (!defined('CORE_PATH')) { - if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) { - define('APP_PATH', null); - define('CORE_PATH', null); - } else { - define('APP_PATH', ROOT . DS . APP_DIR . DS); - define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); - } + define('APP_PATH', ROOT . DS . APP_DIR . DS); + define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); } if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) { trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); @@ -79,7 +74,7 @@ if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') { return; } else { - require CAKE . 'dispatcher.php'; + require LIBS . 'dispatcher.php'; $Dispatcher = new Dispatcher(); - $Dispatcher->dispatch(); + $Dispatcher->dispatch(new CakeRequest($_GET['url'])); } diff --git a/cake/console/templates/skel/webroot/test.php b/cake/console/templates/skel/webroot/test.php index b04b4a463..7a27e8e29 100644 --- a/cake/console/templates/skel/webroot/test.php +++ b/cake/console/templates/skel/webroot/test.php @@ -65,13 +65,8 @@ if (!defined('WWW_ROOT')) { define('WWW_ROOT', dirname(__FILE__) . DS); } if (!defined('CORE_PATH')) { - if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) { - define('APP_PATH', null); - define('CORE_PATH', null); - } else { - define('APP_PATH', ROOT . DS . APP_DIR . DS); - define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); - } + define('APP_PATH', ROOT . DS . APP_DIR . DS); + define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); } if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) { trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR); From 1b89547c5824dec0068ba5d31aa92bcc9e14988e Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 13:02:17 -0500 Subject: [PATCH 075/160] Pulling App out into its own file. Trying to stick with one class per file conventions. Removing class_exists check, as Set is loaded during the framework bootstrap. --- cake/bootstrap.php | 1 + cake/libs/app.php | 879 ++++++++++++++++++++++++++++++++++++++++ cake/libs/configure.php | 869 +-------------------------------------- 3 files changed, 882 insertions(+), 867 deletions(-) create mode 100644 cake/libs/app.php diff --git a/cake/bootstrap.php b/cake/bootstrap.php index 5a1bb4385..105d3ae4c 100644 --- a/cake/bootstrap.php +++ b/cake/bootstrap.php @@ -29,6 +29,7 @@ require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php'; require LIBS . 'exceptions.php'; require LIBS . 'object.php'; require LIBS . 'inflector.php'; +require LIBS . 'app.php'; require LIBS . 'configure.php'; require LIBS . 'set.php'; require LIBS . 'cache.php'; diff --git a/cake/libs/app.php b/cake/libs/app.php new file mode 100644 index 000000000..0d6ae1608 --- /dev/null +++ b/cake/libs/app.php @@ -0,0 +1,879 @@ + array('suffix' => '.php', 'extends' => null, 'core' => true), + 'file' => array('suffix' => '.php', 'extends' => null, 'core' => true), + 'model' => array('suffix' => '.php', 'extends' => 'AppModel', 'core' => false), + 'behavior' => array('suffix' => '.php', 'extends' => 'ModelBehavior', 'core' => true), + 'controller' => array('suffix' => '_controller.php', 'extends' => 'AppController', 'core' => true), + 'component' => array('suffix' => '.php', 'extends' => null, 'core' => true), + 'lib' => array('suffix' => '.php', 'extends' => null, 'core' => true), + 'view' => array('suffix' => '.php', 'extends' => null, 'core' => true), + 'helper' => array('suffix' => '.php', 'extends' => 'AppHelper', 'core' => true), + 'vendor' => array('suffix' => '', 'extends' => null, 'core' => true), + 'shell' => array('suffix' => '.php', 'extends' => 'Shell', 'core' => true), + 'plugin' => array('suffix' => '', 'extends' => null, 'core' => true) + ); + +/** + * List of additional path(s) where model files reside. + * + * @var array + */ + public static $models = array(); + +/** + * List of additional path(s) where behavior files reside. + * + * @var array + */ + public static $behaviors = array(); + +/** + * List of additional path(s) where controller files reside. + * + * @var array + */ + public static $controllers = array(); + +/** + * List of additional path(s) where component files reside. + * + * @var array + */ + public static $components = array(); + +/** + * List of additional path(s) where datasource files reside. + * + * @var array + */ + public static $datasources = array(); + +/** + * List of additional path(s) where libs files reside. + * + * @var array + */ + public static $libs = array(); + +/** + * List of additional path(s) where view files reside. + * + * @var array + */ + public static $views = array(); + +/** + * List of additional path(s) where helper files reside. + * + * @var array + */ + public static $helpers = array(); + +/** + * List of additional path(s) where plugins reside. + * + * @var array + */ + public static $plugins = array(); + +/** + * List of additional path(s) where vendor packages reside. + * + * @var array + */ + public static $vendors = array(); + +/** + * List of additional path(s) where locale files reside. + * + * @var array + */ + public static $locales = array(); + +/** + * List of additional path(s) where console shell files reside. + * + * @var array + */ + public static $shells = array(); + +/** + * Paths to search for files. + * + * @var array + */ + public static $search = array(); + +/** + * Whether or not to return the file that is loaded. + * + * @var boolean + */ + public static $return = false; + +/** + * Determines if $__maps and $__paths cache should be written. + * + * @var boolean + */ + private static $__cache = false; + +/** + * Holds key/value pairs of $type => file path. + * + * @var array + */ + private static $__map = array(); + +/** + * Holds paths for deep searching of files. + * + * @var array + */ + private static $__paths = array(); + +/** + * Holds loaded files. + * + * @var array + */ + private static $__loaded = array(); + +/** + * Holds and key => value array of object types. + * + * @var array + */ + private static $__objects = array(); + +/** + * Used to read information stored path + * + * Usage: + * + * `App::path('models'); will return all paths for models` + * + * @param string $type type of path + * @return string array + */ + public static function path($type) { + if (!isset(self::${$type})) { + return array(); + } + return self::${$type}; + } + +/** + * Build path references. Merges the supplied $paths + * with the base paths and the default core paths. + * + * @param array $paths paths defines in config/bootstrap.php + * @param boolean $reset true will set paths, false merges paths [default] false + * @return void + */ + public static function build($paths = array(), $reset = false) { + $defaults = array( + 'models' => array(MODELS), + 'behaviors' => array(BEHAVIORS), + 'datasources' => array(MODELS . 'datasources'), + 'controllers' => array(CONTROLLERS), + 'components' => array(COMPONENTS), + 'libs' => array(APPLIBS), + 'views' => array(VIEWS), + 'helpers' => array(HELPERS), + 'locales' => array(APP . 'locale' . DS), + 'shells' => array( + APP . 'console' . DS . 'shells' . DS, + APP . 'vendors' . DS . 'shells' . DS, + VENDORS . 'shells' . DS + ), + 'vendors' => array(APP . 'vendors' . DS, VENDORS), + 'plugins' => array(APP . 'plugins' . DS) + ); + + if ($reset == true) { + foreach ($paths as $type => $new) { + self::${$type} = (array)$new; + } + return $paths; + } + + $core = self::core(); + $app = array('models' => true, 'controllers' => true, 'helpers' => true); + + foreach ($defaults as $type => $default) { + $merge = array(); + + if (isset($app[$type])) { + $merge = array(APP); + } + if (isset($core[$type])) { + $merge = array_merge($merge, (array)$core[$type]); + } + + if (empty(self::${$type}) || empty($paths)) { + self::${$type} = $default; + } + + if (!empty($paths[$type])) { + $path = array_flip(array_flip(array_merge( + (array)$paths[$type], self::${$type}, $merge + ))); + self::${$type} = array_values($path); + } else { + $path = array_flip(array_flip(array_merge(self::${$type}, $merge))); + self::${$type} = array_values($path); + } + } + } + +/** + * Get the path that a plugin is on. Searches through the defined plugin paths. + * + * @param string $plugin CamelCased/lower_cased plugin name to find the path of. + * @return string full path to the plugin. + */ + public static function pluginPath($plugin) { + $pluginDir = Inflector::underscore($plugin); + for ($i = 0, $length = count(self::$plugins); $i < $length; $i++) { + if (is_dir(self::$plugins[$i] . $pluginDir)) { + return self::$plugins[$i] . $pluginDir . DS ; + } + } + return self::$plugins[0] . $pluginDir . DS; + } + +/** + * Find the path that a theme is on. Search through the defined theme paths. + * + * @param string $theme lower_cased theme name to find the path of. + * @return string full path to the theme. + */ + public static function themePath($theme) { + $themeDir = 'themed' . DS . Inflector::underscore($theme); + for ($i = 0, $length = count(self::$views); $i < $length; $i++) { + if (is_dir(self::$views[$i] . $themeDir)) { + return self::$views[$i] . $themeDir . DS ; + } + } + return self::$views[0] . $themeDir . DS; + } + +/** + * Returns a key/value list of all paths where core libs are found. + * Passing $type only returns the values for a given value of $key. + * + * @param string $type valid values are: 'model', 'behavior', 'controller', 'component', + * 'view', 'helper', 'datasource', 'libs', and 'cake' + * @return array numeric keyed array of core lib paths + */ + 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; + $cake = dirname($libs) . DS; + $path = dirname($cake) . DS; + + $paths['cake'][] = $cake; + $paths['libs'][] = $libs; + $paths['models'][] = $libs . 'model' . DS; + $paths['datasources'][] = $libs . 'model' . DS . 'datasources' . DS; + $paths['behaviors'][] = $libs . 'model' . DS . 'behaviors' . DS; + $paths['controllers'][] = $libs . 'controller' . DS; + $paths['components'][] = $libs . 'controller' . DS . 'components' . DS; + $paths['views'][] = $libs . 'view' . DS; + $paths['helpers'][] = $libs . 'view' . DS . 'helpers' . DS; + $paths['plugins'][] = $path . 'plugins' . DS; + $paths['vendors'][] = $path . 'vendors' . DS; + $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]; + } + return $paths; + } + +/** + * Returns an array of objects of the given type. + * + * Example usage: + * + * `App::objects('plugin');` returns `array('DebugKit', 'Blog', 'User');` + * + * @param string $type Type of object, i.e. 'model', 'controller', 'helper', or 'plugin' + * @param mixed $path Optional Scan only the path given. If null, paths for the chosen + * type will be used. + * @param boolean $cache Set to false to rescan objects of the chosen type. Defaults to true. + * @return mixed Either false on incorrect / miss. Or an array of found objects. + */ + public static function objects($type, $path = null, $cache = true) { + $objects = array(); + $extension = false; + $name = $type; + + if ($type === 'file' && !$path) { + return false; + } elseif ($type === 'file') { + $extension = true; + $name = $type . str_replace(DS, '', $path); + } + + if (empty(self::$__objects) && $cache === true) { + self::$__objects = Cache::read('object_map', '_cake_core_'); + } + + if (!isset(self::$__objects[$name]) || $cache !== true) { + $types = self::$types; + + if (!isset($types[$type])) { + return false; + } + $objects = array(); + + if (empty($path)) { + $path = self::${"{$type}s"}; + if (isset($types[$type]['core']) && $types[$type]['core'] === false) { + array_pop($path); + } + } + $items = array(); + + foreach ((array)$path as $dir) { + if ($dir != APP) { + $items = self::__list($dir, $types[$type]['suffix'], $extension); + $objects = array_merge($items, array_diff($objects, $items)); + } + } + + if ($type !== 'file') { + foreach ($objects as $key => $value) { + $objects[$key] = Inflector::camelize($value); + } + } + + if ($cache === true) { + self::$__cache = true; + } + self::$__objects[$name] = $objects; + } + + return self::$__objects[$name]; + } + +/** + * Allows you to modify the object listings that App maintains inside of it + * Useful for testing + * + * @param string $type Type of object listing you are changing + * @param array $values The values $type should be set to. + * @return void + */ + public static function setObjects($type, $values) { + self::$__objects[$type] = $values; + } + +/** + * Finds classes based on $name or specific file(s) to search. Calling App::import() will + * not construct any classes contained in the files. It will only find and require() the file. + * + * @link http://book.cakephp.org/view/934/Using-App-import + * @param mixed $type The type of Class if passed as a string, or all params can be passed as + * an single array to $type, + * @param string $name Name of the Class or a unique name for the file + * @param mixed $parent boolean true if Class Parent should be searched, accepts key => value + * array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext'); + * $ext allows setting the extension of the file name + * based on Inflector::underscore($name) . ".$ext"; + * @param array $search paths to search for files, array('path 1', 'path 2', 'path 3'); + * @param string $file full name of the file to search for including extension + * @param boolean $return, return the loaded file, the file must have a return + * statement in it to work: return $variable; + * @return boolean true if Class is already in memory or if file is found and loaded, false if not + */ + public static function import($type = null, $name = null, $parent = true, $search = array(), $file = null, $return = false) { + $plugin = $directory = null; + + if (is_array($type)) { + extract($type, EXTR_OVERWRITE); + } + + if (is_array($parent)) { + extract($parent, EXTR_OVERWRITE); + } + + if ($name === null && $file === null) { + $name = $type; + $type = 'Core'; + } elseif ($name === null) { + $type = 'File'; + } + + if (is_array($name)) { + foreach ($name as $class) { + $tempType = $type; + $plugin = null; + + if (strpos($class, '.') !== false) { + $value = explode('.', $class); + $count = count($value); + + if ($count > 2) { + $tempType = $value[0]; + $plugin = $value[1] . '.'; + $class = $value[2]; + } elseif ($count === 2 && ($type === 'Core' || $type === 'File')) { + $tempType = $value[0]; + $class = $value[1]; + } else { + $plugin = $value[0] . '.'; + $class = $value[1]; + } + } + + if (!App::import($tempType, $plugin . $class, $parent)) { + return false; + } + } + return true; + } + + if ($name != null && strpos($name, '.') !== false) { + list($plugin, $name) = explode('.', $name); + $plugin = Inflector::camelize($plugin); + } + self::$return = $return; + + if (isset($ext)) { + $file = Inflector::underscore($name) . ".{$ext}"; + } + $ext = self::__settings($type, $plugin, $parent); + 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); + } + return true; + } else { + self::__remove($name . $ext['class'], $type, $plugin); + self::$__cache = true; + } + } + if (!empty($search)) { + self::$search = $search; + } elseif ($plugin) { + self::$search = self::__paths('plugin'); + } else { + self::$search = self::__paths($type); + } + $find = $file; + + if ($find === null) { + $find = Inflector::underscore($name . $ext['suffix']).'.php'; + + if ($plugin) { + $paths = self::$search; + foreach ($paths as $key => $value) { + self::$search[$key] = $value . $ext['path']; + } + } + } + + if (strtolower($type) !== 'vendor' && empty($search) && self::__load($file)) { + $directory = false; + } else { + $file = $find; + $directory = self::__find($find, true); + } + + 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); + } + return true; + } + return false; + } + return true; + } + +/** + * Initializes the cache for App, registers a shutdown function. + * + * @return void + */ + public static function init() { + self::$__map = (array)Cache::read('file_map', '_cake_core_'); + register_shutdown_function(array('App', 'shutdown')); + } + +/** + * Locates the $file in $__paths, searches recursively. + * + * @param string $file full file name + * @param boolean $recursive search $__paths recursively + * @return mixed boolean on fail, $file directory path on success + */ + private static function __find($file, $recursive = true) { + static $appPath = false; + + if (empty(self::$search)) { + return null; + } elseif (is_string(self::$search)) { + $this->search = array(self::$search); + } + + if (empty(self::$__paths)) { + self::$__paths = Cache::read('dir_map', '_cake_core_'); + } + + foreach (self::$search as $path) { + if ($appPath === false) { + $appPath = rtrim(APP, DS); + } + $path = rtrim($path, DS); + + if ($path === $appPath) { + $recursive = false; + } + if ($recursive === false) { + if (self::__load($path . DS . $file)) { + return $path . DS; + } + continue; + } + + if (!isset(self::$__paths[$path])) { + if (!class_exists('Folder')) { + require LIBS . 'folder.php'; + } + $Folder = new Folder(); + $directories = $Folder->tree($path, array('.svn', '.git', 'CVS', 'tests', 'templates'), 'dir'); + sort($directories); + self::$__paths[$path] = $directories; + } + + foreach (self::$__paths[$path] as $directory) { + if (self::__load($directory . DS . $file)) { + return $directory . DS; + } + } + } + return null; + } + +/** + * Attempts to load $file. + * + * @param string $file full path to file including file name + * @return boolean + * @access private + */ + private static function __load($file) { + if (empty($file)) { + return false; + } + if (!self::$return && isset(self::$__loaded[$file])) { + return true; + } + if (file_exists($file)) { + if (!self::$return) { + require($file); + self::$__loaded[$file] = true; + } + return true; + } + return false; + } + +/** + * Maps the $name to the $file. + * + * @param string $file full path to file + * @param string $name unique name for this map + * @param string $type type object being mapped + * @param string $plugin camelized if object is from a plugin, the name of the plugin + * @return void + * @access private + */ + private static function __map($file, $name, $type, $plugin) { + if ($plugin) { + self::$__map['Plugin'][$plugin][$type][$name] = $file; + } else { + self::$__map[$type][$name] = $file; + } + } + +/** + * Returns a file's complete path. + * + * @param string $name unique name + * @param string $type type object + * @param string $plugin camelized if object is from a plugin, the name of the plugin + * @return mixed, file path if found, false otherwise + * @access private + */ + private static function __mapped($name, $type, $plugin) { + if ($plugin) { + if (isset(self::$__map['Plugin'][$plugin][$type]) && isset(self::$__map['Plugin'][$plugin][$type][$name])) { + return self::$__map['Plugin'][$plugin][$type][$name]; + } + return false; + } + + if (isset(self::$__map[$type]) && isset(self::$__map[$type][$name])) { + return self::$__map[$type][$name]; + } + 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. + * + * @param string $type type of object + * @param string $plugin camelized name of plugin + * @param boolean $parent false will not attempt to load parent + * @return array + * @access private + */ + private static function __settings($type, $plugin, $parent) { + if (!$parent) { + return array('class' => null, 'suffix' => null, 'path' => null); + } + + if ($plugin) { + $pluginPath = Inflector::underscore($plugin); + } + $path = null; + $load = strtolower($type); + + switch ($load) { + case 'model': + if (!class_exists('Model')) { + require LIBS . 'model' . DS . 'model.php'; + } + if (!class_exists('AppModel')) { + App::import($type, 'AppModel', false); + } + if ($plugin) { + if (!class_exists($plugin . 'AppModel')) { + App::import($type, $plugin . '.' . $plugin . 'AppModel', false, array(), $pluginPath . DS . $pluginPath . '_app_model.php'); + } + $path = $pluginPath . DS . 'models' . DS; + } + return array('class' => null, 'suffix' => null, 'path' => $path); + break; + case 'behavior': + if ($plugin) { + $path = $pluginPath . DS . 'models' . DS . 'behaviors' . DS; + } + return array('class' => $type, 'suffix' => null, 'path' => $path); + break; + case 'datasource': + if ($plugin) { + $path = $pluginPath . DS . 'models' . DS . 'datasources' . DS; + } + return array('class' => $type, 'suffix' => null, 'path' => $path); + case 'controller': + App::import($type, 'AppController', false); + if ($plugin) { + App::import($type, $plugin . '.' . $plugin . 'AppController', false, array(), $pluginPath . DS . $pluginPath . '_app_controller.php'); + $path = $pluginPath . DS . 'controllers' . DS; + } + return array('class' => $type, 'suffix' => $type, 'path' => $path); + break; + case 'component': + App::import('Core', 'Component', false); + if ($plugin) { + $path = $pluginPath . DS . 'controllers' . DS . 'components' . DS; + } + return array('class' => $type, 'suffix' => null, 'path' => $path); + break; + case 'lib': + if ($plugin) { + $path = $pluginPath . DS . 'libs' . DS; + } + return array('class' => null, 'suffix' => null, 'path' => $path); + break; + case 'view': + App::import('View', 'View', false); + if ($plugin) { + $path = $pluginPath . DS . 'views' . DS; + } + return array('class' => $type, 'suffix' => null, 'path' => $path); + break; + case 'helper': + if (!class_exists('AppHelper')) { + App::import($type, 'AppHelper', false); + } + if ($plugin) { + $path = $pluginPath . DS . 'views' . DS . 'helpers' . DS; + } + return array('class' => $type, 'suffix' => null, 'path' => $path); + break; + case 'shell': + if (!class_exists('Shell')) { + App::import($type, 'Shell', false); + } + if ($plugin) { + $path = $pluginPath . DS . 'console' . DS . 'shells' . DS; + } + return array('class' => $type, 'suffix' => null, 'path' => $path); + break; + case 'vendor': + if ($plugin) { + $path = $pluginPath . DS . 'vendors' . DS; + } + return array('class' => null, 'suffix' => null, 'path' => $path); + break; + default: + $type = $suffix = $path = null; + break; + } + return array('class' => null, 'suffix' => null, 'path' => null); + } + +/** + * Returns default search paths. + * + * @param string $type type of object to be searched + * @return array list of paths + */ + private static function __paths($type) { + $type = strtolower($type); + $paths = array(); + + if ($type === 'core') { + return App::core('libs'); + } + if (isset(self::${$type . 's'})) { + return self::${$type . 's'}; + } + return $paths; + } + +/** + * Removes file location from map if the file has been deleted. + * + * @param string $name name of object + * @param string $type type of object + * @param string $plugin camelized name of plugin + * @return void + */ + private static function __remove($name, $type, $plugin) { + if ($plugin) { + unset(self::$__map['Plugin'][$plugin][$type][$name]); + } else { + unset(self::$__map[$type][$name]); + } + } + +/** + * Returns an array of filenames of PHP files in the given directory. + * + * @param string $path Path to scan for files + * @param string $suffix if false, return only directories. if string, match and return files + * @return array List of directories or files in directory + */ + private static function __list($path, $suffix = false, $extension = false) { + if (!class_exists('Folder')) { + require LIBS . 'folder.php'; + } + $items = array(); + $Folder = new Folder($path); + $contents = $Folder->read(false, true); + + if (is_array($contents)) { + if (!$suffix) { + return $contents[0]; + } else { + foreach ($contents[1] as $item) { + if (substr($item, - strlen($suffix)) === $suffix) { + if ($extension) { + $items[] = $item; + } else { + $items[] = substr($item, 0, strlen($item) - strlen($suffix)); + } + } + } + } + } + return $items; + } + +/** + * Object destructor. + * + * Writes cache file if changes have been made to the $__map or $__paths + * + * @return void + */ + public static function shutdown() { + if (self::$__cache) { + $core = App::core('cake'); + unset(self::$__paths[rtrim($core[0], DS)]); + Cache::write('dir_map', array_filter(self::$__paths), '_cake_core_'); + Cache::write('file_map', array_filter(self::$__map), '_cake_core_'); + Cache::write('object_map', self::$__objects, '_cake_core_'); + } + } +} diff --git a/cake/libs/configure.php b/cake/libs/configure.php index ff8af76cd..9376c8e4d 100644 --- a/cake/libs/configure.php +++ b/cake/libs/configure.php @@ -1,6 +1,6 @@ array('suffix' => '.php', 'extends' => null, 'core' => true), - 'file' => array('suffix' => '.php', 'extends' => null, 'core' => true), - 'model' => array('suffix' => '.php', 'extends' => 'AppModel', 'core' => false), - 'behavior' => array('suffix' => '.php', 'extends' => 'ModelBehavior', 'core' => true), - 'controller' => array('suffix' => '_controller.php', 'extends' => 'AppController', 'core' => true), - 'component' => array('suffix' => '.php', 'extends' => null, 'core' => true), - 'lib' => array('suffix' => '.php', 'extends' => null, 'core' => true), - 'view' => array('suffix' => '.php', 'extends' => null, 'core' => true), - 'helper' => array('suffix' => '.php', 'extends' => 'AppHelper', 'core' => true), - 'vendor' => array('suffix' => '', 'extends' => null, 'core' => true), - 'shell' => array('suffix' => '.php', 'extends' => 'Shell', 'core' => true), - 'plugin' => array('suffix' => '', 'extends' => null, 'core' => true) - ); - -/** - * List of additional path(s) where model files reside. - * - * @var array - */ - public static $models = array(); - -/** - * List of additional path(s) where behavior files reside. - * - * @var array - */ - public static $behaviors = array(); - -/** - * List of additional path(s) where controller files reside. - * - * @var array - */ - public static $controllers = array(); - -/** - * List of additional path(s) where component files reside. - * - * @var array - */ - public static $components = array(); - -/** - * List of additional path(s) where datasource files reside. - * - * @var array - */ - public static $datasources = array(); - -/** - * List of additional path(s) where libs files reside. - * - * @var array - */ - public static $libs = array(); - -/** - * List of additional path(s) where view files reside. - * - * @var array - */ - public static $views = array(); - -/** - * List of additional path(s) where helper files reside. - * - * @var array - */ - public static $helpers = array(); - -/** - * List of additional path(s) where plugins reside. - * - * @var array - */ - public static $plugins = array(); - -/** - * List of additional path(s) where vendor packages reside. - * - * @var array - */ - public static $vendors = array(); - -/** - * List of additional path(s) where locale files reside. - * - * @var array - */ - public static $locales = array(); - -/** - * List of additional path(s) where console shell files reside. - * - * @var array - */ - public static $shells = array(); - -/** - * Paths to search for files. - * - * @var array - */ - public static $search = array(); - -/** - * Whether or not to return the file that is loaded. - * - * @var boolean - */ - public static $return = false; - -/** - * Determines if $__maps and $__paths cache should be written. - * - * @var boolean - */ - private static $__cache = false; - -/** - * Holds key/value pairs of $type => file path. - * - * @var array - */ - private static $__map = array(); - -/** - * Holds paths for deep searching of files. - * - * @var array - */ - private static $__paths = array(); - -/** - * Holds loaded files. - * - * @var array - */ - private static $__loaded = array(); - -/** - * Holds and key => value array of object types. - * - * @var array - */ - private static $__objects = array(); - -/** - * Used to read information stored path - * - * Usage: - * - * `App::path('models'); will return all paths for models` - * - * @param string $type type of path - * @return string array - */ - public static function path($type) { - if (!isset(self::${$type})) { - return array(); - } - return self::${$type}; - } - -/** - * Build path references. Merges the supplied $paths - * with the base paths and the default core paths. - * - * @param array $paths paths defines in config/bootstrap.php - * @param boolean $reset true will set paths, false merges paths [default] false - * @return void - */ - public static function build($paths = array(), $reset = false) { - $defaults = array( - 'models' => array(MODELS), - 'behaviors' => array(BEHAVIORS), - 'datasources' => array(MODELS . 'datasources'), - 'controllers' => array(CONTROLLERS), - 'components' => array(COMPONENTS), - 'libs' => array(APPLIBS), - 'views' => array(VIEWS), - 'helpers' => array(HELPERS), - 'locales' => array(APP . 'locale' . DS), - 'shells' => array( - APP . 'console' . DS . 'shells' . DS, - APP . 'vendors' . DS . 'shells' . DS, - VENDORS . 'shells' . DS - ), - 'vendors' => array(APP . 'vendors' . DS, VENDORS), - 'plugins' => array(APP . 'plugins' . DS) - ); - - if ($reset == true) { - foreach ($paths as $type => $new) { - self::${$type} = (array)$new; - } - return $paths; - } - - $core = self::core(); - $app = array('models' => true, 'controllers' => true, 'helpers' => true); - - foreach ($defaults as $type => $default) { - $merge = array(); - - if (isset($app[$type])) { - $merge = array(APP); - } - if (isset($core[$type])) { - $merge = array_merge($merge, (array)$core[$type]); - } - - if (empty(self::${$type}) || empty($paths)) { - self::${$type} = $default; - } - - if (!empty($paths[$type])) { - $path = array_flip(array_flip(array_merge( - (array)$paths[$type], self::${$type}, $merge - ))); - self::${$type} = array_values($path); - } else { - $path = array_flip(array_flip(array_merge(self::${$type}, $merge))); - self::${$type} = array_values($path); - } - } - } - -/** - * Get the path that a plugin is on. Searches through the defined plugin paths. - * - * @param string $plugin CamelCased/lower_cased plugin name to find the path of. - * @return string full path to the plugin. - */ - public static function pluginPath($plugin) { - $pluginDir = Inflector::underscore($plugin); - for ($i = 0, $length = count(self::$plugins); $i < $length; $i++) { - if (is_dir(self::$plugins[$i] . $pluginDir)) { - return self::$plugins[$i] . $pluginDir . DS ; - } - } - return self::$plugins[0] . $pluginDir . DS; - } - -/** - * Find the path that a theme is on. Search through the defined theme paths. - * - * @param string $theme lower_cased theme name to find the path of. - * @return string full path to the theme. - */ - public static function themePath($theme) { - $themeDir = 'themed' . DS . Inflector::underscore($theme); - for ($i = 0, $length = count(self::$views); $i < $length; $i++) { - if (is_dir(self::$views[$i] . $themeDir)) { - return self::$views[$i] . $themeDir . DS ; - } - } - return self::$views[0] . $themeDir . DS; - } - -/** - * Returns a key/value list of all paths where core libs are found. - * Passing $type only returns the values for a given value of $key. - * - * @param string $type valid values are: 'model', 'behavior', 'controller', 'component', - * 'view', 'helper', 'datasource', 'libs', and 'cake' - * @return array numeric keyed array of core lib paths - */ - 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; - $cake = dirname($libs) . DS; - $path = dirname($cake) . DS; - - $paths['cake'][] = $cake; - $paths['libs'][] = $libs; - $paths['models'][] = $libs . 'model' . DS; - $paths['datasources'][] = $libs . 'model' . DS . 'datasources' . DS; - $paths['behaviors'][] = $libs . 'model' . DS . 'behaviors' . DS; - $paths['controllers'][] = $libs . 'controller' . DS; - $paths['components'][] = $libs . 'controller' . DS . 'components' . DS; - $paths['views'][] = $libs . 'view' . DS; - $paths['helpers'][] = $libs . 'view' . DS . 'helpers' . DS; - $paths['plugins'][] = $path . 'plugins' . DS; - $paths['vendors'][] = $path . 'vendors' . DS; - $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]; - } - return $paths; - } - -/** - * Returns an array of objects of the given type. - * - * Example usage: - * - * `App::objects('plugin');` returns `array('DebugKit', 'Blog', 'User');` - * - * @param string $type Type of object, i.e. 'model', 'controller', 'helper', or 'plugin' - * @param mixed $path Optional Scan only the path given. If null, paths for the chosen - * type will be used. - * @param boolean $cache Set to false to rescan objects of the chosen type. Defaults to true. - * @return mixed Either false on incorrect / miss. Or an array of found objects. - */ - public static function objects($type, $path = null, $cache = true) { - $objects = array(); - $extension = false; - $name = $type; - - if ($type === 'file' && !$path) { - return false; - } elseif ($type === 'file') { - $extension = true; - $name = $type . str_replace(DS, '', $path); - } - - if (empty(self::$__objects) && $cache === true) { - self::$__objects = Cache::read('object_map', '_cake_core_'); - } - - if (!isset(self::$__objects[$name]) || $cache !== true) { - $types = self::$types; - - if (!isset($types[$type])) { - return false; - } - $objects = array(); - - if (empty($path)) { - $path = self::${"{$type}s"}; - if (isset($types[$type]['core']) && $types[$type]['core'] === false) { - array_pop($path); - } - } - $items = array(); - - foreach ((array)$path as $dir) { - if ($dir != APP) { - $items = self::__list($dir, $types[$type]['suffix'], $extension); - $objects = array_merge($items, array_diff($objects, $items)); - } - } - - if ($type !== 'file') { - foreach ($objects as $key => $value) { - $objects[$key] = Inflector::camelize($value); - } - } - - if ($cache === true) { - self::$__cache = true; - } - self::$__objects[$name] = $objects; - } - - return self::$__objects[$name]; - } - -/** - * Allows you to modify the object listings that App maintains inside of it - * Useful for testing - * - * @param string $type Type of object listing you are changing - * @param array $values The values $type should be set to. - * @return void - */ - public static function setObjects($type, $values) { - self::$__objects[$type] = $values; - } - -/** - * Finds classes based on $name or specific file(s) to search. Calling App::import() will - * not construct any classes contained in the files. It will only find and require() the file. - * - * @link http://book.cakephp.org/view/934/Using-App-import - * @param mixed $type The type of Class if passed as a string, or all params can be passed as - * an single array to $type, - * @param string $name Name of the Class or a unique name for the file - * @param mixed $parent boolean true if Class Parent should be searched, accepts key => value - * array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext'); - * $ext allows setting the extension of the file name - * based on Inflector::underscore($name) . ".$ext"; - * @param array $search paths to search for files, array('path 1', 'path 2', 'path 3'); - * @param string $file full name of the file to search for including extension - * @param boolean $return, return the loaded file, the file must have a return - * statement in it to work: return $variable; - * @return boolean true if Class is already in memory or if file is found and loaded, false if not - */ - public static function import($type = null, $name = null, $parent = true, $search = array(), $file = null, $return = false) { - $plugin = $directory = null; - - if (is_array($type)) { - extract($type, EXTR_OVERWRITE); - } - - if (is_array($parent)) { - extract($parent, EXTR_OVERWRITE); - } - - if ($name === null && $file === null) { - $name = $type; - $type = 'Core'; - } elseif ($name === null) { - $type = 'File'; - } - - if (is_array($name)) { - foreach ($name as $class) { - $tempType = $type; - $plugin = null; - - if (strpos($class, '.') !== false) { - $value = explode('.', $class); - $count = count($value); - - if ($count > 2) { - $tempType = $value[0]; - $plugin = $value[1] . '.'; - $class = $value[2]; - } elseif ($count === 2 && ($type === 'Core' || $type === 'File')) { - $tempType = $value[0]; - $class = $value[1]; - } else { - $plugin = $value[0] . '.'; - $class = $value[1]; - } - } - - if (!App::import($tempType, $plugin . $class, $parent)) { - return false; - } - } - return true; - } - - if ($name != null && strpos($name, '.') !== false) { - list($plugin, $name) = explode('.', $name); - $plugin = Inflector::camelize($plugin); - } - self::$return = $return; - - if (isset($ext)) { - $file = Inflector::underscore($name) . ".{$ext}"; - } - $ext = self::__settings($type, $plugin, $parent); - 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); - } - return true; - } else { - self::__remove($name . $ext['class'], $type, $plugin); - self::$__cache = true; - } - } - if (!empty($search)) { - self::$search = $search; - } elseif ($plugin) { - self::$search = self::__paths('plugin'); - } else { - self::$search = self::__paths($type); - } - $find = $file; - - if ($find === null) { - $find = Inflector::underscore($name . $ext['suffix']).'.php'; - - if ($plugin) { - $paths = self::$search; - foreach ($paths as $key => $value) { - self::$search[$key] = $value . $ext['path']; - } - } - } - - if (strtolower($type) !== 'vendor' && empty($search) && self::__load($file)) { - $directory = false; - } else { - $file = $find; - $directory = self::__find($find, true); - } - - 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); - } - return true; - } - return false; - } - return true; - } - -/** - * Initializes the cache for App, registers a shutdown function. - * - * @return void - */ - public static function init() { - self::$__map = (array)Cache::read('file_map', '_cake_core_'); - register_shutdown_function(array('App', 'shutdown')); - } - -/** - * Locates the $file in $__paths, searches recursively. - * - * @param string $file full file name - * @param boolean $recursive search $__paths recursively - * @return mixed boolean on fail, $file directory path on success - */ - private static function __find($file, $recursive = true) { - static $appPath = false; - - if (empty(self::$search)) { - return null; - } elseif (is_string(self::$search)) { - $this->search = array(self::$search); - } - - if (empty(self::$__paths)) { - self::$__paths = Cache::read('dir_map', '_cake_core_'); - } - - foreach (self::$search as $path) { - if ($appPath === false) { - $appPath = rtrim(APP, DS); - } - $path = rtrim($path, DS); - - if ($path === $appPath) { - $recursive = false; - } - if ($recursive === false) { - if (self::__load($path . DS . $file)) { - return $path . DS; - } - continue; - } - - if (!isset(self::$__paths[$path])) { - if (!class_exists('Folder')) { - require LIBS . 'folder.php'; - } - $Folder = new Folder(); - $directories = $Folder->tree($path, array('.svn', '.git', 'CVS', 'tests', 'templates'), 'dir'); - sort($directories); - self::$__paths[$path] = $directories; - } - - foreach (self::$__paths[$path] as $directory) { - if (self::__load($directory . DS . $file)) { - return $directory . DS; - } - } - } - return null; - } - -/** - * Attempts to load $file. - * - * @param string $file full path to file including file name - * @return boolean - * @access private - */ - private static function __load($file) { - if (empty($file)) { - return false; - } - if (!self::$return && isset(self::$__loaded[$file])) { - return true; - } - if (file_exists($file)) { - if (!self::$return) { - require($file); - self::$__loaded[$file] = true; - } - return true; - } - return false; - } - -/** - * Maps the $name to the $file. - * - * @param string $file full path to file - * @param string $name unique name for this map - * @param string $type type object being mapped - * @param string $plugin camelized if object is from a plugin, the name of the plugin - * @return void - * @access private - */ - private static function __map($file, $name, $type, $plugin) { - if ($plugin) { - self::$__map['Plugin'][$plugin][$type][$name] = $file; - } else { - self::$__map[$type][$name] = $file; - } - } - -/** - * Returns a file's complete path. - * - * @param string $name unique name - * @param string $type type object - * @param string $plugin camelized if object is from a plugin, the name of the plugin - * @return mixed, file path if found, false otherwise - * @access private - */ - private static function __mapped($name, $type, $plugin) { - if ($plugin) { - if (isset(self::$__map['Plugin'][$plugin][$type]) && isset(self::$__map['Plugin'][$plugin][$type][$name])) { - return self::$__map['Plugin'][$plugin][$type][$name]; - } - return false; - } - - if (isset(self::$__map[$type]) && isset(self::$__map[$type][$name])) { - return self::$__map[$type][$name]; - } - 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. - * - * @param string $type type of object - * @param string $plugin camelized name of plugin - * @param boolean $parent false will not attempt to load parent - * @return array - * @access private - */ - private static function __settings($type, $plugin, $parent) { - if (!$parent) { - return array('class' => null, 'suffix' => null, 'path' => null); - } - - if ($plugin) { - $pluginPath = Inflector::underscore($plugin); - } - $path = null; - $load = strtolower($type); - - switch ($load) { - case 'model': - if (!class_exists('Model')) { - require LIBS . 'model' . DS . 'model.php'; - } - if (!class_exists('AppModel')) { - App::import($type, 'AppModel', false); - } - if ($plugin) { - if (!class_exists($plugin . 'AppModel')) { - App::import($type, $plugin . '.' . $plugin . 'AppModel', false, array(), $pluginPath . DS . $pluginPath . '_app_model.php'); - } - $path = $pluginPath . DS . 'models' . DS; - } - return array('class' => null, 'suffix' => null, 'path' => $path); - break; - case 'behavior': - if ($plugin) { - $path = $pluginPath . DS . 'models' . DS . 'behaviors' . DS; - } - return array('class' => $type, 'suffix' => null, 'path' => $path); - break; - case 'datasource': - if ($plugin) { - $path = $pluginPath . DS . 'models' . DS . 'datasources' . DS; - } - return array('class' => $type, 'suffix' => null, 'path' => $path); - case 'controller': - App::import($type, 'AppController', false); - if ($plugin) { - App::import($type, $plugin . '.' . $plugin . 'AppController', false, array(), $pluginPath . DS . $pluginPath . '_app_controller.php'); - $path = $pluginPath . DS . 'controllers' . DS; - } - return array('class' => $type, 'suffix' => $type, 'path' => $path); - break; - case 'component': - App::import('Core', 'Component', false); - if ($plugin) { - $path = $pluginPath . DS . 'controllers' . DS . 'components' . DS; - } - return array('class' => $type, 'suffix' => null, 'path' => $path); - break; - case 'lib': - if ($plugin) { - $path = $pluginPath . DS . 'libs' . DS; - } - return array('class' => null, 'suffix' => null, 'path' => $path); - break; - case 'view': - App::import('View', 'View', false); - if ($plugin) { - $path = $pluginPath . DS . 'views' . DS; - } - return array('class' => $type, 'suffix' => null, 'path' => $path); - break; - case 'helper': - if (!class_exists('AppHelper')) { - App::import($type, 'AppHelper', false); - } - if ($plugin) { - $path = $pluginPath . DS . 'views' . DS . 'helpers' . DS; - } - return array('class' => $type, 'suffix' => null, 'path' => $path); - break; - case 'shell': - if (!class_exists('Shell')) { - App::import($type, 'Shell', false); - } - if ($plugin) { - $path = $pluginPath . DS . 'console' . DS . 'shells' . DS; - } - return array('class' => $type, 'suffix' => null, 'path' => $path); - break; - case 'vendor': - if ($plugin) { - $path = $pluginPath . DS . 'vendors' . DS; - } - return array('class' => null, 'suffix' => null, 'path' => $path); - break; - default: - $type = $suffix = $path = null; - break; - } - return array('class' => null, 'suffix' => null, 'path' => null); - } - -/** - * Returns default search paths. - * - * @param string $type type of object to be searched - * @return array list of paths - */ - private static function __paths($type) { - $type = strtolower($type); - $paths = array(); - - if ($type === 'core') { - return App::core('libs'); - } - if (isset(self::${$type . 's'})) { - return self::${$type . 's'}; - } - return $paths; - } - -/** - * Removes file location from map if the file has been deleted. - * - * @param string $name name of object - * @param string $type type of object - * @param string $plugin camelized name of plugin - * @return void - */ - private static function __remove($name, $type, $plugin) { - if ($plugin) { - unset(self::$__map['Plugin'][$plugin][$type][$name]); - } else { - unset(self::$__map[$type][$name]); - } - } - -/** - * Returns an array of filenames of PHP files in the given directory. - * - * @param string $path Path to scan for files - * @param string $suffix if false, return only directories. if string, match and return files - * @return array List of directories or files in directory - */ - private static function __list($path, $suffix = false, $extension = false) { - if (!class_exists('Folder')) { - require LIBS . 'folder.php'; - } - $items = array(); - $Folder = new Folder($path); - $contents = $Folder->read(false, true); - - if (is_array($contents)) { - if (!$suffix) { - return $contents[0]; - } else { - foreach ($contents[1] as $item) { - if (substr($item, - strlen($suffix)) === $suffix) { - if ($extension) { - $items[] = $item; - } else { - $items[] = substr($item, 0, strlen($item) - strlen($suffix)); - } - } - } - } - } - return $items; - } - -/** - * Object destructor. - * - * Writes cache file if changes have been made to the $__map or $__paths - * - * @return void - */ - public static function shutdown() { - if (self::$__cache) { - $core = App::core('cake'); - unset(self::$__paths[rtrim($core[0], DS)]); - Cache::write('dir_map', array_filter(self::$__paths), '_cake_core_'); - Cache::write('file_map', array_filter(self::$__map), '_cake_core_'); - Cache::write('object_map', self::$__objects, '_cake_core_'); - } - } -} +} \ No newline at end of file From 27287e4b9feff698565d5e4aaa8c5af88c327dd8 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 13:06:25 -0500 Subject: [PATCH 076/160] Moving AppTest into a separate file. Updating test suite. --- cake/tests/cases/libs/all_configure.test.php | 1 + cake/tests/cases/libs/app.test.php | 527 +++++++++++++++++++ cake/tests/cases/libs/configure.test.php | 526 ------------------ 3 files changed, 528 insertions(+), 526 deletions(-) create mode 100644 cake/tests/cases/libs/app.test.php diff --git a/cake/tests/cases/libs/all_configure.test.php b/cake/tests/cases/libs/all_configure.test.php index 39f4059b9..859178051 100644 --- a/cake/tests/cases/libs/all_configure.test.php +++ b/cake/tests/cases/libs/all_configure.test.php @@ -37,6 +37,7 @@ class AllConfigureTest extends PHPUnit_Framework_TestSuite { $suite = new PHPUnit_Framework_TestSuite('All Configure, App and ClassRegistry related tests'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'configure.test.php'); + $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'app.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'class_registry.test.php'); return $suite; } diff --git a/cake/tests/cases/libs/app.test.php b/cake/tests/cases/libs/app.test.php new file mode 100644 index 000000000..f9519057b --- /dev/null +++ b/cake/tests/cases/libs/app.test.php @@ -0,0 +1,527 @@ +assertEqual($expected, $old); + + App::build(array('models' => array('/path/to/models/'))); + + $new = App::path('models'); + + $expected = array( + '/path/to/models/', + APP . 'models' . DS, + APP, + ROOT . DS . LIBS . 'model' . DS + ); + $this->assertEqual($expected, $new); + + App::build(); //reset defaults + $defaults = App::path('models'); + $this->assertEqual($old, $defaults); + } + +/** + * testBuildWithReset method + * + * @access public + * @return void + */ + function testBuildWithReset() { + $old = App::path('models'); + $expected = array( + APP . 'models' . DS, + APP, + ROOT . DS . LIBS . 'model' . DS + ); + $this->assertEqual($expected, $old); + + App::build(array('models' => array('/path/to/models/')), true); + + $new = App::path('models'); + + $expected = array( + '/path/to/models/' + ); + $this->assertEqual($expected, $new); + + App::build(); //reset defaults + $defaults = App::path('models'); + $this->assertEqual($old, $defaults); + } + +/** + * testCore method + * + * @access public + * @return void + */ + function testCore() { + $model = App::core('models'); + $this->assertEqual(array(ROOT . DS . LIBS . 'model' . DS), $model); + + $view = App::core('views'); + $this->assertEqual(array(ROOT . DS . LIBS . 'view' . DS), $view); + + $controller = App::core('controllers'); + $this->assertEqual(array(ROOT . DS . LIBS . 'controller' . DS), $controller); + + } + +/** + * testListObjects method + * + * @access public + * @return void + */ + function testListObjects() { + $result = App::objects('class', TEST_CAKE_CORE_INCLUDE_PATH . 'libs', false); + $this->assertTrue(in_array('Xml', $result)); + $this->assertTrue(in_array('Cache', $result)); + $this->assertTrue(in_array('HttpSocket', $result)); + + $result = App::objects('behavior', null, false); + $this->assertTrue(in_array('Tree', $result)); + + $result = App::objects('controller', null, false); + $this->assertTrue(in_array('Pages', $result)); + + $result = App::objects('component', null, false); + $this->assertTrue(in_array('Auth', $result)); + + $result = App::objects('view', null, false); + $this->assertTrue(in_array('Media', $result)); + + $result = App::objects('helper', null, false); + $this->assertTrue(in_array('Html', $result)); + + $result = App::objects('model', null, false); + $notExpected = array('AppModel', 'ModelBehavior', 'ConnectionManager', 'DbAcl', 'Model', 'CakeSchema'); + foreach ($notExpected as $class) { + $this->assertFalse(in_array($class, $result)); + } + + $result = App::objects('file'); + $this->assertFalse($result); + + $result = App::objects('file', 'non_existing_configure'); + $expected = array(); + $this->assertEqual($result, $expected); + + $result = App::objects('NonExistingType'); + $this->assertFalse($result); + + App::build(array( + 'plugins' => array( + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'libs' . DS + ) + )); + $result = App::objects('plugin', null, false); + $this->assertTrue(in_array('Cache', $result)); + $this->assertTrue(in_array('Log', $result)); + + App::build(); + } + +/** + * test that pluginPath can find paths for plugins. + * + * @return void + */ + function testPluginPath() { + App::build(array( + 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS) + )); + $path = App::pluginPath('test_plugin'); + $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS; + $this->assertEqual($path, $expected); + + $path = App::pluginPath('TestPlugin'); + $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS; + $this->assertEqual($path, $expected); + + $path = App::pluginPath('TestPluginTwo'); + $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin_two' . DS; + $this->assertEqual($path, $expected); + App::build(); + } + +/** + * test that pluginPath can find paths for plugins. + * + * @return void + */ + function testThemePath() { + App::build(array( + 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS) + )); + $path = App::themePath('test_theme'); + $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS; + $this->assertEqual($path, $expected); + + $path = App::themePath('TestTheme'); + $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS; + $this->assertEqual($path, $expected); + + App::build(); + } + +/** + * testClassLoading method + * + * @access public + * @return void + */ + function testClassLoading() { + $file = App::import(); + $this->assertTrue($file); + + $file = App::import('Model', 'Model', false); + $this->assertTrue($file); + $this->assertTrue(class_exists('Model')); + + $file = App::import('Controller', 'Controller', false); + $this->assertTrue($file); + $this->assertTrue(class_exists('Controller')); + + $file = App::import('Component', 'Component', false); + $this->assertTrue($file); + $this->assertTrue(class_exists('Component')); + + $file = App::import('Shell', 'Shell', false); + $this->assertTrue($file); + $this->assertTrue(class_exists('Shell')); + + $file = App::import('Model', 'SomeRandomModelThatDoesNotExist', false); + $this->assertFalse($file); + + $file = App::import('Model', 'AppModel', false); + $this->assertTrue($file); + $this->assertTrue(class_exists('AppModel')); + + $file = App::import('WrongType', null, true, array(), ''); + $this->assertTrue($file); + + $file = App::import('Model', 'NonExistingPlugin.NonExistingModel', false); + $this->assertFalse($file); + + $file = App::import('Core', 'NonExistingPlugin.NonExistingModel', false); + $this->assertFalse($file); + + $file = App::import('Model', array('NonExistingPlugin.NonExistingModel'), false); + $this->assertFalse($file); + + $file = App::import('Core', array('NonExistingPlugin.NonExistingModel'), false); + $this->assertFalse($file); + + $file = App::import('Core', array('NonExistingPlugin.NonExistingModel.AnotherChild'), false); + $this->assertFalse($file); + + if (!class_exists('AppController')) { + $classes = array_flip(get_declared_classes()); + + $this->assertFalse(isset($classes['PagesController'])); + $this->assertFalse(isset($classes['AppController'])); + + $file = App::import('Controller', 'Pages'); + $this->assertTrue($file); + $this->assertTrue(class_exists('PagesController')); + + $classes = array_flip(get_declared_classes()); + + $this->assertTrue(isset($classes['PagesController'])); + $this->assertTrue(isset($classes['AppController'])); + + $file = App::import('Behavior', 'Containable'); + $this->assertTrue($file); + $this->assertTrue(class_exists('ContainableBehavior')); + + $file = App::import('Component', 'RequestHandler'); + $this->assertTrue($file); + $this->assertTrue(class_exists('RequestHandlerComponent')); + + $file = App::import('Helper', 'Form'); + $this->assertTrue($file); + $this->assertTrue(class_exists('FormHelper')); + + $file = App::import('Model', 'NonExistingModel'); + $this->assertFalse($file); + + $file = App::import('Datasource', 'DboSource'); + $this->assertTrue($file); + $this->assertTrue(class_exists('DboSource')); + } + App::build(); + } + +/** + * test import() with plugins + * + * @return void + */ + function testPluginImporting() { + App::build(array( + 'libs' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'libs' . DS), + 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS) + )); + + $result = App::import('Controller', 'TestPlugin.Tests'); + $this->assertTrue($result); + $this->assertTrue(class_exists('TestPluginAppController')); + $this->assertTrue(class_exists('TestsController')); + + $result = App::import('Lib', 'TestPlugin.TestPluginLibrary'); + $this->assertTrue($result); + $this->assertTrue(class_exists('TestPluginLibrary')); + + $result = App::import('Lib', 'Library'); + $this->assertTrue($result); + $this->assertTrue(class_exists('Library')); + + $result = App::import('Helper', 'TestPlugin.OtherHelper'); + $this->assertTrue($result); + $this->assertTrue(class_exists('OtherHelperHelper')); + + $result = App::import('Helper', 'TestPlugin.TestPluginApp'); + $this->assertTrue($result); + $this->assertTrue(class_exists('TestPluginAppHelper')); + + $result = App::import('Datasource', 'TestPlugin.TestSource'); + $this->assertTrue($result); + $this->assertTrue(class_exists('TestSource')); + + App::build(); + } + +/** + * test that building helper paths actually works. + * + * @return void + * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/410 + */ + function testImportingHelpersFromAlternatePaths() { + App::build(); + $this->assertFalse(class_exists('BananaHelper'), 'BananaHelper exists, cannot test importing it.'); + App::import('Helper', 'Banana'); + $this->assertFalse(class_exists('BananaHelper'), 'BananaHelper was not found because the path does not exist.'); + + App::build(array( + 'helpers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'helpers' . DS) + )); + App::build(array('vendors' => array(TEST_CAKE_CORE_INCLUDE_PATH))); + $this->assertFalse(class_exists('BananaHelper'), 'BananaHelper exists, cannot test importing it.'); + App::import('Helper', 'Banana'); + $this->assertTrue(class_exists('BananaHelper'), 'BananaHelper was not loaded.'); + + App::build(); + } + +/** + * testFileLoading method + * + * @access public + * @return void + */ + function testFileLoading () { + $file = App::import('File', 'RealFile', false, array(), TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'config.php'); + $this->assertTrue($file); + + $file = App::import('File', 'NoFile', false, array(), TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'cake' . DS . 'config.php'); + $this->assertFalse($file); + } + +/** + * testFileLoadingWithArray method + * + * @access public + * @return void + */ + function testFileLoadingWithArray() { + $type = array('type' => 'File', 'name' => 'SomeName', 'parent' => false, + 'file' => TEST_CAKE_CORE_INCLUDE_PATH . DS . 'config' . DS . 'config.php'); + $file = App::import($type); + $this->assertTrue($file); + + $type = array('type' => 'File', 'name' => 'NoFile', 'parent' => false, + 'file' => TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'cake' . DS . 'config.php'); + $file = App::import($type); + $this->assertFalse($file); + } + +/** + * testFileLoadingReturnValue method + * + * @access public + * @return void + */ + function testFileLoadingReturnValue () { + $file = App::import('File', 'Name', false, array(), TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'config.php', true); + $this->assertTrue(!empty($file)); + + $this->assertTrue(isset($file['Cake.version'])); + + $type = array('type' => 'File', 'name' => 'OtherName', 'parent' => false, + 'file' => TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'config.php', 'return' => true); + $file = App::import($type); + $this->assertTrue(!empty($file)); + + $this->assertTrue(isset($file['Cake.version'])); + } + +/** + * testLoadingWithSearch method + * + * @access public + * @return void + */ + function testLoadingWithSearch () { + $file = App::import('File', 'NewName', false, array(TEST_CAKE_CORE_INCLUDE_PATH ), 'config.php'); + $this->assertTrue($file); + + $file = App::import('File', 'AnotherNewName', false, array(LIBS), 'config.php'); + $this->assertFalse($file); + } + +/** + * testLoadingWithSearchArray method + * + * @access public + * @return void + */ + function testLoadingWithSearchArray () { + $type = array('type' => 'File', 'name' => 'RandomName', 'parent' => false, 'file' => 'config.php', 'search' => array(TEST_CAKE_CORE_INCLUDE_PATH )); + $file = App::import($type); + $this->assertTrue($file); + + $type = array('type' => 'File', 'name' => 'AnotherRandomName', 'parent' => false, 'file' => 'config.php', 'search' => array(LIBS)); + $file = App::import($type); + $this->assertFalse($file); + } + +/** + * testMultipleLoading method + * + * @access public + * @return void + */ + function testMultipleLoading() { + if (class_exists('I18n', false) || class_exists('CakeSocket', false)) { + $this->markTestSkipped('Cannot test loading of classes that exist.'); + } + $toLoad = array('I18n', 'CakeSocket'); + + $classes = array_flip(get_declared_classes()); + $this->assertFalse(isset($classes['i18n'])); + $this->assertFalse(isset($classes['CakeSocket'])); + + $load = App::import($toLoad); + $this->assertTrue($load); + + $classes = array_flip(get_declared_classes()); + + + $this->assertTrue(isset($classes['I18n'])); + + $load = App::import(array('I18n', 'SomeNotFoundClass', 'CakeSocket')); + $this->assertFalse($load); + + $load = App::import($toLoad); + $this->assertTrue($load); + } + +/** + * This test only works if you have plugins/my_plugin set up. + * plugins/my_plugin/models/my_plugin.php and other_model.php + */ + +/* + function testMultipleLoadingByType() { + $classes = array_flip(get_declared_classes()); + $this->assertFalse(isset($classes['OtherPlugin'])); + $this->assertFalse(isset($classes['MyPlugin'])); + + + $load = App::import('Model', array('MyPlugin.OtherPlugin', 'MyPlugin.MyPlugin')); + $this->assertTrue($load); + + $classes = array_flip(get_declared_classes()); + $this->assertTrue(isset($classes['OtherPlugin'])); + $this->assertTrue(isset($classes['MyPlugin'])); + } +*/ + function testLoadingVendor() { + App::build(array( + 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS), + 'vendors' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'vendors'. DS), + ), true); + + ob_start(); + $result = App::import('Vendor', 'TestPlugin.TestPluginAsset', array('ext' => 'css')); + $text = ob_get_clean(); + $this->assertTrue($result); + $this->assertEqual($text, 'this is the test plugin asset css file'); + + ob_start(); + $result = App::import('Vendor', 'TestAsset', array('ext' => 'css')); + $text = ob_get_clean(); + $this->assertTrue($result); + $this->assertEqual($text, 'this is the test asset css file'); + + $result = App::import('Vendor', 'TestPlugin.SamplePlugin'); + $this->assertTrue($result); + $this->assertTrue(class_exists('SamplePluginClassTestName')); + + $result = App::import('Vendor', 'ConfigureTestVendorSample'); + $this->assertTrue($result); + $this->assertTrue(class_exists('ConfigureTestVendorSample')); + + ob_start(); + $result = App::import('Vendor', 'SomeName', array('file' => 'some.name.php')); + $text = ob_get_clean(); + $this->assertTrue($result); + $this->assertEqual($text, 'This is a file with dot in file name'); + + ob_start(); + $result = App::import('Vendor', 'TestHello', array('file' => 'Test'.DS.'hello.php')); + $text = ob_get_clean(); + $this->assertTrue($result); + $this->assertEqual($text, 'This is the hello.php file in Test directory'); + + ob_start(); + $result = App::import('Vendor', 'MyTest', array('file' => 'Test'.DS.'MyTest.php')); + $text = ob_get_clean(); + $this->assertTrue($result); + $this->assertEqual($text, 'This is the MyTest.php file'); + + ob_start(); + $result = App::import('Vendor', 'Welcome'); + $text = ob_get_clean(); + $this->assertTrue($result); + $this->assertEqual($text, 'This is the welcome.php file in vendors directory'); + + ob_start(); + $result = App::import('Vendor', 'TestPlugin.Welcome'); + $text = ob_get_clean(); + $this->assertTrue($result); + $this->assertEqual($text, 'This is the welcome.php file in test_plugin/vendors directory'); + } +} diff --git a/cake/tests/cases/libs/configure.test.php b/cake/tests/cases/libs/configure.test.php index 599e37b01..11ef38f05 100644 --- a/cake/tests/cases/libs/configure.test.php +++ b/cake/tests/cases/libs/configure.test.php @@ -19,7 +19,6 @@ * @since CakePHP(tm) v 1.2.0.5432 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', 'Configure'); /** * ConfigureTest @@ -295,528 +294,3 @@ class ConfigureTest extends CakeTestCase { } } -/** - * AppImportTest class - * - * @package cake - * @subpackage cake.tests.cases.libs - */ -class AppImportTest extends CakeTestCase { - -/** - * testBuild method - * - * @access public - * @return void - */ - function testBuild() { - $old = App::path('models'); - $expected = array( - APP . 'models' . DS, - APP, - ROOT . DS . LIBS . 'model' . DS - ); - $this->assertEqual($expected, $old); - - App::build(array('models' => array('/path/to/models/'))); - - $new = App::path('models'); - - $expected = array( - '/path/to/models/', - APP . 'models' . DS, - APP, - ROOT . DS . LIBS . 'model' . DS - ); - $this->assertEqual($expected, $new); - - App::build(); //reset defaults - $defaults = App::path('models'); - $this->assertEqual($old, $defaults); - } - -/** - * testBuildWithReset method - * - * @access public - * @return void - */ - function testBuildWithReset() { - $old = App::path('models'); - $expected = array( - APP . 'models' . DS, - APP, - ROOT . DS . LIBS . 'model' . DS - ); - $this->assertEqual($expected, $old); - - App::build(array('models' => array('/path/to/models/')), true); - - $new = App::path('models'); - - $expected = array( - '/path/to/models/' - ); - $this->assertEqual($expected, $new); - - App::build(); //reset defaults - $defaults = App::path('models'); - $this->assertEqual($old, $defaults); - } - -/** - * testCore method - * - * @access public - * @return void - */ - function testCore() { - $model = App::core('models'); - $this->assertEqual(array(ROOT . DS . LIBS . 'model' . DS), $model); - - $view = App::core('views'); - $this->assertEqual(array(ROOT . DS . LIBS . 'view' . DS), $view); - - $controller = App::core('controllers'); - $this->assertEqual(array(ROOT . DS . LIBS . 'controller' . DS), $controller); - - } - -/** - * testListObjects method - * - * @access public - * @return void - */ - function testListObjects() { - $result = App::objects('class', TEST_CAKE_CORE_INCLUDE_PATH . 'libs', false); - $this->assertTrue(in_array('Xml', $result)); - $this->assertTrue(in_array('Cache', $result)); - $this->assertTrue(in_array('HttpSocket', $result)); - - $result = App::objects('behavior', null, false); - $this->assertTrue(in_array('Tree', $result)); - - $result = App::objects('controller', null, false); - $this->assertTrue(in_array('Pages', $result)); - - $result = App::objects('component', null, false); - $this->assertTrue(in_array('Auth', $result)); - - $result = App::objects('view', null, false); - $this->assertTrue(in_array('Media', $result)); - - $result = App::objects('helper', null, false); - $this->assertTrue(in_array('Html', $result)); - - $result = App::objects('model', null, false); - $notExpected = array('AppModel', 'ModelBehavior', 'ConnectionManager', 'DbAcl', 'Model', 'CakeSchema'); - foreach ($notExpected as $class) { - $this->assertFalse(in_array($class, $result)); - } - - $result = App::objects('file'); - $this->assertFalse($result); - - $result = App::objects('file', 'non_existing_configure'); - $expected = array(); - $this->assertEqual($result, $expected); - - $result = App::objects('NonExistingType'); - $this->assertFalse($result); - - App::build(array( - 'plugins' => array( - TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'libs' . DS - ) - )); - $result = App::objects('plugin', null, false); - $this->assertTrue(in_array('Cache', $result)); - $this->assertTrue(in_array('Log', $result)); - - App::build(); - } - -/** - * test that pluginPath can find paths for plugins. - * - * @return void - */ - function testPluginPath() { - App::build(array( - 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS) - )); - $path = App::pluginPath('test_plugin'); - $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS; - $this->assertEqual($path, $expected); - - $path = App::pluginPath('TestPlugin'); - $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin' . DS; - $this->assertEqual($path, $expected); - - $path = App::pluginPath('TestPluginTwo'); - $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS . 'test_plugin_two' . DS; - $this->assertEqual($path, $expected); - App::build(); - } - -/** - * test that pluginPath can find paths for plugins. - * - * @return void - */ - function testThemePath() { - App::build(array( - 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS) - )); - $path = App::themePath('test_theme'); - $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS; - $this->assertEqual($path, $expected); - - $path = App::themePath('TestTheme'); - $expected = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'themed' . DS . 'test_theme' . DS; - $this->assertEqual($path, $expected); - - App::build(); - } - -/** - * testClassLoading method - * - * @access public - * @return void - */ - function testClassLoading() { - $file = App::import(); - $this->assertTrue($file); - - $file = App::import('Model', 'Model', false); - $this->assertTrue($file); - $this->assertTrue(class_exists('Model')); - - $file = App::import('Controller', 'Controller', false); - $this->assertTrue($file); - $this->assertTrue(class_exists('Controller')); - - $file = App::import('Component', 'Component', false); - $this->assertTrue($file); - $this->assertTrue(class_exists('Component')); - - $file = App::import('Shell', 'Shell', false); - $this->assertTrue($file); - $this->assertTrue(class_exists('Shell')); - - $file = App::import('Model', 'SomeRandomModelThatDoesNotExist', false); - $this->assertFalse($file); - - $file = App::import('Model', 'AppModel', false); - $this->assertTrue($file); - $this->assertTrue(class_exists('AppModel')); - - $file = App::import('WrongType', null, true, array(), ''); - $this->assertTrue($file); - - $file = App::import('Model', 'NonExistingPlugin.NonExistingModel', false); - $this->assertFalse($file); - - $file = App::import('Core', 'NonExistingPlugin.NonExistingModel', false); - $this->assertFalse($file); - - $file = App::import('Model', array('NonExistingPlugin.NonExistingModel'), false); - $this->assertFalse($file); - - $file = App::import('Core', array('NonExistingPlugin.NonExistingModel'), false); - $this->assertFalse($file); - - $file = App::import('Core', array('NonExistingPlugin.NonExistingModel.AnotherChild'), false); - $this->assertFalse($file); - - if (!class_exists('AppController')) { - $classes = array_flip(get_declared_classes()); - - $this->assertFalse(isset($classes['PagesController'])); - $this->assertFalse(isset($classes['AppController'])); - - $file = App::import('Controller', 'Pages'); - $this->assertTrue($file); - $this->assertTrue(class_exists('PagesController')); - - $classes = array_flip(get_declared_classes()); - - $this->assertTrue(isset($classes['PagesController'])); - $this->assertTrue(isset($classes['AppController'])); - - $file = App::import('Behavior', 'Containable'); - $this->assertTrue($file); - $this->assertTrue(class_exists('ContainableBehavior')); - - $file = App::import('Component', 'RequestHandler'); - $this->assertTrue($file); - $this->assertTrue(class_exists('RequestHandlerComponent')); - - $file = App::import('Helper', 'Form'); - $this->assertTrue($file); - $this->assertTrue(class_exists('FormHelper')); - - $file = App::import('Model', 'NonExistingModel'); - $this->assertFalse($file); - - $file = App::import('Datasource', 'DboSource'); - $this->assertTrue($file); - $this->assertTrue(class_exists('DboSource')); - } - App::build(); - } - -/** - * test import() with plugins - * - * @return void - */ - function testPluginImporting() { - App::build(array( - 'libs' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'libs' . DS), - 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS) - )); - - $result = App::import('Controller', 'TestPlugin.Tests'); - $this->assertTrue($result); - $this->assertTrue(class_exists('TestPluginAppController')); - $this->assertTrue(class_exists('TestsController')); - - $result = App::import('Lib', 'TestPlugin.TestPluginLibrary'); - $this->assertTrue($result); - $this->assertTrue(class_exists('TestPluginLibrary')); - - $result = App::import('Lib', 'Library'); - $this->assertTrue($result); - $this->assertTrue(class_exists('Library')); - - $result = App::import('Helper', 'TestPlugin.OtherHelper'); - $this->assertTrue($result); - $this->assertTrue(class_exists('OtherHelperHelper')); - - $result = App::import('Helper', 'TestPlugin.TestPluginApp'); - $this->assertTrue($result); - $this->assertTrue(class_exists('TestPluginAppHelper')); - - $result = App::import('Datasource', 'TestPlugin.TestSource'); - $this->assertTrue($result); - $this->assertTrue(class_exists('TestSource')); - - App::build(); - } - -/** - * test that building helper paths actually works. - * - * @return void - * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/410 - */ - function testImportingHelpersFromAlternatePaths() { - App::build(); - $this->assertFalse(class_exists('BananaHelper'), 'BananaHelper exists, cannot test importing it.'); - App::import('Helper', 'Banana'); - $this->assertFalse(class_exists('BananaHelper'), 'BananaHelper was not found because the path does not exist.'); - - App::build(array( - 'helpers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS . 'helpers' . DS) - )); - App::build(array('vendors' => array(TEST_CAKE_CORE_INCLUDE_PATH))); - $this->assertFalse(class_exists('BananaHelper'), 'BananaHelper exists, cannot test importing it.'); - App::import('Helper', 'Banana'); - $this->assertTrue(class_exists('BananaHelper'), 'BananaHelper was not loaded.'); - - App::build(); - } - -/** - * testFileLoading method - * - * @access public - * @return void - */ - function testFileLoading () { - $file = App::import('File', 'RealFile', false, array(), TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'config.php'); - $this->assertTrue($file); - - $file = App::import('File', 'NoFile', false, array(), TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'cake' . DS . 'config.php'); - $this->assertFalse($file); - } - -/** - * testFileLoadingWithArray method - * - * @access public - * @return void - */ - function testFileLoadingWithArray() { - $type = array('type' => 'File', 'name' => 'SomeName', 'parent' => false, - 'file' => TEST_CAKE_CORE_INCLUDE_PATH . DS . 'config' . DS . 'config.php'); - $file = App::import($type); - $this->assertTrue($file); - - $type = array('type' => 'File', 'name' => 'NoFile', 'parent' => false, - 'file' => TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'cake' . DS . 'config.php'); - $file = App::import($type); - $this->assertFalse($file); - } - -/** - * testFileLoadingReturnValue method - * - * @access public - * @return void - */ - function testFileLoadingReturnValue () { - $file = App::import('File', 'Name', false, array(), TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'config.php', true); - $this->assertTrue(!empty($file)); - - $this->assertTrue(isset($file['Cake.version'])); - - $type = array('type' => 'File', 'name' => 'OtherName', 'parent' => false, - 'file' => TEST_CAKE_CORE_INCLUDE_PATH . 'config' . DS . 'config.php', 'return' => true); - $file = App::import($type); - $this->assertTrue(!empty($file)); - - $this->assertTrue(isset($file['Cake.version'])); - } - -/** - * testLoadingWithSearch method - * - * @access public - * @return void - */ - function testLoadingWithSearch () { - $file = App::import('File', 'NewName', false, array(TEST_CAKE_CORE_INCLUDE_PATH ), 'config.php'); - $this->assertTrue($file); - - $file = App::import('File', 'AnotherNewName', false, array(LIBS), 'config.php'); - $this->assertFalse($file); - } - -/** - * testLoadingWithSearchArray method - * - * @access public - * @return void - */ - function testLoadingWithSearchArray () { - $type = array('type' => 'File', 'name' => 'RandomName', 'parent' => false, 'file' => 'config.php', 'search' => array(TEST_CAKE_CORE_INCLUDE_PATH )); - $file = App::import($type); - $this->assertTrue($file); - - $type = array('type' => 'File', 'name' => 'AnotherRandomName', 'parent' => false, 'file' => 'config.php', 'search' => array(LIBS)); - $file = App::import($type); - $this->assertFalse($file); - } - -/** - * testMultipleLoading method - * - * @access public - * @return void - */ - function testMultipleLoading() { - if (class_exists('I18n', false) || class_exists('CakeSocket', false)) { - $this->markTestSkipped('Cannot test loading of classes that exist.'); - } - $toLoad = array('I18n', 'CakeSocket'); - - $classes = array_flip(get_declared_classes()); - $this->assertFalse(isset($classes['i18n'])); - $this->assertFalse(isset($classes['CakeSocket'])); - - $load = App::import($toLoad); - $this->assertTrue($load); - - $classes = array_flip(get_declared_classes()); - - - $this->assertTrue(isset($classes['I18n'])); - - $load = App::import(array('I18n', 'SomeNotFoundClass', 'CakeSocket')); - $this->assertFalse($load); - - $load = App::import($toLoad); - $this->assertTrue($load); - } - -/** - * This test only works if you have plugins/my_plugin set up. - * plugins/my_plugin/models/my_plugin.php and other_model.php - */ - -/* - function testMultipleLoadingByType() { - $classes = array_flip(get_declared_classes()); - $this->assertFalse(isset($classes['OtherPlugin'])); - $this->assertFalse(isset($classes['MyPlugin'])); - - - $load = App::import('Model', array('MyPlugin.OtherPlugin', 'MyPlugin.MyPlugin')); - $this->assertTrue($load); - - $classes = array_flip(get_declared_classes()); - $this->assertTrue(isset($classes['OtherPlugin'])); - $this->assertTrue(isset($classes['MyPlugin'])); - } -*/ - function testLoadingVendor() { - App::build(array( - 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS), - 'vendors' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'vendors'. DS), - ), true); - - ob_start(); - $result = App::import('Vendor', 'TestPlugin.TestPluginAsset', array('ext' => 'css')); - $text = ob_get_clean(); - $this->assertTrue($result); - $this->assertEqual($text, 'this is the test plugin asset css file'); - - ob_start(); - $result = App::import('Vendor', 'TestAsset', array('ext' => 'css')); - $text = ob_get_clean(); - $this->assertTrue($result); - $this->assertEqual($text, 'this is the test asset css file'); - - $result = App::import('Vendor', 'TestPlugin.SamplePlugin'); - $this->assertTrue($result); - $this->assertTrue(class_exists('SamplePluginClassTestName')); - - $result = App::import('Vendor', 'ConfigureTestVendorSample'); - $this->assertTrue($result); - $this->assertTrue(class_exists('ConfigureTestVendorSample')); - - ob_start(); - $result = App::import('Vendor', 'SomeName', array('file' => 'some.name.php')); - $text = ob_get_clean(); - $this->assertTrue($result); - $this->assertEqual($text, 'This is a file with dot in file name'); - - ob_start(); - $result = App::import('Vendor', 'TestHello', array('file' => 'Test'.DS.'hello.php')); - $text = ob_get_clean(); - $this->assertTrue($result); - $this->assertEqual($text, 'This is the hello.php file in Test directory'); - - ob_start(); - $result = App::import('Vendor', 'MyTest', array('file' => 'Test'.DS.'MyTest.php')); - $text = ob_get_clean(); - $this->assertTrue($result); - $this->assertEqual($text, 'This is the MyTest.php file'); - - ob_start(); - $result = App::import('Vendor', 'Welcome'); - $text = ob_get_clean(); - $this->assertTrue($result); - $this->assertEqual($text, 'This is the welcome.php file in vendors directory'); - - ob_start(); - $result = App::import('Vendor', 'TestPlugin.Welcome'); - $text = ob_get_clean(); - $this->assertTrue($result); - $this->assertEqual($text, 'This is the welcome.php file in test_plugin/vendors directory'); - } -} From b91566d35fd20a428ad97ec9498f7c91ee779413 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 14:45:09 -0500 Subject: [PATCH 077/160] Removing ini_set() in project root. Fixing notice errors that would happen when mod_rewrite wasn't enabled. --- app/webroot/index.php | 2 +- cake/console/templates/skel/webroot/index.php | 2 +- index.php | 14 +++----------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/app/webroot/index.php b/app/webroot/index.php index 35ebed025..719f172c4 100644 --- a/app/webroot/index.php +++ b/app/webroot/index.php @@ -76,5 +76,5 @@ } else { require LIBS . 'dispatcher.php'; $Dispatcher = new Dispatcher(); - $Dispatcher->dispatch(new CakeRequest($_GET['url'])); + $Dispatcher->dispatch(new CakeRequest(isset($_GET['url']) ? $_GET['url'] : null)); } diff --git a/cake/console/templates/skel/webroot/index.php b/cake/console/templates/skel/webroot/index.php index 35ebed025..719f172c4 100644 --- a/cake/console/templates/skel/webroot/index.php +++ b/cake/console/templates/skel/webroot/index.php @@ -76,5 +76,5 @@ } else { require LIBS . 'dispatcher.php'; $Dispatcher = new Dispatcher(); - $Dispatcher->dispatch(new CakeRequest($_GET['url'])); + $Dispatcher->dispatch(new CakeRequest(isset($_GET['url']) ? $_GET['url'] : null)); } diff --git a/index.php b/index.php index 860f61d02..cb0352b8a 100644 --- a/index.php +++ b/index.php @@ -41,15 +41,7 @@ /** * Set the include path or define app and core path */ - if (function_exists('ini_set')) { - ini_set('include_path', - ini_get('include_path') . PATH_SEPARATOR . CAKE_CORE_INCLUDE_PATH - . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS - ); - define('APP_PATH', null); - define('CORE_PATH', null); - } else { - define('APP_PATH', ROOT . DS . APP_DIR . DS); - define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); - } + define('APP_PATH', ROOT . DS . APP_DIR . DS); + define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS); + require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php'; From 1631f31460a240ec4a3c5bf4b7728d52f333788b Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 18:26:54 -0500 Subject: [PATCH 078/160] Adding doc comments to Configure and App. --- cake/libs/app.php | 26 ++++++++++++++++++++++++-- cake/libs/configure.php | 13 +++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/cake/libs/app.php b/cake/libs/app.php index 0d6ae1608..4261447b7 100644 --- a/cake/libs/app.php +++ b/cake/libs/app.php @@ -1,6 +1,6 @@ Date: Sun, 14 Nov 2010 18:37:27 -0500 Subject: [PATCH 079/160] Expanding doc blocks for Dispatcher. Extracting _isPrivateAction() so subclasses could change the behavior. --- cake/libs/dispatcher.php | 53 ++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index e9aff026a..75f3fd293 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -28,9 +28,9 @@ App::import('Core', array('Router', 'CakeRequest', 'CakeResponse'), false); App::import('Controller', 'Controller', false); /** - * Dispatcher translates URLs to controller-action-paramter triads. - * - * Dispatches the request, creating appropriate models and controllers. + * Dispatcher converts Requests into controller actions. It uses the dispatched Request + * to locate and load the correct controller. If found, the requested action is called on + * the controller. * * @package cake * @subpackage cake.cake @@ -73,12 +73,16 @@ class Dispatcher { } /** - * Dispatches and invokes given URL, handing over control to the involved controllers, and then renders the - * results (if autoRender is set). + * Dispatches and invokes given Request, handing over control to the involved controller. If the controller is set + * to autoRender, via Controller::$autoRender, then Dispatcher will render the view. * - * If no controller of given name can be found, invoke() shows error messages in - * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called - * Actions). + * Actions in CakePHP can be any public method on a controller, that is not declared in Controller. If you + * want controller methods to be public and in-accesible by URL, then prefix them with a `_`. + * For example `public function _loadPosts() { }` would not be accessible via URL. Private and protected methods + * are also not accessible via URL. + * + * If no controller of given name can be found, invoke() will throw an exception. + * If the controller is found, and the action is not found an exception will be thrown. * * @param CakeRequest $request Request object to dispatch. * @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params @@ -102,6 +106,27 @@ class Dispatcher { 'controller' => Inflector::camelize($request->params['controller']) . 'Controller' )); } + $privateAction = $this->_isPrivateAction($request); + Router::setRequestInfo($request); + + if ($privateAction) { + throw new PrivateActionException(array( + 'controller' => Inflector::camelize($request->params['controller']) . "Controller", + 'action' => $request->params['action'] + )); + } + + return $this->_invoke($controller, $request); + } + +/** + * Check if the request's action is marked as private, with an underscore, of if the request is attempting to + * directly accessing a prefixed action. + * + * @param CakeRequest $request The request to check + * @return boolean + */ + protected function _isPrivateAction($request) { $privateAction = $request->params['action'][0] === '_'; $prefixes = Router::prefixes(); @@ -113,17 +138,7 @@ class Dispatcher { $privateAction = in_array($prefix, $prefixes); } } - - Router::setRequestInfo($request); - - if ($privateAction) { - throw new PrivateActionException(array( - 'controller' => Inflector::camelize($request->params['controller']) . "Controller", - 'action' => $request->params['action'] - )); - } - - return $this->_invoke($controller, $request); + return $privateAction; } /** From db3f74dfa0f16ea71a299146b02c7da07dcccca9 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 18:38:10 -0500 Subject: [PATCH 080/160] Moving a method around. --- cake/libs/dispatcher.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index 75f3fd293..fe05ce058 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -106,10 +106,10 @@ class Dispatcher { 'controller' => Inflector::camelize($request->params['controller']) . 'Controller' )); } - $privateAction = $this->_isPrivateAction($request); + Router::setRequestInfo($request); - if ($privateAction) { + if ($this->_isPrivateAction($request)) { throw new PrivateActionException(array( 'controller' => Inflector::camelize($request->params['controller']) . "Controller", 'action' => $request->params['action'] From 293ef95f33c2ab9cf645f0ca88429f7da8a78867 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 18:43:46 -0500 Subject: [PATCH 081/160] Adding more documentation, and adding some return early changes. --- cake/libs/dispatcher.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index fe05ce058..5bfa749cb 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -157,7 +157,6 @@ class Dispatcher { $methods = array_flip($controller->methods); - if (!isset($methods[$request->params['action']])) { if ($controller->scaffold !== false) { App::import('Controller', 'Scaffold', false); @@ -185,10 +184,13 @@ class Dispatcher { } /** - * Returns array of GET and POST parameters. GET parameters are taken from given URL. + * Applies Routing and additionalParameters to the request to be dispatched. + * If Routes have not been loaded they will be loaded, and app/config/routes.php will be run. * - * @param CakeRequest $fromUrl CakeRequest object to mine for parameter information. - * @return array Parameters found in POST and GET. + * @param CakeRequest $request CakeRequest object to mine for parameter information. + * @param array $additionalParams An array of additional parameters to set to the request. + * Useful when Object::requestAction() is involved + * @return CakeRequest The request object with routing params set. */ public function parseParams(CakeRequest $request, $additionalParams = array()) { if (count(Router::$routes) > 0) { @@ -213,16 +215,14 @@ class Dispatcher { * @return mixed name of controller if not loaded, or object if loaded */ protected function _getController($request) { - $controller = false; $ctrlClass = $this->_loadController($request); if (!$ctrlClass) { - return $controller; + return false; } $ctrlClass .= 'Controller'; if (class_exists($ctrlClass)) { - $controller = new $ctrlClass($request); + return new $ctrlClass($request); } - return $controller; } /** From f0ac462775a24e5801ac234bdc10c5485154206c Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 15 Nov 2010 22:53:49 -0500 Subject: [PATCH 082/160] Updating test cases with failing tests. --- .../libs/controller/component_collection.test.php | 2 +- .../cases/libs/controller/components/auth.test.php | 11 ++++++----- cake/tests/cases/libs/debugger.test.php | 3 ++- cake/tests/cases/libs/view/helpers/rss.test.php | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cake/tests/cases/libs/controller/component_collection.test.php b/cake/tests/cases/libs/controller/component_collection.test.php index 4e38e6938..d41f74095 100644 --- a/cake/tests/cases/libs/controller/component_collection.test.php +++ b/cake/tests/cases/libs/controller/component_collection.test.php @@ -65,7 +65,7 @@ class ComponentCollectionTest extends CakeTestCase { * @return void */ function testLoadWithEnableFalse() { - $result = $this->Components->load('Cookie', array('callbacks' => false)); + $result = $this->Components->load('Cookie', array('enabled' => false)); $this->assertType('CookieComponent', $result); $this->assertType('CookieComponent', $this->Components->Cookie); diff --git a/cake/tests/cases/libs/controller/components/auth.test.php b/cake/tests/cases/libs/controller/components/auth.test.php index 6ca7e7201..98f389efd 100644 --- a/cake/tests/cases/libs/controller/components/auth.test.php +++ b/cake/tests/cases/libs/controller/components/auth.test.php @@ -1451,17 +1451,18 @@ class AuthTest extends CakeTestCase { * @return void */ function testAjaxLogin() { - App::build(array('views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS))); + App::build(array( + 'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS) + )); $_SERVER['HTTP_X_REQUESTED_WITH'] = "XMLHttpRequest"; - if (!class_exists('dispatcher')) { - require CAKE . 'dispatcher.php'; - } + App::import('Core', 'Dispatcher'); ob_start(); $Dispatcher = new Dispatcher(); - $Dispatcher->dispatch('/ajax_auth/add', array('return' => 1)); + $Dispatcher->dispatch(new CakeRequest('/ajax_auth/add'), array('return' => 1)); $result = ob_get_clean(); + $this->assertEqual("Ajax!\nthis is the test element", str_replace("\r\n", "\n", $result)); unset($_SERVER['HTTP_X_REQUESTED_WITH']); } diff --git a/cake/tests/cases/libs/debugger.test.php b/cake/tests/cases/libs/debugger.test.php index d29ee6093..e5a5aff14 100644 --- a/cake/tests/cases/libs/debugger.test.php +++ b/cake/tests/cases/libs/debugger.test.php @@ -243,7 +243,8 @@ class DebuggerTest extends CakeTestCase { View::$modelId = NULL View::$uuids = array View::$output = false - View::$request = NULL'; + View::$request = NULL + View::$elementCache = "default"'; $result = str_replace(array("\t", "\r\n", "\n"), "", strtolower($result)); $expected = str_replace(array("\t", "\r\n", "\n"), "", strtolower($expected)); $this->assertEqual($result, $expected); diff --git a/cake/tests/cases/libs/view/helpers/rss.test.php b/cake/tests/cases/libs/view/helpers/rss.test.php index 6b8b36887..afc3e54e9 100644 --- a/cake/tests/cases/libs/view/helpers/rss.test.php +++ b/cake/tests/cases/libs/view/helpers/rss.test.php @@ -36,6 +36,7 @@ class RssHelperTest extends CakeTestCase { */ function setUp() { parent::setUp(); + $controller = null; $this->View = new View($controller); $this->Rss = new RssHelper($this->View); } From 5349257bbd90450ed0cfd60873d10274749e64b1 Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 16 Nov 2010 07:32:14 -0500 Subject: [PATCH 083/160] 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 084/160] 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 085/160] 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 086/160] 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 087/160] 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 088/160] 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 089/160] 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 090/160] 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 091/160] 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 092/160] 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 093/160] 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 094/160] 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 095/160] 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 096/160] 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 097/160] 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 098/160] 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 099/160] 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 100/160] 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 101/160] 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 102/160] 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 103/160] 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 104/160] 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 105/160] 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 106/160] 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 107/160] 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 108/160] 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 109/160] 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 110/160] 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 111/160] 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 112/160] 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 113/160] 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 114/160] 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) { From 6d5cf96d1c302ddf1beba2cb353e3c8db31b6b47 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 19:59:46 -0500 Subject: [PATCH 115/160] Making instance method use the instance, and not call itself statically. --- cake/libs/debugger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/libs/debugger.php b/cake/libs/debugger.php index 87b71aeb3..dd99977d6 100644 --- a/cake/libs/debugger.php +++ b/cake/libs/debugger.php @@ -295,7 +295,7 @@ class Debugger { $data = compact( 'level', 'error', 'code', 'helpID', 'description', 'file', 'path', 'line', 'context' ); - echo self::_output($data); + echo $_this->_output($data); if (Configure::read('log')) { $tpl = $_this->_templates['log']['error']; From da3bf1c7472f1730424de172a5a35ba8ff23da50 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 20:00:27 -0500 Subject: [PATCH 116/160] Adding ErrorHandler::handleError for consolidating core error handling out of CakeLog and Debugger. --- cake/libs/error_handler.php | 23 ++++++++++ cake/tests/cases/libs/error_handler.test.php | 45 ++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 53e1dfbaf..db1afceec 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -178,6 +178,29 @@ class ErrorHandler { $error->render(); } +/** + * Set as the default error handler by CakePHP. Use Configure::write('Error.handler', $callback), to use your own + * error handling methods. This function will use Debugger to display errors when debug > 0. And + * will log errors to CakeLog, when debug == 0. + * + * You can use Configure::write('Error.level', $value); to set what type of errors will be handled here. + * + * @param integer $code Code of error + * @param string $description Error description + * @param string $file File on which error occurred + * @param integer $line Line that triggered the error + * @param array $context Context + * @return boolean true if error was handled + */ + public static function handleError($code, $description, $file = null, $line = null, $context = null) { + $debug = Configure::read('debug'); + if ($debug) { + return Debugger::handleError($code, $description, $file, $line, $context); + } else { + return CakeLog::handleError($code, $description, $file, $line, $context); + } + } + /** * Renders the response for the exception. * diff --git a/cake/tests/cases/libs/error_handler.test.php b/cake/tests/cases/libs/error_handler.test.php index 631ec3efb..66cbbdcaa 100644 --- a/cake/tests/cases/libs/error_handler.test.php +++ b/cake/tests/cases/libs/error_handler.test.php @@ -151,6 +151,7 @@ class MissingWidgetThingException extends NotFoundException { } */ class ErrorHandlerTest extends CakeTestCase { + var $_restoreError = false; /** * setup create a request object to get out of router later. * @@ -179,6 +180,9 @@ class ErrorHandlerTest extends CakeTestCase { function teardown() { Configure::write('debug', $this->_debug); App::build(); + if ($this->_restoreError) { + restore_error_handler(); + } } /** @@ -191,6 +195,47 @@ class ErrorHandlerTest extends CakeTestCase { return $error; } +/** + * test error handling when debug is on, an error should be printed from Debugger. + * + * @return void + */ + function testHandleErrorDebugOn() { + set_error_handler('ErrorHandler::handleError'); + $this->_restoreError = true; + + ob_start(); + $wrong .= ''; + $result = ob_get_clean(); + + $this->assertPattern('/
/', $result);
+		$this->assertPattern('/Notice<\/b>/', $result);
+		$this->assertPattern('/variable:\s+wrong/', $result);
+	}
+
+/**
+ * Test that errors go into CakeLog when debug = 0.
+ *
+ * @return void
+ */
+	function testHandleErrorDebugOff() {
+		Configure::write('debug', 0);
+		@unlink(LOGS . 'debug.log');
+
+		set_error_handler('ErrorHandler::handleError');
+		$this->_restoreError = true;
+
+		$out .= '';
+
+		$result = file(LOGS . 'debug.log');
+		$this->assertEqual(count($result), 1);
+		$this->assertPattern(
+			'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Notice: Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
+			$result[0]
+		);
+		@unlink(LOGS . 'debug.log');
+	}
+
 /**
  * test handleException generating a page.
  *

From 4960b6e7bf3c8114056c4cc21c8dfc6b4a070f79 Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 20:19:15 -0500
Subject: [PATCH 117/160] Changing method names on CakeLog and Debugger to
 better reflect what they do.  Updating test cases.

---
 cake/libs/cake_log.php                  |  9 +--------
 cake/libs/debugger.php                  | 22 +---------------------
 cake/tests/cases/libs/cake_log.test.php |  2 +-
 cake/tests/cases/libs/debugger.test.php | 21 +++++++++++++--------
 4 files changed, 16 insertions(+), 38 deletions(-)

diff --git a/cake/libs/cake_log.php b/cake/libs/cake_log.php
index ce0475156..8672ad821 100644
--- a/cake/libs/cake_log.php
+++ b/cake/libs/cake_log.php
@@ -236,10 +236,7 @@ class CakeLog {
  * @param array $context Context
  * @return void
  */
-	public static function handleError($code, $description, $file = null, $line = null, $context = null) {
-		if ($code === 2048 || $code === 8192) {
-			return;
-		}
+	public static function logError($code, $description, $file = null, $line = null, $context = null) {
 		switch ($code) {
 			case E_PARSE:
 			case E_ERROR:
@@ -269,7 +266,3 @@ class CakeLog {
 		CakeLog::write($level, $message);
 	}
 }
-
-if (!defined('DISABLE_DEFAULT_ERROR_HANDLING')) {
-	set_error_handler(array('CakeLog', 'handleError'));
-}
diff --git a/cake/libs/debugger.php b/cake/libs/debugger.php
index dd99977d6..a21ae6dd6 100644
--- a/cake/libs/debugger.php
+++ b/cake/libs/debugger.php
@@ -236,11 +236,7 @@ class Debugger {
  * @param array $context Context
  * @return boolean true if error was handled
  */
-	public function handleError($code, $description, $file = null, $line = null, $context = null) {
-		if (error_reporting() == 0 || $code === 2048 || $code === 8192) {
-			return;
-		}
-
+	public function showError($code, $description, $file = null, $line = null, $context = null) {
 		$_this = Debugger::getInstance();
 
 		if (empty($file)) {
@@ -672,20 +668,4 @@ class Debugger {
 		}
 	}
 
-/**
- * Invokes the given debugger object as the current error handler, taking over control from the
- * previous handler in a stack-like hierarchy.
- *
- * @param object $debugger A reference to the Debugger object
- * @access public
- * @static
- * @link http://book.cakephp.org/view/1191/Using-the-Debugger-Class
- */
-	function invoke(&$debugger) {
-		set_error_handler(array(&$debugger, 'handleError'));
-	}
-}
-
-if (!defined('DISABLE_DEFAULT_ERROR_HANDLING')) {
-	Debugger::invoke(Debugger::getInstance());
 }
diff --git a/cake/tests/cases/libs/cake_log.test.php b/cake/tests/cases/libs/cake_log.test.php
index 458821e91..4fe3d100b 100644
--- a/cake/tests/cases/libs/cake_log.test.php
+++ b/cake/tests/cases/libs/cake_log.test.php
@@ -174,7 +174,7 @@ class CakeLogTest extends CakeTestCase {
 		Configure::write('log', E_ALL & ~E_DEPRECATED);
 		Configure::write('debug', 0);
 
-		set_error_handler(array('CakeLog', 'handleError'));
+		set_error_handler(array('CakeLog', 'logError'));
 		$out .= '';
 
 		$result = file(LOGS . 'debug.log');
diff --git a/cake/tests/cases/libs/debugger.test.php b/cake/tests/cases/libs/debugger.test.php
index e5a5aff14..d6ea5ac8e 100644
--- a/cake/tests/cases/libs/debugger.test.php
+++ b/cake/tests/cases/libs/debugger.test.php
@@ -39,6 +39,8 @@ class DebuggerTest extends CakeTestCase {
 // !!! Be careful with changing code below as it may
 // !!! change line numbers which are used in the tests
 // !!!
+	protected $_restoreError = false;
+
 /**
  * setUp method
  *
@@ -60,6 +62,9 @@ class DebuggerTest extends CakeTestCase {
 	function tearDown() {
 		parent::teardown();
 		Configure::write('log', true);
+		if ($this->_restoreError) {
+			restore_error_handler();
+		}
 	}
 
 /**
@@ -106,7 +111,9 @@ class DebuggerTest extends CakeTestCase {
  * @return void
  */
 	function testOutput() {
-		Debugger::invoke(Debugger::getInstance());
+		set_error_handler('Debugger::showError');
+		$this->_restoreError = true;
+
 		$result = Debugger::output(false);
 		$this->assertEqual($result, '');
 		$out .= '';
@@ -141,8 +148,8 @@ class DebuggerTest extends CakeTestCase {
 			'pre' => array('class' => 'cake-debug'),
 			'a' => array(
 				'href' => "javascript:void(0);",
-				'onclick' => "document.getElementById('cakeErr4-trace').style.display = " .
-				             "(document.getElementById('cakeErr4-trace').style.display == 'none'" .
+				'onclick' => "document.getElementById('cakeErr9-trace').style.display = " .
+				             "(document.getElementById('cakeErr9-trace').style.display == 'none'" .
 				             " ? '' : 'none');"
 			),
 			'b' => array(), 'Notice', '/b', ' (8)',
@@ -151,8 +158,6 @@ class DebuggerTest extends CakeTestCase {
 		$this->assertPattern('/Undefined variable:\s+buzz/', $result[1]);
 		$this->assertPattern('/]+>Code/', $result[1]);
 		$this->assertPattern('/]+>Context/', $result[2]);
-
-		restore_error_handler();
 	}
 
 /**
@@ -161,7 +166,9 @@ class DebuggerTest extends CakeTestCase {
  * @return void
  */
 	function testChangeOutputFormats() {
-		Debugger::invoke(Debugger::getInstance());
+		set_error_handler('Debugger::showError');
+		$this->_restoreError = true;
+
 		Debugger::output('js', array(
 			'traceLine' => '{:reference} - {:path}, line {:line}'
@@ -190,8 +197,6 @@ class DebuggerTest extends CakeTestCase {
 			'/error'
 		);
 		$this->assertTags($result, $data, true);
-		
-		restore_error_handler();
 	}
 
 /**

From e68a1a094e503bdebeced4961adf6779cda51f21 Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 20:32:44 -0500
Subject: [PATCH 118/160] Moving error and exception handler configuration into
 Configure, as settings.  You can use Error.handler and Exception.handler to
 define the error and exception handlers for your application.

---
 cake/bootstrap.php          |  1 -
 cake/libs/configure.php     | 22 ++++++++--------------
 cake/libs/error_handler.php | 10 ++++++++--
 3 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/cake/bootstrap.php b/cake/bootstrap.php
index 105d3ae4c..e35c9b41d 100644
--- a/cake/bootstrap.php
+++ b/cake/bootstrap.php
@@ -34,7 +34,6 @@ require LIBS . 'configure.php';
 require LIBS . 'set.php';
 require LIBS . 'cache.php';
 require LIBS . 'error_handler.php';
-set_exception_handler(array('ErrorHandler', 'handleException'));
 
 Configure::bootstrap(isset($boot) ? $boot : true);
 
diff --git a/cake/libs/configure.php b/cake/libs/configure.php
index a2a690acd..bffe661db 100644
--- a/cake/libs/configure.php
+++ b/cake/libs/configure.php
@@ -103,9 +103,6 @@ class Configure {
 		if (isset($config['debug']) || isset($config['log'])) {
 			$reporting = 0;
 			if (self::$_values['debug']) {
-				if (!class_exists('Debugger')) {
-					require LIBS . 'debugger.php';
-				}
 				$reporting = E_ALL & ~E_DEPRECATED;
 				if (function_exists('ini_set')) {
 					ini_set('display_errors', 1);
@@ -113,17 +110,6 @@ class Configure {
 			} elseif (function_exists('ini_set')) {
 				ini_set('display_errors', 0);
 			}
-
-			if (isset(self::$_values['log']) && self::$_values['log']) {
-				if (!class_exists('CakeLog')) {
-					require LIBS . 'cake_log.php';
-				}
-				if (is_integer(self::$_values['log']) && !self::$_values['debug']) {
-					$reporting = self::$_values['log'];
-				} else {
-					$reporting = E_ALL & ~E_DEPRECATED;
-				}
-			}
 			error_reporting($reporting);
 		}
 		return true;
@@ -381,6 +367,14 @@ class Configure {
 					)));
 				}
 			}
+
+			if (!empty(self::$_values['Error']['handler'])) {
+				set_error_handler(self::$_values['Error']['handler']);
+			}
+			if (!empty(self::$_values['Exception']['handler'])) {
+				set_exception_handler(self::$_values['Exception']['handler']);
+			}
+
 			App::init();
 			App::build();
 			if (!include(CONFIGS . 'bootstrap.php')) {
diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php
index db1afceec..60b4a92c8 100644
--- a/cake/libs/error_handler.php
+++ b/cake/libs/error_handler.php
@@ -195,9 +195,15 @@ class ErrorHandler {
 	public static function handleError($code, $description, $file = null, $line = null, $context = null) {
 		$debug = Configure::read('debug');
 		if ($debug) {
-			return Debugger::handleError($code, $description, $file, $line, $context);
+			if (!class_exists('Debugger')) {
+				require LIBS . 'debugger.php';
+			}
+			return Debugger::showError($code, $description, $file, $line, $context);
 		} else {
-			return CakeLog::handleError($code, $description, $file, $line, $context);
+			if (!class_exists('CakeLog')) {
+				require LIBS . 'cake_log.php';
+			}
+			return CakeLog::logError($code, $description, $file, $line, $context);
 		}
 	}
 

From b371de8cf452e5219ca8bdc08876fae9265b69fc Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 20:34:10 -0500
Subject: [PATCH 119/160] Moving error handler configuration setting after
 application bootstrap is done, this will allow classes to be imported using
 the cache.

---
 cake/libs/configure.php | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/cake/libs/configure.php b/cake/libs/configure.php
index bffe661db..bc0eea92c 100644
--- a/cake/libs/configure.php
+++ b/cake/libs/configure.php
@@ -368,18 +368,18 @@ class Configure {
 				}
 			}
 
+			App::init();
+			App::build();
+			if (!include(CONFIGS . 'bootstrap.php')) {
+				trigger_error(sprintf(__("Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP."), CONFIGS), E_USER_ERROR);
+			}
+			
 			if (!empty(self::$_values['Error']['handler'])) {
 				set_error_handler(self::$_values['Error']['handler']);
 			}
 			if (!empty(self::$_values['Exception']['handler'])) {
 				set_exception_handler(self::$_values['Exception']['handler']);
 			}
-
-			App::init();
-			App::build();
-			if (!include(CONFIGS . 'bootstrap.php')) {
-				trigger_error(sprintf(__("Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP."), CONFIGS), E_USER_ERROR);
-			}
 		}
 	}
-}
+}
\ No newline at end of file

From a8ba73da624db1f4b579d171887b0b6f1eae5c56 Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 20:37:50 -0500
Subject: [PATCH 120/160] Removing wrapper method that didn't contribute
 anything. Adding doc blocks for the sequence bootstrapping takes.

---
 cake/libs/configure.php | 131 ++++++++++++++++++++--------------------
 1 file changed, 64 insertions(+), 67 deletions(-)

diff --git a/cake/libs/configure.php b/cake/libs/configure.php
index bc0eea92c..72012e554 100644
--- a/cake/libs/configure.php
+++ b/cake/libs/configure.php
@@ -42,11 +42,74 @@ class Configure {
 
 /**
  * Initializes configure and runs the bootstrap process.
+ * Bootstrapping includes the following steps:
+ *
+ * - Setup App array in Configure.
+ * - Include app/config/core.php.
+ * - Configure core cache configurations.
+ * - Load App cache files.
+ * - Include app/config/bootstrap.php.
+ * - Setup error/exception handlers.
  *
  * @return void
  */
 	public static function bootstrap($boot = true) {
-		self::__loadBootstrap($boot);
+		if ($boot) {
+			self::write('App', array('base' => false, 'baseUrl' => false, 'dir' => APP_DIR, 'webroot' => WEBROOT_DIR, 'www_root' => WWW_ROOT));
+
+			if (!include(CONFIGS . 'core.php')) {
+				trigger_error(sprintf(__("Can't find application core file. Please create %score.php, and make sure it is readable by PHP."), CONFIGS), E_USER_ERROR);
+			}
+
+			if (Configure::read('Cache.disable') !== true) {
+				$cache = Cache::config('default');
+
+				if (empty($cache['settings'])) {
+					trigger_error(__('Cache not configured properly. Please check Cache::config(); in APP/config/core.php'), E_USER_WARNING);
+					$cache = Cache::config('default', array('engine' => 'File'));
+				}
+				$path = $prefix = $duration = null;
+
+				if (!empty($cache['settings']['path'])) {
+					$path = realpath($cache['settings']['path']);
+				} else {
+					$prefix = $cache['settings']['prefix'];
+				}
+
+				if (Configure::read('debug') >= 1) {
+					$duration = '+10 seconds';
+				} else {
+					$duration = '+999 days';
+				}
+
+				if (Cache::config('_cake_core_') === false) {
+					Cache::config('_cake_core_', array_merge((array)$cache['settings'], array(
+						'prefix' => $prefix . 'cake_core_', 'path' => $path . DS . 'persistent' . DS,
+						'serialize' => true, 'duration' => $duration
+					)));
+				}
+
+				if (Cache::config('_cake_model_') === false) {
+					Cache::config('_cake_model_', array_merge((array)$cache['settings'], array(
+						'prefix' => $prefix . 'cake_model_', 'path' => $path . DS . 'models' . DS,
+						'serialize' => true, 'duration' => $duration
+					)));
+				}
+			}
+
+			App::init();
+			App::build();
+			if (!include(CONFIGS . 'bootstrap.php')) {
+				trigger_error(sprintf(__("Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP."), CONFIGS), E_USER_ERROR);
+			}
+			
+			if (!empty(self::$_values['Error']['handler'])) {
+				set_error_handler(self::$_values['Error']['handler']);
+			}
+			if (!empty(self::$_values['Exception']['handler'])) {
+				set_exception_handler(self::$_values['Exception']['handler']);
+			}
+		}
 	}
 
 /**
@@ -316,70 +379,4 @@ class Configure {
 		}
 	}
 
-/**
- * Loads app/config/bootstrap.php.
- * If the alternative paths are set in this file
- * they will be added to the paths vars.
- *
- * @param boolean $boot Load application bootstrap (if true)
- * @return void
- */
-	private static function __loadBootstrap($boot) {
-		if ($boot) {
-			Configure::write('App', array('base' => false, 'baseUrl' => false, 'dir' => APP_DIR, 'webroot' => WEBROOT_DIR, 'www_root' => WWW_ROOT));
-
-			if (!include(CONFIGS . 'core.php')) {
-				trigger_error(sprintf(__("Can't find application core file. Please create %score.php, and make sure it is readable by PHP."), CONFIGS), E_USER_ERROR);
-			}
-
-			if (Configure::read('Cache.disable') !== true) {
-				$cache = Cache::config('default');
-
-				if (empty($cache['settings'])) {
-					trigger_error(__('Cache not configured properly. Please check Cache::config(); in APP/config/core.php'), E_USER_WARNING);
-					$cache = Cache::config('default', array('engine' => 'File'));
-				}
-				$path = $prefix = $duration = null;
-
-				if (!empty($cache['settings']['path'])) {
-					$path = realpath($cache['settings']['path']);
-				} else {
-					$prefix = $cache['settings']['prefix'];
-				}
-
-				if (Configure::read('debug') >= 1) {
-					$duration = '+10 seconds';
-				} else {
-					$duration = '+999 days';
-				}
-
-				if (Cache::config('_cake_core_') === false) {
-					Cache::config('_cake_core_', array_merge((array)$cache['settings'], array(
-						'prefix' => $prefix . 'cake_core_', 'path' => $path . DS . 'persistent' . DS,
-						'serialize' => true, 'duration' => $duration
-					)));
-				}
-
-				if (Cache::config('_cake_model_') === false) {
-					Cache::config('_cake_model_', array_merge((array)$cache['settings'], array(
-						'prefix' => $prefix . 'cake_model_', 'path' => $path . DS . 'models' . DS,
-						'serialize' => true, 'duration' => $duration
-					)));
-				}
-			}
-
-			App::init();
-			App::build();
-			if (!include(CONFIGS . 'bootstrap.php')) {
-				trigger_error(sprintf(__("Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP."), CONFIGS), E_USER_ERROR);
-			}
-			
-			if (!empty(self::$_values['Error']['handler'])) {
-				set_error_handler(self::$_values['Error']['handler']);
-			}
-			if (!empty(self::$_values['Exception']['handler'])) {
-				set_exception_handler(self::$_values['Exception']['handler']);
-			}
-		}
-	}
 }
\ No newline at end of file

From 561fe7b91f79d6870a9b0558d27e109db0ea986f Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 20:42:48 -0500
Subject: [PATCH 121/160] Adding basic configuration for Error and Exception
 handling.

---
 app/config/core.php | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/app/config/core.php b/app/config/core.php
index 36956c570..cf1a0ab44 100644
--- a/app/config/core.php
+++ b/app/config/core.php
@@ -50,6 +50,25 @@
  */
 	Configure::write('log', true);
 
+/**
+ * Configure the Error handler used to handle errors for your application.  By default
+ * ErrorHandler::handleError() is used.  It will display errors using Debugger, when debug > 0
+ * and log errors with CakeLog when debug = 0.  You can set it to any static method that is built to handle 
+ * errors.
+ */
+	Configure::write('Error', array(
+		'handler' => 'ErrorHandler::handleError',
+	));
+
+/**
+ * Configure the default Exception handler.  This method will be invoked each time there is an uncaught exception
+ * by default, ErrorHandler::handleException() is used. It will display a HTML page for the exception, and 
+ * while debug > 0, framework errors like Missing Controller will be displayed.
+ */
+	Configure::write('Exception', array(
+		'handler' => 'ErrorHandler::handleException'
+	));
+
 /**
  * Application wide charset encoding
  */

From a621ac1ba3d3e819c772312713fb47b03b1c278d Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 20:56:03 -0500
Subject: [PATCH 122/160] Adding level to the core.php file, this lets you
 choose which error levels you are interested in for your application.
 Removing hardcoded error_reporting levels in Configure.

---
 app/config/core.php     |  9 +++++++--
 cake/libs/configure.php | 14 +++++++-------
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/app/config/core.php b/app/config/core.php
index cf1a0ab44..1674efd33 100644
--- a/app/config/core.php
+++ b/app/config/core.php
@@ -53,11 +53,16 @@
 /**
  * Configure the Error handler used to handle errors for your application.  By default
  * ErrorHandler::handleError() is used.  It will display errors using Debugger, when debug > 0
- * and log errors with CakeLog when debug = 0.  You can set it to any static method that is built to handle 
- * errors.
+ * and log errors with CakeLog when debug = 0.
+ *
+ * Options:
+ *
+ * - `handler` The callback to handle errors. You can set this to any callback type, including anonymous functions.
+ * - `level` The level of errors you are interested in capturing.
  */
 	Configure::write('Error', array(
 		'handler' => 'ErrorHandler::handleError',
+		'level' => E_ALL & ~E_DEPRECATED
 	));
 
 /**
diff --git a/cake/libs/configure.php b/cake/libs/configure.php
index 72012e554..bd88c5a18 100644
--- a/cake/libs/configure.php
+++ b/cake/libs/configure.php
@@ -106,6 +106,9 @@ class Configure {
 			if (!empty(self::$_values['Error']['handler'])) {
 				set_error_handler(self::$_values['Error']['handler']);
 			}
+			if (isset(self::$_values['Error']['level'])) {
+				error_reporting(self::$_values['Error']['level']);
+			}
 			if (!empty(self::$_values['Exception']['handler'])) {
 				set_exception_handler(self::$_values['Exception']['handler']);
 			}
@@ -164,16 +167,13 @@ class Configure {
 		}
 
 		if (isset($config['debug']) || isset($config['log'])) {
-			$reporting = 0;
-			if (self::$_values['debug']) {
-				$reporting = E_ALL & ~E_DEPRECATED;
-				if (function_exists('ini_set')) {
+			if (function_exists('ini_set')) {
+				if (self::$_values['debug']) {
 					ini_set('display_errors', 1);
+				} else {
+					ini_set('display_errors', 0);
 				}
-			} elseif (function_exists('ini_set')) {
-				ini_set('display_errors', 0);
 			}
-			error_reporting($reporting);
 		}
 		return true;
 	}

From 6c2c4f91df19e8d1e51120b7c16ad38eeaa7c05d Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 20:58:20 -0500
Subject: [PATCH 123/160] Removing dead tests and updating ones to reflect
 changes in how Configure works.

---
 cake/tests/cases/libs/configure.test.php | 42 ++----------------------
 1 file changed, 3 insertions(+), 39 deletions(-)

diff --git a/cake/tests/cases/libs/configure.test.php b/cake/tests/cases/libs/configure.test.php
index 11ef38f05..a99790291 100644
--- a/cake/tests/cases/libs/configure.test.php
+++ b/cake/tests/cases/libs/configure.test.php
@@ -135,54 +135,18 @@ class ConfigureTest extends CakeTestCase {
 	}
 
 /**
- * testSetErrorReporting Level
+ * test setting display_errors with debug.
  *
  * @return void
  */
-	function testSetErrorReportingLevel() {
-		Configure::write('log', false);
-
+	function testDebugSettingDisplayErrors() {
 		Configure::write('debug', 0);
-		$result = ini_get('error_reporting');
+		$result = ini_get('display_errors');
 		$this->assertEqual($result, 0);
 
 		Configure::write('debug', 2);
-		$result = ini_get('error_reporting');
-		$this->assertEqual($result, E_ALL & ~E_DEPRECATED);
-
 		$result = ini_get('display_errors');
 		$this->assertEqual($result, 1);
-
-		Configure::write('debug', 0);
-		$result = ini_get('error_reporting');
-		$this->assertEqual($result, 0);
-	}
-
-/**
- * test that log and debug configure values interact well.
- *
- * @return void
- */
-	function testInteractionOfDebugAndLog() {
-		Configure::write('log', false);
-
-		Configure::write('debug', 0);
-		$this->assertEqual(ini_get('error_reporting'), 0);
-		$this->assertEqual(ini_get('display_errors'), 0);
-
-		Configure::write('log', E_WARNING);
-		Configure::write('debug', 0);
-		$this->assertEqual(ini_get('error_reporting'), E_WARNING);
-		$this->assertEqual(ini_get('display_errors'), 0);
-
-		Configure::write('debug', 2);
-		$this->assertEqual(ini_get('error_reporting'), E_ALL & ~E_DEPRECATED);
-		$this->assertEqual(ini_get('display_errors'), 1);
-
-		Configure::write('debug', 0);
-		Configure::write('log', false);
-		$this->assertEqual(ini_get('error_reporting'), 0);
-		$this->assertEqual(ini_get('display_errors'), 0);
 	}
 
 /**

From f373fc19d15bf717180577d8213b3bdcde32b490 Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 21:07:23 -0500
Subject: [PATCH 124/160] Removing logError from CakeLog,  it will be moved
 into ErrorHandler::handleError()

---
 cake/libs/cake_log.php                  | 45 +------------------------
 cake/tests/cases/libs/cake_log.test.php | 25 ++------------
 2 files changed, 4 insertions(+), 66 deletions(-)

diff --git a/cake/libs/cake_log.php b/cake/libs/cake_log.php
index 8672ad821..f1c5b32cf 100644
--- a/cake/libs/cake_log.php
+++ b/cake/libs/cake_log.php
@@ -99,7 +99,7 @@ class CakeLog {
  * @return boolean success of configuration.
  * @throws Exception
  */
-	static function config($key, $config) {
+	public static function config($key, $config) {
 		if (empty($config['engine'])) {
 			throw new Exception(__('Missing logger classname'));
 		}
@@ -222,47 +222,4 @@ class CakeLog {
 		}
 		return true;
 	}
-
-/**
- * An error_handler that will log errors to file using CakeLog::write();
- * You can control how verbose and what type of errors this error_handler will 
- * catch using `Configure::write('log', $value)`.  See core.php for more information.
- *
- *
- * @param integer $code Code of error
- * @param string $description Error description
- * @param string $file File on which error occurred
- * @param integer $line Line that triggered the error
- * @param array $context Context
- * @return void
- */
-	public static function logError($code, $description, $file = null, $line = null, $context = null) {
-		switch ($code) {
-			case E_PARSE:
-			case E_ERROR:
-			case E_CORE_ERROR:
-			case E_COMPILE_ERROR:
-			case E_USER_ERROR:
-				$error = 'Fatal Error';
-				$level = LOG_ERROR;
-			break;
-			case E_WARNING:
-			case E_USER_WARNING:
-			case E_COMPILE_WARNING:
-			case E_RECOVERABLE_ERROR:
-				$error = 'Warning';
-				$level = LOG_WARNING;
-			break;
-			case E_NOTICE:
-			case E_USER_NOTICE:
-				$error = 'Notice';
-				$level = LOG_NOTICE;
-			break;
-			default:
-				return;
-			break;
-		}
-		$message = $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
-		CakeLog::write($level, $message);
-	}
 }
diff --git a/cake/tests/cases/libs/cake_log.test.php b/cake/tests/cases/libs/cake_log.test.php
index 4fe3d100b..52c5c5abc 100644
--- a/cake/tests/cases/libs/cake_log.test.php
+++ b/cake/tests/cases/libs/cake_log.test.php
@@ -116,7 +116,9 @@ class CakeLogTest extends CakeTestCase {
 		$result = CakeLog::configured();
 		$this->assertEqual($result, array('file'));
 
-		@unlink(LOGS . 'error.log');
+		if (file_exists(LOGS . 'error.log')) {
+			@unlink(LOGS . 'error.log');
+		}
 		CakeLog::write(LOG_WARNING, 'Test warning');
 		$this->assertTrue(file_exists(LOGS . 'error.log'));
 
@@ -164,25 +166,4 @@ class CakeLogTest extends CakeTestCase {
 		unlink(LOGS . 'error.log');
 	}
 
-/**
- * Test logging with the error handler.
- *
- * @return void
- */
-	function testLoggingWithErrorHandling() {
-		@unlink(LOGS . 'debug.log');
-		Configure::write('log', E_ALL & ~E_DEPRECATED);
-		Configure::write('debug', 0);
-
-		set_error_handler(array('CakeLog', 'logError'));
-		$out .= '';
-
-		$result = file(LOGS . 'debug.log');
-		$this->assertEqual(count($result), 1);
-		$this->assertPattern(
-			'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Notice: Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
-			$result[0]
-		);
-		@unlink(LOGS . 'debug.log');
-	}
 }

From 722b1a02bab9aaed4b13d595d089870397d8b7f7 Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 22:06:18 -0500
Subject: [PATCH 125/160] Adding Debugger output to ErrorHandler::handleError,
 and adding tracing for log writes. Renaming Debugger::_output() ->
 Debugger::outputError() and making it public instead of protected.

---
 cake/libs/debugger.php                       | 14 ++--
 cake/libs/error_handler.php                  | 69 +++++++++++++++++++-
 cake/tests/cases/libs/error_handler.test.php | 35 +++++++++-
 3 files changed, 109 insertions(+), 9 deletions(-)

diff --git a/cake/libs/debugger.php b/cake/libs/debugger.php
index a21ae6dd6..bf31accf7 100644
--- a/cake/libs/debugger.php
+++ b/cake/libs/debugger.php
@@ -581,11 +581,12 @@ class Debugger {
 	}
 
 /**
- * Renders error messages
+ * Takes a processed array of data from an error and displays it in the chosen format.
  *
- * @param array $data Data about the current error
+ * @param string $data 
+ * @return void
  */
-	protected function _output($data = array()) {
+	public function outputError($data) {
 		$defaults = array(
 			'level' => 0,
 			'error' => 0,
@@ -594,13 +595,14 @@ class Debugger {
 			'description' => '',
 			'file' => '',
 			'line' => 0,
-			'context' => array()
+			'context' => array(),
+			'start' => 2
 		);
 		$data += $defaults;
 
-		$files = $this->trace(array('start' => 2, 'format' => 'points'));
+		$files = $this->trace(array('start' => $data['start'], 'format' => 'points'));
 		$code = $this->excerpt($files[0]['file'], $files[0]['line'] - 1, 1);
-		$trace = $this->trace(array('start' => 2, 'depth' => '20'));
+		$trace = $this->trace(array('start' => $data['start'], 'depth' => '20'));
 		$insertOpts = array('before' => '{:', 'after' => '}');
 		$context = array();
 		$links = array();
diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php
index 60b4a92c8..73deafc9c 100644
--- a/cake/libs/error_handler.php
+++ b/cake/libs/error_handler.php
@@ -184,6 +184,7 @@ class ErrorHandler {
  * will log errors to CakeLog, when debug == 0.
  *
  * You can use Configure::write('Error.level', $value); to set what type of errors will be handled here.
+ * Stack traces for errors can be enabled with Configure::write('Error.trace', true);
  *
  * @param integer $code Code of error
  * @param string $description Error description
@@ -193,20 +194,84 @@ class ErrorHandler {
  * @return boolean true if error was handled
  */
 	public static function handleError($code, $description, $file = null, $line = null, $context = null) {
+		$errorConfig = Configure::read('Error');
+		if ($errorConfig['level'] && ($code & ~$errorConfig['level'])) {
+			return;
+		}
+		list($error, $log) = self::_mapErrorCode($code);
+
 		$debug = Configure::read('debug');
 		if ($debug) {
 			if (!class_exists('Debugger')) {
 				require LIBS . 'debugger.php';
 			}
-			return Debugger::showError($code, $description, $file, $line, $context);
+			$data = array(
+				'level' => $log,
+				'code' => $code,
+				'error' => $error,
+				'description' => $description,
+				'file' => $file,
+				'line' => $line,
+				'context' => $context,
+				'start' => 2,
+				'path' => Debugger::trimPath($file)
+			);
+			return Debugger::getInstance()->outputError($data);
 		} else {
 			if (!class_exists('CakeLog')) {
 				require LIBS . 'cake_log.php';
 			}
-			return CakeLog::logError($code, $description, $file, $line, $context);
+			$message = $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
+			if (!empty($errorConfig['trace'])) {
+				if (!class_exists('Debugger')) {
+					require LIBS . 'debugger.php';
+				}
+				$trace = Debugger::trace(array('start' => 1, 'format' => 'log'));
+				$message .= "\nTrace:\n" . $trace . "\n";
+			}
+			return CakeLog::write($log, $message);
 		}
 	}
 
+/**
+ * Map an error code into an Error word, and log location.
+ *
+ * @param int $code Error code to map
+ * @return array Array of error word, and log location.
+ */
+	protected static function _mapErrorCode($code) {
+		switch ($code) {
+			case E_PARSE:
+			case E_ERROR:
+			case E_CORE_ERROR:
+			case E_COMPILE_ERROR:
+			case E_USER_ERROR:
+				$error = 'Fatal Error';
+				$log = LOG_ERROR;
+			break;
+			case E_WARNING:
+			case E_USER_WARNING:
+			case E_COMPILE_WARNING:
+			case E_RECOVERABLE_ERROR:
+				$error = 'Warning';
+				$log = LOG_WARNING;
+			break;
+			case E_NOTICE:
+			case E_USER_NOTICE:
+				$error = 'Notice';
+				$log = LOG_NOTICE;
+			break;
+			case E_STRICT:
+				$error = 'Strict';
+				$log = LOG_NOTICE;
+			break;
+			default:
+				return array();
+			break;
+		}
+		return array($error, $log);
+	}
+
 /**
  * Renders the response for the exception.
  *
diff --git a/cake/tests/cases/libs/error_handler.test.php b/cake/tests/cases/libs/error_handler.test.php
index 66cbbdcaa..e09e4fc85 100644
--- a/cake/tests/cases/libs/error_handler.test.php
+++ b/cake/tests/cases/libs/error_handler.test.php
@@ -170,6 +170,8 @@ class ErrorHandlerTest extends CakeTestCase {
 		$request->base = '';
 		Router::setRequestInfo($request);
 		$this->_debug = Configure::read('debug');
+		$this->_error = Configure::read('Error');
+		Configure::write('debug', 2);
 	}
 
 /**
@@ -179,6 +181,7 @@ class ErrorHandlerTest extends CakeTestCase {
  */
 	function teardown() {
 		Configure::write('debug', $this->_debug);
+		Configure::write('Error', $this->_error);
 		App::build();
 		if ($this->_restoreError) {
 			restore_error_handler();
@@ -220,7 +223,10 @@ class ErrorHandlerTest extends CakeTestCase {
  */
 	function testHandleErrorDebugOff() {
 		Configure::write('debug', 0);
-		@unlink(LOGS . 'debug.log');
+		Configure::write('Error.trace', false);
+		if (file_exists(LOGS . 'debug.log')) {
+			@unlink(LOGS . 'debug.log');
+		}
 
 		set_error_handler('ErrorHandler::handleError');
 		$this->_restoreError = true;
@@ -236,6 +242,33 @@ class ErrorHandlerTest extends CakeTestCase {
 		@unlink(LOGS . 'debug.log');
 	}
 
+/**
+ * Test that errors going into CakeLog include traces.
+ *
+ * @return void
+ */
+	function testHandleErrorLoggingTrace() {
+		Configure::write('debug', 0);
+		Configure::write('Error.trace', true);
+		if (file_exists(LOGS . 'debug.log')) {
+			@unlink(LOGS . 'debug.log');
+		}
+
+		set_error_handler('ErrorHandler::handleError');
+		$this->_restoreError = true;
+
+		$out .= '';
+
+		$result = file(LOGS . 'debug.log');
+		$this->assertPattern(
+			'/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Notice: Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
+			$result[0]
+		);
+		$this->assertPattern('/^Trace:/', $result[1]);
+		$this->assertPattern('/^ErrorHandlerTest\:\:testHandleErrorLoggingTrace\(\)/', $result[2]);
+		@unlink(LOGS . 'debug.log');
+	}
+
 /**
  * test handleException generating a page.
  *

From 8a35b76cc263efe2ea523357fb2a6381bae39b85 Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 22:19:49 -0500
Subject: [PATCH 126/160] Fixing error caused by removed method.

---
 cake/libs/debugger.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cake/libs/debugger.php b/cake/libs/debugger.php
index bf31accf7..b18b1faed 100644
--- a/cake/libs/debugger.php
+++ b/cake/libs/debugger.php
@@ -291,7 +291,7 @@ class Debugger {
 		$data = compact(
 			'level', 'error', 'code', 'helpID', 'description', 'file', 'path', 'line', 'context'
 		);
-		echo $_this->_output($data);
+		echo $_this->outputError($data);
 
 		if (Configure::read('log')) {
 			$tpl = $_this->_templates['log']['error'];

From e2c8e20afa589aa85846564236f2a1c46d480eac Mon Sep 17 00:00:00 2001
From: mark_story 
Date: Sun, 14 Nov 2010 22:20:29 -0500
Subject: [PATCH 127/160] Pulling exception page rendering out into a separate
 class, ErrorHandler felt very large and confusing, as it had a few too many
 jobs.

---
 cake/libs/error_handler.php                   | 185 +-----
 cake/libs/exception_renderer.php              | 233 +++++++
 cake/tests/cases/libs/error_handler.test.php  | 382 ------------
 .../cases/libs/exception_renderer.test.php    | 573 ++++++++++++++++++
 4 files changed, 809 insertions(+), 564 deletions(-)
 create mode 100644 cake/libs/exception_renderer.php
 create mode 100644 cake/tests/cases/libs/exception_renderer.test.php

diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php
index 73deafc9c..33146a289 100644
--- a/cake/libs/error_handler.php
+++ b/cake/libs/error_handler.php
@@ -54,119 +54,17 @@
  */
 class ErrorHandler {
 
-/**
- * Controller instance.
- *
- * @var Controller
- * @access public
- */
-	public $controller = null;
-
-/**
- * template to render for CakeException
- *
- * @var string
- */
-	public $template = '';
-
-/**
- * The method corresponding to the Exception this object is for.
- *
- * @var string
- */
-	public $method = '';
-
-/**
- * The exception being handled.
- *
- * @var Exception
- */
-	public $error = null;
-
-/**
- * Creates the controller to perform rendering on the error response.
- * If the error is a CakeException it will be converted to either a 400 or a 500
- * code error depending on the code used to construct the error.
- *
- * @param string $method Method producing the error
- * @param array $messages Error messages
- */
-	function __construct(Exception $exception) {
-		App::import('Core', 'Sanitize');
-
-		$this->controller = $this->_getController($exception);
-
-		if (method_exists($this->controller, 'apperror')) {
-			return $this->controller->appError($exception);
-		}
-		$method = $template = Inflector::variable(str_replace('Exception', '', get_class($exception)));
-		$code = $exception->getCode();
-
-		$methodExists = method_exists($this, $method);
-
-		if ($exception instanceof CakeException && !$methodExists) {
-			$method = '_cakeError';
-			if ($template == 'internalError') {
-				$template = 'error500';
-			}
-		} elseif (!$methodExists) {
-			$method = 'error500';
-			if ($code >= 400) {
-				$method = 'error400';
-			}
-		}
-
-		if (Configure::read('debug') == 0) {
-			$parentClass = get_parent_class($this);
-			if ($parentClass != 'ErrorHandler') {
-				$method = 'error400';
-			}
-			$parentMethods = (array)get_class_methods($parentClass);
-			if (in_array($method, $parentMethods)) {
-				$method = 'error400';
-			}
-			if ($code == 500) {
-				$method = 'error500';
-			}
-		}
-		$this->template = $template;
-		$this->method = $method;
-		$this->error = $exception;
-	}
-
-/**
- * Get the controller instance to handle the exception.
- * Override this method in subclasses to customize the controller used. 
- * This method returns the built in `CakeErrorController` normally, or if an error is repeated
- * a bare controller will be used.
- *
- * @param Exception $exception The exception to get a controller for.
- * @return Controller
- */
-	protected function _getController($exception) {
-		static $__previousError = null;
-		App::import('Controller', 'CakeError');
-
-		if ($__previousError != $exception) {
-			$__previousError = $exception;
-			$controller = new CakeErrorController();
-		} else {
-			$controller = new Controller();
-			$controller->viewPath = 'errors';
-		}
-		return $controller;
-	}
-
 /**
  * Set as the default exception handler by the CakePHP bootstrap process.
  *
  * This will either use an AppError class if your application has one,
- * or use the default ErrorHandler.
+ * or use the default ExceptionRenderer.
  *
  * @return void
  * @see http://php.net/manual/en/function.set-exception-handler.php
  */
 	public static function handleException(Exception $exception) {
+		App::import('Core', 'ExceptionRenderer');
 		if (file_exists(APP . 'app_error.php') || class_exists('AppError')) {
 			if (!class_exists('AppError')) {
 				require(APP . 'app_error.php');
@@ -174,7 +72,7 @@ class ErrorHandler {
 			$AppError = new AppError($exception);
 			return $AppError->render();
 		}
-		$error = new ErrorHandler($exception);
+		$error = new ExceptionRenderer($exception);
 		$error->render();
 	}
 
@@ -271,81 +169,4 @@ class ErrorHandler {
 		}
 		return array($error, $log);
 	}
-
-/**
- * Renders the response for the exception.
- *
- * @return void
- */
-	public function render() {
-		call_user_func_array(array($this, $this->method), array($this->error));
-	}
-
-/**
- * Generic handler for the internal framework errors CakePHP can generate.
- *
- * @param CakeExeption $error
- * @return void
- */
-	protected function _cakeError(CakeException $error) {
-		$url = Router::normalize($this->controller->request->here);
-		$code = $error->getCode();
-		$this->controller->response->statusCode($code);
-		$this->controller->set(array(
-			'code' => $code,
-			'url' => h($url),
-			'name' => $error->getMessage(),
-			'error' => $error,
-		));
-		$this->controller->set($error->getAttributes());
-		$this->_outputMessage($this->template);
-	}
-
-/**
- * Convenience method to display a 400 series page.
- *
- * @param array $params Parameters for controller
- */
-	public function error400($error) {
-		$message = $error->getMessage();
-		if (Configure::read('debug') == 0 && $error instanceof CakeException) {
-			$message = __('Not Found');
-		}
-		$url = Router::normalize($this->controller->request->here);
-		$this->controller->response->statusCode($error->getCode());
-		$this->controller->set(array(
-			'name' => $message,
-			'url' => h($url),
-			'error' => $error,
-		));
-		$this->_outputMessage('error400');
-	}
-
-/**
- * Convenience method to display a 500 page.
- *
- * @param array $params Parameters for controller
- */
-	public function error500($error) {
-		$url = Router::normalize($this->controller->request->here);
-		$code = ($error->getCode() > 500) ? $error->getCode() : 500;
-		$this->controller->response->statusCode($code);
-		$this->controller->set(array(
-			'name' => __('An Internal Error Has Occurred'),
-			'message' => h($url),
-			'error' => $error,
-		));
-		$this->_outputMessage('error500');
-	}
-
-/**
- * Generate the response using the controller object.
- *
- * @param string $template The template to render.
- */
-	protected function _outputMessage($template) {
-		$this->controller->render($template);
-		$this->controller->afterFilter();
-		$this->controller->response->send();
-	}
 }
diff --git a/cake/libs/exception_renderer.php b/cake/libs/exception_renderer.php
new file mode 100644
index 000000000..cb795d212
--- /dev/null
+++ b/cake/libs/exception_renderer.php
@@ -0,0 +1,233 @@
+ 1.
+ * When debug < 1 a CakeException will render 404 or  500 errors.  If an uncaught exception is thrown
+ * and it is a type that ExceptionHandler does not know about it will be treated as a 500 error.
+ *
+ * ### Implementing application specific exception handling
+ *
+ * You can implement application specific exception handling in one of a few ways:
+ *
+ * - Create a AppController::appError();
+ * - Create an AppError class.
+ *
+ * #### Using AppController::appError();
+ *
+ * This controller method is called instead of the default exception handling.  It receives the 
+ * thrown exception as its only argument.  You should implement your error handling in that method.
+ *
+ * #### Using an AppError class
+ *
+ * This approach gives more flexibility and power in how you handle exceptions.  You can create 
+ * `app/libs/app_error.php` and create a class called `AppError`.  The core ErrorHandler class
+ * will attempt to construct this class and let it handle the exception. This provides a more
+ * flexible way to handle exceptions in your application.
+ *
+ * @package       cake
+ * @subpackage    cake.cake.libs
+ */
+class ExceptionRenderer {
+
+/**
+ * Controller instance.
+ *
+ * @var Controller
+ * @access public
+ */
+	public $controller = null;
+
+/**
+ * template to render for CakeException
+ *
+ * @var string
+ */
+	public $template = '';
+
+/**
+ * The method corresponding to the Exception this object is for.
+ *
+ * @var string
+ */
+	public $method = '';
+
+/**
+ * The exception being handled.
+ *
+ * @var Exception
+ */
+	public $error = null;
+
+/**
+ * Creates the controller to perform rendering on the error response.
+ * If the error is a CakeException it will be converted to either a 400 or a 500
+ * code error depending on the code used to construct the error.
+ *
+ * @param string $method Method producing the error
+ * @param array $messages Error messages
+ */
+	function __construct(Exception $exception) {
+		App::import('Core', 'Sanitize');
+
+		$this->controller = $this->_getController($exception);
+
+		if (method_exists($this->controller, 'apperror')) {
+			return $this->controller->appError($exception);
+		}
+		$method = $template = Inflector::variable(str_replace('Exception', '', get_class($exception)));
+		$code = $exception->getCode();
+
+		$methodExists = method_exists($this, $method);
+
+		if ($exception instanceof CakeException && !$methodExists) {
+			$method = '_cakeError';
+			if ($template == 'internalError') {
+				$template = 'error500';
+			}
+		} elseif (!$methodExists) {
+			$method = 'error500';
+			if ($code >= 400) {
+				$method = 'error400';
+			}
+		}
+
+		if (Configure::read('debug') == 0) {
+			$parentClass = get_parent_class($this);
+			if ($parentClass != __CLASS__) {
+				$method = 'error400';
+			}
+			$parentMethods = (array)get_class_methods($parentClass);
+			if (in_array($method, $parentMethods)) {
+				$method = 'error400';
+			}
+			if ($code == 500) {
+				$method = 'error500';
+			}
+		}
+		$this->template = $template;
+		$this->method = $method;
+		$this->error = $exception;
+	}
+
+/**
+ * Get the controller instance to handle the exception.
+ * Override this method in subclasses to customize the controller used. 
+ * This method returns the built in `CakeErrorController` normally, or if an error is repeated
+ * a bare controller will be used.
+ *
+ * @param Exception $exception The exception to get a controller for.
+ * @return Controller
+ */
+	protected function _getController($exception) {
+		static $__previousError = null;
+		App::import('Controller', 'CakeError');
+
+		if ($__previousError != $exception) {
+			$__previousError = $exception;
+			$controller = new CakeErrorController();
+		} else {
+			$controller = new Controller();
+			$controller->viewPath = 'errors';
+		}
+		return $controller;
+	}
+
+/**
+ * Renders the response for the exception.
+ *
+ * @return void
+ */
+	public function render() {
+		call_user_func_array(array($this, $this->method), array($this->error));
+	}
+
+/**
+ * Generic handler for the internal framework errors CakePHP can generate.
+ *
+ * @param CakeExeption $error
+ * @return void
+ */
+	protected function _cakeError(CakeException $error) {
+		$url = Router::normalize($this->controller->request->here);
+		$code = $error->getCode();
+		$this->controller->response->statusCode($code);
+		$this->controller->set(array(
+			'code' => $code,
+			'url' => h($url),
+			'name' => $error->getMessage(),
+			'error' => $error,
+		));
+		$this->controller->set($error->getAttributes());
+		$this->_outputMessage($this->template);
+	}
+
+/**
+ * Convenience method to display a 400 series page.
+ *
+ * @param array $params Parameters for controller
+ */
+	public function error400($error) {
+		$message = $error->getMessage();
+		if (Configure::read('debug') == 0 && $error instanceof CakeException) {
+			$message = __('Not Found');
+		}
+		$url = Router::normalize($this->controller->request->here);
+		$this->controller->response->statusCode($error->getCode());
+		$this->controller->set(array(
+			'name' => $message,
+			'url' => h($url),
+			'error' => $error,
+		));
+		$this->_outputMessage('error400');
+	}
+
+/**
+ * Convenience method to display a 500 page.
+ *
+ * @param array $params Parameters for controller
+ */
+	public function error500($error) {
+		$url = Router::normalize($this->controller->request->here);
+		$code = ($error->getCode() > 500) ? $error->getCode() : 500;
+		$this->controller->response->statusCode($code);
+		$this->controller->set(array(
+			'name' => __('An Internal Error Has Occurred'),
+			'message' => h($url),
+			'error' => $error,
+		));
+		$this->_outputMessage('error500');
+	}
+
+/**
+ * Generate the response using the controller object.
+ *
+ * @param string $template The template to render.
+ */
+	protected function _outputMessage($template) {
+		$this->controller->render($template);
+		$this->controller->afterFilter();
+		$this->controller->response->send();
+	}
+}
\ No newline at end of file
diff --git a/cake/tests/cases/libs/error_handler.test.php b/cake/tests/cases/libs/error_handler.test.php
index e09e4fc85..490ce1a87 100644
--- a/cake/tests/cases/libs/error_handler.test.php
+++ b/cake/tests/cases/libs/error_handler.test.php
@@ -188,16 +188,6 @@ class ErrorHandlerTest extends CakeTestCase {
 		}
 	}
 
-/**
- * Mocks out the response on the errorhandler object so headers aren't modified.
- *
- * @return void
- */
-	protected function _mockResponse($error) {
-		$error->controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
-		return $error;
-	}
-
 /**
  * test error handling when debug is on, an error should be printed from Debugger.
  *
@@ -288,376 +278,4 @@ class ErrorHandlerTest extends CakeTestCase {
 		$this->assertPattern('/Kaboom!/', $result, 'message missing.');
 	}
 
-/**
- * test that methods declared in an ErrorHandler subclass are not converted
- * into error400 when debug > 0
- *
- * @return void
- */
-	function testSubclassMethodsNotBeingConvertedToError() {
-		Configure::write('debug', 2);
-		
-		$exception = new MissingWidgetThingException('Widget not found');
-		$ErrorHandler = $this->_mockResponse(new MyCustomErrorHandler($exception));
-
-		ob_start();
-		$ErrorHandler->render();
-		$result = ob_get_clean();
-
-		$this->assertEqual($result, 'widget thing is missing');
-	}
-
-/**
- * test that subclass methods are not converted when debug = 0
- *
- * @return void
- */
-	function testSubclassMethodsNotBeingConvertedDebug0() {
-		Configure::write('debug', 0);
-		$exception = new MissingWidgetThingException('Widget not found');
-		$ErrorHandler = $this->_mockResponse(new MyCustomErrorHandler($exception));
-
-		$this->assertEqual('missingWidgetThing', $ErrorHandler->method);
-
-		ob_start();
-		$ErrorHandler->render();
-		$result = ob_get_clean();
-
-		$this->assertEqual($result, 'widget thing is missing', 'Method declared in subclass converted to error400');
-	}
-
-/**
- * test that ErrorHandler subclasses properly convert framework errors.
- *
- * @return void
- */
-	function testSubclassConvertingFrameworkErrors() {
-		Configure::write('debug', 0);
-		
-		$exception = new MissingControllerException('PostsController');
-		$ErrorHandler = $this->_mockResponse(new MyCustomErrorHandler($exception));
-		
-		$this->assertEqual('error400', $ErrorHandler->method);
-
-		ob_start();
-		$ErrorHandler->render();
-		$result = ob_get_clean();
-
-		$this->assertPattern('/Not Found/', $result, 'Method declared in error handler not converted to error400. %s');
-	}
-
-/**
- * test things in the constructor.
- *
- * @return void
- */
-	function testConstruction() {
-		$exception = new NotFoundException('Page not found');
-		$ErrorHandler = new ErrorHandler($exception);
-
-		$this->assertType('CakeErrorController', $ErrorHandler->controller);
-		$this->assertEquals('error400', $ErrorHandler->method);
-		$this->assertEquals($exception, $ErrorHandler->error);
-	}
-
-/**
- * test that method gets coerced when debug = 0
- *
- * @return void
- */
-	function testErrorMethodCoercion() {
-		Configure::write('debug', 0);
-		$exception = new MissingActionException('Page not found');
-		$ErrorHandler = new ErrorHandler($exception);
-
-		$this->assertType('CakeErrorController', $ErrorHandler->controller);
-		$this->assertEquals('error400', $ErrorHandler->method);
-		$this->assertEquals($exception, $ErrorHandler->error);
-	}
-
-/**
- * test that unknown exception types with valid status codes are treated correctly.
- *
- * @return void
- */
-	function testUnknownExceptionTypeWithExceptionThatHasA400Code() {
-		$exception = new MissingWidgetThingException('coding fail.');
-		$ErrorHandler = new ErrorHandler($exception);
-		$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
-		$ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(404);
-
-		ob_start();
-		$ErrorHandler->render();
-		$results = ob_get_clean();
-
-		$this->assertFalse(method_exists($ErrorHandler, 'missingWidgetThing'), 'no method should exist.');
-		$this->assertEquals('error400', $ErrorHandler->method, 'incorrect method coercion.');
-	}
-
-/**
- * test that unknown exception types with valid status codes are treated correctly.
- *
- * @return void
- */
-	function testUnknownExceptionTypeWithNoCodeIsA500() {
-		$exception = new OutOfBoundsException('foul ball.');
-		$ErrorHandler = new ErrorHandler($exception);
-		$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
-		$ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(500);
-
-		ob_start();
-		$ErrorHandler->render();
-		$results = ob_get_clean();
-
-		$this->assertEquals('error500', $ErrorHandler->method, 'incorrect method coercion.');
-	}
-
-/**
- * testerror400 method
- *
- * @access public
- * @return void
- */
-	function testError400() {
-		Router::reload();
-
-		$request = new CakeRequest('posts/view/1000', false);
-		Router::setRequestInfo($request);
-
-		$exception = new NotFoundException('Custom message');
-		$ErrorHandler = new ErrorHandler($exception);
-		$ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
-		$ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(404);
-
-		ob_start();
-		$ErrorHandler->render();
-		$result = ob_get_clean();
-
-		$this->assertPattern('/

Custom message<\/h2>/', $result); - $this->assertPattern("/'\/posts\/view\/1000'<\/strong>/", $result); - } - -/** - * test that error400 only modifies the messages on CakeExceptions. - * - * @return void - */ - function testerror400OnlyChangingCakeException() { - Configure::write('debug', 0); - - $exception = new NotFoundException('Custom message'); - $ErrorHandler = $this->_mockResponse(new ErrorHandler($exception)); - - ob_start(); - $ErrorHandler->render(); - $result = ob_get_clean(); - $this->assertContains('Custom message', $result); - - $exception = new MissingActionException(array('controller' => 'PostsController', 'action' => 'index')); - $ErrorHandler = $this->_mockResponse(new ErrorHandler($exception)); - - ob_start(); - $ErrorHandler->render(); - $result = ob_get_clean(); - $this->assertContains('Not Found', $result); - } -/** - * test that error400 doesn't expose XSS - * - * @return void - */ - function testError400NoInjection() { - Router::reload(); - - $request = new CakeRequest('pages/pink', false); - Router::setRequestInfo($request); - - $exception = new NotFoundException('Custom message'); - $ErrorHandler = $this->_mockResponse(new ErrorHandler($exception)); - - ob_start(); - $ErrorHandler->render(); - $result = ob_get_clean(); - - $this->assertNoPattern('##', $result); - } - -/** - * testError500 method - * - * @access public - * @return void - */ - function testError500Message() { - $exception = new InternalErrorException('An Internal Error Has Occurred'); - $ErrorHandler = new ErrorHandler($exception); - $ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader')); - $ErrorHandler->controller->response->expects($this->once())->method('statusCode')->with(500); - - ob_start(); - $ErrorHandler->render(); - $result = ob_get_clean(); - - $this->assertPattern('/

An Internal Error Has Occurred<\/h2>/', $result); - } - -/** - * testMissingController method - * - * @access public - * @return void - */ - function testMissingController() { - $exception = new MissingControllerException(array('controller' => 'PostsController')); - $ErrorHandler = $this->_mockResponse(new ErrorHandler($exception)); - - ob_start(); - $ErrorHandler->render(); - $result = ob_get_clean(); - - $this->assertPattern('/

Missing Controller<\/h2>/', $result); - $this->assertPattern('/PostsController<\/em>/', $result); - } - -/** - * Returns an array of tests to run for the various CakeException classes. - * - * @return void - */ - public static function testProvider() { - return array( - array( - new MissingActionException(array('controller' => 'PostsController', 'action' => 'index')), - array( - '/

Missing Method in PostsController<\/h2>/', - '/PostsController::<\/em>index\(\)<\/em>/' - ), - 404 - ), - array( - new PrivateActionException(array('controller' => 'PostsController' , 'action' => '_secretSauce')), - array( - '/

Private Method in PostsController<\/h2>/', - '/PostsController::<\/em>_secretSauce\(\)<\/em>/' - ), - 404 - ), - array( - new MissingTableException(array('table' => 'articles', 'class' => 'Article')), - array( - '/

Missing Database Table<\/h2>/', - '/table articles<\/em> for model Article<\/em>/' - ), - 500 - ), - array( - new MissingDatabaseException(array('connection' => 'default')), - array( - '/

Missing Database Connection<\/h2>/', - '/Confirm you have created the file/' - ), - 500 - ), - array( - new MissingViewException(array('file' => '/posts/about.ctp')), - array( - "/posts\/about.ctp/" - ), - 500 - ), - array( - new MissingLayoutException(array('file' => 'layouts/my_layout.ctp')), - array( - "/Missing Layout/", - "/layouts\/my_layout.ctp/" - ), - 500 - ), - array( - new MissingConnectionException(array('class' => 'Article')), - array( - '/

Missing Database Connection<\/h2>/', - '/Article requires a database connection/' - ), - 500 - ), - array( - new MissingHelperFileException(array('file' => 'my_custom.php', 'class' => 'MyCustomHelper')), - array( - '/

Missing Helper File<\/h2>/', - '/Create the class below in file:/', - '/(\/|\\\)my_custom.php/' - ), - 500 - ), - array( - new MissingHelperClassException(array('file' => 'my_custom.php', 'class' => 'MyCustomHelper')), - array( - '/

Missing Helper Class<\/h2>/', - '/The helper class MyCustomHelper<\/em> can not be found or does not exist./', - '/(\/|\\\)my_custom.php/', - ), - 500 - ), - array( - new MissingBehaviorFileException(array('file' => 'my_custom.php', 'class' => 'MyCustomBehavior')), - array( - '/

Missing Behavior File<\/h2>/', - '/Create the class below in file:/', - '/(\/|\\\)my_custom.php/', - ), - 500 - ), - array( - new MissingBehaviorClassException(array('file' => 'my_custom.php', 'class' => 'MyCustomBehavior')), - array( - '/The behavior class MyCustomBehavior<\/em> can not be found or does not exist./', - '/(\/|\\\)my_custom.php/' - ), - 500 - ), - array( - new MissingComponentFileException(array('file' => 'sidebox.php', 'class' => 'SideboxComponent')), - array( - '/

Missing Component File<\/h2>/', - '/Create the class SideboxComponent<\/em> in file:/', - '/(\/|\\\)sidebox.php/' - ), - 500 - ), - array( - new MissingComponentClassException(array('file' => 'sidebox.php', 'class' => 'SideboxComponent')), - array( - '/

Missing Component Class<\/h2>/', - '/Create the class SideboxComponent<\/em> in file:/', - '/(\/|\\\)sidebox.php/' - ), - 500 - ) - - ); - } - -/** - * Test the various CakeException sub classes - * - * @dataProvider testProvider - * @return void - */ - function testCakeExceptionHandling($exception, $patterns, $code) { - $ErrorHandler = new ErrorHandler($exception); - $ErrorHandler->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader')); - $ErrorHandler->controller->response->expects($this->once()) - ->method('statusCode') - ->with($code); - - ob_start(); - $ErrorHandler->render(); - $result = ob_get_clean(); - - foreach ($patterns as $pattern) { - $this->assertPattern($pattern, $result); - } - } } diff --git a/cake/tests/cases/libs/exception_renderer.test.php b/cake/tests/cases/libs/exception_renderer.test.php new file mode 100644 index 000000000..c99c6b118 --- /dev/null +++ b/cake/tests/cases/libs/exception_renderer.test.php @@ -0,0 +1,573 @@ + + * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice + * + * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests + * @package cake + * @subpackage cake.tests.cases.libs + * @since CakePHP(tm) v 2.0 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ + +App::import('Core', array('ExceptionRenderer', 'Controller', 'Component')); + +/** + * Short description for class. + * + * @package cake + * @subpackage cake.tests.cases.libs + */ +class AuthBlueberryUser extends CakeTestModel { + +/** + * name property + * + * @var string 'AuthBlueberryUser' + * @access public + */ + public $name = 'AuthBlueberryUser'; + +/** + * useTable property + * + * @var string + * @access public + */ + public $useTable = false; +} + +/** + * BlueberryComponent class + * + * @package cake + * @subpackage cake.tests.cases.libs + */ +class BlueberryComponent extends Component { + +/** + * testName property + * + * @access public + * @return void + */ + public $testName = null; + +/** + * initialize method + * + * @access public + * @return void + */ + function initialize(&$controller) { + $this->testName = 'BlueberryComponent'; + } +} + +/** + * TestErrorController class + * + * @package cake + * @subpackage cake.tests.cases.libs + */ +class TestErrorController extends Controller { + +/** + * uses property + * + * @var array + * @access public + */ + public $uses = array(); + +/** + * components property + * + * @access public + * @return void + */ + public $components = array('Blueberry'); + +/** + * beforeRender method + * + * @access public + * @return void + */ + function beforeRender() { + echo $this->Blueberry->testName; + } + +/** + * index method + * + * @access public + * @return void + */ + function index() { + $this->autoRender = false; + return 'what up'; + } +} + +/** + * MyCustomExceptionRenderer class + * + * @package cake + * @subpackage cake.tests.cases.libs + */ +class MyCustomExceptionRenderer extends ExceptionRenderer { + +/** + * custom error message type. + * + * @return void + */ + function missingWidgetThing() { + echo 'widget thing is missing'; + } +} +/** + * Exception class for testing app error handlers and custom errors. + * + * @package cake.test.cases.libs + */ +class MissingWidgetThingException extends NotFoundException { } + + +/** + * ExceptionRendererTest class + * + * @package cake + * @subpackage cake.tests.cases.libs + */ +class ExceptionRendererTest extends CakeTestCase { + + var $_restoreError = false; +/** + * setup create a request object to get out of router later. + * + * @return void + */ + function setUp() { + App::build(array( + 'views' => array( + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS, + TEST_CAKE_CORE_INCLUDE_PATH . 'libs' . DS . 'view' . DS + ) + ), true); + Router::reload(); + + $request = new CakeRequest(null, false); + $request->base = ''; + Router::setRequestInfo($request); + $this->_debug = Configure::read('debug'); + $this->_error = Configure::read('Error'); + Configure::write('debug', 2); + } + +/** + * teardown + * + * @return void + */ + function teardown() { + Configure::write('debug', $this->_debug); + Configure::write('Error', $this->_error); + App::build(); + if ($this->_restoreError) { + restore_error_handler(); + } + } + +/** + * Mocks out the response on the ExceptionRenderer object so headers aren't modified. + * + * @return void + */ + protected function _mockResponse($error) { + $error->controller->response = $this->getMock('CakeResponse', array('_sendHeader')); + return $error; + } + +/** + * test that methods declared in an ExceptionRenderer subclass are not converted + * into error400 when debug > 0 + * + * @return void + */ + function testSubclassMethodsNotBeingConvertedToError() { + Configure::write('debug', 2); + + $exception = new MissingWidgetThingException('Widget not found'); + $ExceptionRenderer = $this->_mockResponse(new MyCustomExceptionRenderer($exception)); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertEqual($result, 'widget thing is missing'); + } + +/** + * test that subclass methods are not converted when debug = 0 + * + * @return void + */ + function testSubclassMethodsNotBeingConvertedDebug0() { + Configure::write('debug', 0); + $exception = new MissingWidgetThingException('Widget not found'); + $ExceptionRenderer = $this->_mockResponse(new MyCustomExceptionRenderer($exception)); + + $this->assertEqual('missingWidgetThing', $ExceptionRenderer->method); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertEqual($result, 'widget thing is missing', 'Method declared in subclass converted to error400'); + } + +/** + * test that ExceptionRenderer subclasses properly convert framework errors. + * + * @return void + */ + function testSubclassConvertingFrameworkErrors() { + Configure::write('debug', 0); + + $exception = new MissingControllerException('PostsController'); + $ExceptionRenderer = $this->_mockResponse(new MyCustomExceptionRenderer($exception)); + + $this->assertEqual('error400', $ExceptionRenderer->method); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertPattern('/Not Found/', $result, 'Method declared in error handler not converted to error400. %s'); + } + +/** + * test things in the constructor. + * + * @return void + */ + function testConstruction() { + $exception = new NotFoundException('Page not found'); + $ExceptionRenderer = new ExceptionRenderer($exception); + + $this->assertType('CakeErrorController', $ExceptionRenderer->controller); + $this->assertEquals('error400', $ExceptionRenderer->method); + $this->assertEquals($exception, $ExceptionRenderer->error); + } + +/** + * test that method gets coerced when debug = 0 + * + * @return void + */ + function testErrorMethodCoercion() { + Configure::write('debug', 0); + $exception = new MissingActionException('Page not found'); + $ExceptionRenderer = new ExceptionRenderer($exception); + + $this->assertType('CakeErrorController', $ExceptionRenderer->controller); + $this->assertEquals('error400', $ExceptionRenderer->method); + $this->assertEquals($exception, $ExceptionRenderer->error); + } + +/** + * test that unknown exception types with valid status codes are treated correctly. + * + * @return void + */ + function testUnknownExceptionTypeWithExceptionThatHasA400Code() { + $exception = new MissingWidgetThingException('coding fail.'); + $ExceptionRenderer = new ExceptionRenderer($exception); + $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader')); + $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(404); + + ob_start(); + $ExceptionRenderer->render(); + $results = ob_get_clean(); + + $this->assertFalse(method_exists($ExceptionRenderer, 'missingWidgetThing'), 'no method should exist.'); + $this->assertEquals('error400', $ExceptionRenderer->method, 'incorrect method coercion.'); + } + +/** + * test that unknown exception types with valid status codes are treated correctly. + * + * @return void + */ + function testUnknownExceptionTypeWithNoCodeIsA500() { + $exception = new OutOfBoundsException('foul ball.'); + $ExceptionRenderer = new ExceptionRenderer($exception); + $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader')); + $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(500); + + ob_start(); + $ExceptionRenderer->render(); + $results = ob_get_clean(); + + $this->assertEquals('error500', $ExceptionRenderer->method, 'incorrect method coercion.'); + } + +/** + * testerror400 method + * + * @access public + * @return void + */ + function testError400() { + Router::reload(); + + $request = new CakeRequest('posts/view/1000', false); + Router::setRequestInfo($request); + + $exception = new NotFoundException('Custom message'); + $ExceptionRenderer = new ExceptionRenderer($exception); + $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader')); + $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(404); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertPattern('/

Custom message<\/h2>/', $result); + $this->assertPattern("/'\/posts\/view\/1000'<\/strong>/", $result); + } + +/** + * test that error400 only modifies the messages on CakeExceptions. + * + * @return void + */ + function testerror400OnlyChangingCakeException() { + Configure::write('debug', 0); + + $exception = new NotFoundException('Custom message'); + $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception)); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + $this->assertContains('Custom message', $result); + + $exception = new MissingActionException(array('controller' => 'PostsController', 'action' => 'index')); + $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception)); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + $this->assertContains('Not Found', $result); + } +/** + * test that error400 doesn't expose XSS + * + * @return void + */ + function testError400NoInjection() { + Router::reload(); + + $request = new CakeRequest('pages/pink', false); + Router::setRequestInfo($request); + + $exception = new NotFoundException('Custom message'); + $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception)); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertNoPattern('##', $result); + } + +/** + * testError500 method + * + * @access public + * @return void + */ + function testError500Message() { + $exception = new InternalErrorException('An Internal Error Has Occurred'); + $ExceptionRenderer = new ExceptionRenderer($exception); + $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader')); + $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(500); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertPattern('/

An Internal Error Has Occurred<\/h2>/', $result); + } + +/** + * testMissingController method + * + * @access public + * @return void + */ + function testMissingController() { + $exception = new MissingControllerException(array('controller' => 'PostsController')); + $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception)); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + $this->assertPattern('/

Missing Controller<\/h2>/', $result); + $this->assertPattern('/PostsController<\/em>/', $result); + } + +/** + * Returns an array of tests to run for the various CakeException classes. + * + * @return void + */ + public static function testProvider() { + return array( + array( + new MissingActionException(array('controller' => 'PostsController', 'action' => 'index')), + array( + '/

Missing Method in PostsController<\/h2>/', + '/PostsController::<\/em>index\(\)<\/em>/' + ), + 404 + ), + array( + new PrivateActionException(array('controller' => 'PostsController' , 'action' => '_secretSauce')), + array( + '/

Private Method in PostsController<\/h2>/', + '/PostsController::<\/em>_secretSauce\(\)<\/em>/' + ), + 404 + ), + array( + new MissingTableException(array('table' => 'articles', 'class' => 'Article')), + array( + '/

Missing Database Table<\/h2>/', + '/table articles<\/em> for model Article<\/em>/' + ), + 500 + ), + array( + new MissingDatabaseException(array('connection' => 'default')), + array( + '/

Missing Database Connection<\/h2>/', + '/Confirm you have created the file/' + ), + 500 + ), + array( + new MissingViewException(array('file' => '/posts/about.ctp')), + array( + "/posts\/about.ctp/" + ), + 500 + ), + array( + new MissingLayoutException(array('file' => 'layouts/my_layout.ctp')), + array( + "/Missing Layout/", + "/layouts\/my_layout.ctp/" + ), + 500 + ), + array( + new MissingConnectionException(array('class' => 'Article')), + array( + '/

Missing Database Connection<\/h2>/', + '/Article requires a database connection/' + ), + 500 + ), + array( + new MissingHelperFileException(array('file' => 'my_custom.php', 'class' => 'MyCustomHelper')), + array( + '/

Missing Helper File<\/h2>/', + '/Create the class below in file:/', + '/(\/|\\\)my_custom.php/' + ), + 500 + ), + array( + new MissingHelperClassException(array('file' => 'my_custom.php', 'class' => 'MyCustomHelper')), + array( + '/

Missing Helper Class<\/h2>/', + '/The helper class MyCustomHelper<\/em> can not be found or does not exist./', + '/(\/|\\\)my_custom.php/', + ), + 500 + ), + array( + new MissingBehaviorFileException(array('file' => 'my_custom.php', 'class' => 'MyCustomBehavior')), + array( + '/

Missing Behavior File<\/h2>/', + '/Create the class below in file:/', + '/(\/|\\\)my_custom.php/', + ), + 500 + ), + array( + new MissingBehaviorClassException(array('file' => 'my_custom.php', 'class' => 'MyCustomBehavior')), + array( + '/The behavior class MyCustomBehavior<\/em> can not be found or does not exist./', + '/(\/|\\\)my_custom.php/' + ), + 500 + ), + array( + new MissingComponentFileException(array('file' => 'sidebox.php', 'class' => 'SideboxComponent')), + array( + '/

Missing Component File<\/h2>/', + '/Create the class SideboxComponent<\/em> in file:/', + '/(\/|\\\)sidebox.php/' + ), + 500 + ), + array( + new MissingComponentClassException(array('file' => 'sidebox.php', 'class' => 'SideboxComponent')), + array( + '/

Missing Component Class<\/h2>/', + '/Create the class SideboxComponent<\/em> in file:/', + '/(\/|\\\)sidebox.php/' + ), + 500 + ) + + ); + } + +/** + * Test the various CakeException sub classes + * + * @dataProvider testProvider + * @return void + */ + function testCakeExceptionHandling($exception, $patterns, $code) { + $ExceptionRenderer = new ExceptionRenderer($exception); + $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader')); + $ExceptionRenderer->controller->response->expects($this->once()) + ->method('statusCode') + ->with($code); + + ob_start(); + $ExceptionRenderer->render(); + $result = ob_get_clean(); + + foreach ($patterns as $pattern) { + $this->assertPattern($pattern, $result); + } + } +} From fac222e2cdfa9a70aca91993caeb57207605859e Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 22:24:29 -0500 Subject: [PATCH 128/160] Removing classes that were not used in the ErrorHandler test case. Adding a new test suite for error classes. --- cake/tests/cases/libs/all_error.test.php | 45 +++++++ cake/tests/cases/libs/error_handler.test.php | 125 +------------------ 2 files changed, 46 insertions(+), 124 deletions(-) create mode 100644 cake/tests/cases/libs/all_error.test.php diff --git a/cake/tests/cases/libs/all_error.test.php b/cake/tests/cases/libs/all_error.test.php new file mode 100644 index 000000000..cfd994393 --- /dev/null +++ b/cake/tests/cases/libs/all_error.test.php @@ -0,0 +1,45 @@ +addTestFile($libs . 'error_handler.test.php'); + $suite->addTestFile($libs . 'exception_renderer.test.php'); + return $suite; + } +} diff --git a/cake/tests/cases/libs/error_handler.test.php b/cake/tests/cases/libs/error_handler.test.php index 490ce1a87..b2f61da5f 100644 --- a/cake/tests/cases/libs/error_handler.test.php +++ b/cake/tests/cases/libs/error_handler.test.php @@ -18,130 +18,7 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', array('ErrorHandler', 'Controller', 'Component')); - -/** - * Short description for class. - * - * @package cake - * @subpackage cake.tests.cases.libs - */ -class AuthBlueberryUser extends CakeTestModel { - -/** - * name property - * - * @var string 'AuthBlueberryUser' - * @access public - */ - public $name = 'AuthBlueberryUser'; - -/** - * useTable property - * - * @var string - * @access public - */ - public $useTable = false; -} - -/** - * BlueberryComponent class - * - * @package cake - * @subpackage cake.tests.cases.libs - */ -class BlueberryComponent extends Component { - -/** - * testName property - * - * @access public - * @return void - */ - public $testName = null; - -/** - * initialize method - * - * @access public - * @return void - */ - function initialize(&$controller) { - $this->testName = 'BlueberryComponent'; - } -} - -/** - * TestErrorController class - * - * @package cake - * @subpackage cake.tests.cases.libs - */ -class TestErrorController extends Controller { - -/** - * uses property - * - * @var array - * @access public - */ - public $uses = array(); - -/** - * components property - * - * @access public - * @return void - */ - public $components = array('Blueberry'); - -/** - * beforeRender method - * - * @access public - * @return void - */ - function beforeRender() { - echo $this->Blueberry->testName; - } - -/** - * index method - * - * @access public - * @return void - */ - function index() { - $this->autoRender = false; - return 'what up'; - } -} - -/** - * MyCustomErrorHandler class - * - * @package cake - * @subpackage cake.tests.cases.libs - */ -class MyCustomErrorHandler extends ErrorHandler { - -/** - * custom error message type. - * - * @return void - */ - function missingWidgetThing() { - echo 'widget thing is missing'; - } -} -/** - * Exception class for testing app error handlers and custom errors. - * - * @package cake.test.cases.libs - */ -class MissingWidgetThingException extends NotFoundException { } - +App::import('Core', 'ErrorHandler'); /** * ErrorHandlerTest class From 3bc708ba192d7e10c42e06bce07c1a35aa943a2a Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 22:26:04 -0500 Subject: [PATCH 129/160] Adding the new group to AllTests. Removing ErrorHandler test from AllLibs. --- cake/tests/cases/libs/all_libs.test.php | 1 - cake/tests/cases/libs/all_tests.test.php | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/tests/cases/libs/all_libs.test.php b/cake/tests/cases/libs/all_libs.test.php index 3d334d72b..0bab4f0e9 100644 --- a/cake/tests/cases/libs/all_libs.test.php +++ b/cake/tests/cases/libs/all_libs.test.php @@ -39,7 +39,6 @@ class AllLibsTest extends PHPUnit_Framework_TestSuite { $suite->addTestFile(CORE_TEST_CASES . DS . 'basics.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'cake_session.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'debugger.test.php'); - $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'error_handler.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'file.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'folder.test.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'libs' . DS . 'inflector.test.php'); diff --git a/cake/tests/cases/libs/all_tests.test.php b/cake/tests/cases/libs/all_tests.test.php index c3a580103..b3c94cb82 100644 --- a/cake/tests/cases/libs/all_tests.test.php +++ b/cake/tests/cases/libs/all_tests.test.php @@ -48,6 +48,7 @@ class AllTests extends PHPUnit_Framework_TestSuite { $suite->addTestFile($path . 'all_configure.test.php'); $suite->addTestFile($path . 'all_controllers.test.php'); $suite->addTestFile($path . 'all_database.test.php'); + $suite->addTestFile($path . 'all_error.test.php'); $suite->addTestFile($path . 'all_helpers.test.php'); $suite->addTestFile($path . 'all_libs.test.php'); $suite->addTestFile($path . 'all_localization.test.php'); From 74bf455c4963e58898df1e63993852db33b6e7da Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 22:47:35 -0500 Subject: [PATCH 130/160] Updating ConsoleErrorHandler to match ErrorHandler. Updating test cases for ConsoleErrorHandler. --- cake/console/libs/console_error_handler.php | 70 +++++++------------ .../libs/console_error_handler.test.php | 66 +++++++++-------- 2 files changed, 62 insertions(+), 74 deletions(-) diff --git a/cake/console/libs/console_error_handler.php b/cake/console/libs/console_error_handler.php index 5dda75a3c..fc8414767 100644 --- a/cake/console/libs/console_error_handler.php +++ b/cake/console/libs/console_error_handler.php @@ -35,17 +35,19 @@ class ConsoleErrorHandler extends ErrorHandler { * @var filehandle * @access public */ - public $stderr; + public static $stderr; /** - * Class constructor. + * Get the stderr object for the console error handling. * * @param Exception $error Exception to handle. * @param array $messages Error messages */ - function __construct($error) { - $this->stderr = new ConsoleOutput('php://stderr'); - parent::__construct($error); + public static function getStderr() { + if (empty(self::$stderr)) { + self::$stderr = new ConsoleOutput('php://stderr'); + } + return self::$stderr; } /** @@ -54,57 +56,37 @@ class ConsoleErrorHandler extends ErrorHandler { * @return void */ public static function handleException($exception) { - $error = new ConsoleErrorHandler($exception); - $error->render(); + $stderr = self::getStderr(); + $stderr->write(sprintf( + __("Error: %s\n%s"), + $exception->getMessage(), + $exception->getTraceAsString() + )); } /** - * Do nothing, no controllers are needed in the console. + * Handle errors in the console environment. * * @return void */ - protected function _getController($exception) { - return null; + public static function handleError($code, $description, $file = null, $line = null, $context = null) { + $errorConfig = Configure::read('Error'); + if (isset($errorConfig['level']) && ($code & ~$errorConfig['level'])) { + return; + } + $stderr = self::getStderr(); + list($name, $log) = self::_mapErrorCode($code); + $stderr->write(sprintf( + __("%s Error: %s in [%s, line %s]\n"), $name, $description, $file, $line + )); } /** - * Overwrite how _cakeError behaves for console. There is no reason - * to prepare urls as they are not relevant for this. + * undocumented function * - * @param $error Exception Exception being handled. * @return void */ - protected function _cakeError($error) { - $this->_outputMessage(); - } - -/** - * Override error404 method - * - * @param Exception $error Exception - * @return void - */ - public function error400($error) { - $this->_outputMessage(); - } - -/** - * Override error500 method - * - * @param Exception $error Exception - * @return void - */ - public function error500($error) { - $this->_outputMessage(); - } - -/** - * Outputs the exception to STDERR. - * - * @param string $template The name of the template to render. - * @return void - */ - public function _outputMessage($template = null) { + public function render() { $this->stderr->write(sprintf( __("Error: %s\n%s"), $this->error->getMessage(), diff --git a/cake/tests/cases/console/libs/console_error_handler.test.php b/cake/tests/cases/console/libs/console_error_handler.test.php index 81c3b5aae..0b0719a14 100644 --- a/cake/tests/cases/console/libs/console_error_handler.test.php +++ b/cake/tests/cases/console/libs/console_error_handler.test.php @@ -27,14 +27,36 @@ require_once CONSOLE_LIBS . 'console_error_handler.php'; class ConsoleErrorHandlerTest extends CakeTestCase { /** - * Factory method for error handlers with stderr() mocked out. + * setup, create mocks * * @return Mock object */ - function getErrorHandler($exception) { - $error = new ConsoleErrorHandler($exception); - $error->stderr = $this->getMock('ConsoleOutput', array(), array(), '', false); - return $error; + function setUp() { + parent::setUp(); + ConsoleErrorHandler::$stderr = $this->getMock('ConsoleOutput', array(), array(), '', false); + } + +/** + * teardown + * + * @return void + */ + function tearDown() { + parent::tearDown(); + ConsoleErrorHandler::$stderr = null; + } + +/** + * test that the console error handler can deal with CakeExceptions. + * + * @return void + */ + function testHandleError() { + $content = 'Notice Error: This is a notice error in [/some/file, line 275]'; + ConsoleErrorHandler::$stderr->expects($this->once())->method('write') + ->with($content); + + ConsoleErrorHandler::handleError(E_NOTICE, 'This is a notice error', '/some/file', 275); } /** @@ -44,12 +66,10 @@ class ConsoleErrorHandlerTest extends CakeTestCase { */ function testCakeErrors() { $exception = new MissingActionException('Missing action'); - $error = $this->getErrorHandler($exception); - - $error->stderr->expects($this->once())->method('write') + ConsoleErrorHandler::$stderr->expects($this->once())->method('write') ->with($this->stringContains('Missing action')); - $error->render(); + ConsoleErrorHandler::handleException($exception); } /** @@ -59,12 +79,11 @@ class ConsoleErrorHandlerTest extends CakeTestCase { */ function testNonCakeExceptions() { $exception = new InvalidArgumentException('Too many parameters.'); - $error = $this->getErrorHandler($exception); - $error->stderr->expects($this->once())->method('write') + ConsoleErrorHandler::$stderr->expects($this->once())->method('write') ->with($this->stringContains('Too many parameters.')); - $error->render(); + ConsoleErrorHandler::handleException($exception); } /** @@ -74,12 +93,11 @@ class ConsoleErrorHandlerTest extends CakeTestCase { */ function testError404Exception() { $exception = new NotFoundException('dont use me in cli.'); - $error = $this->getErrorHandler($exception); - - $error->stderr->expects($this->once())->method('write') + + ConsoleErrorHandler::$stderr->expects($this->once())->method('write') ->with($this->stringContains('dont use me in cli.')); - $error->render(); + ConsoleErrorHandler::handleException($exception); } /** @@ -89,23 +107,11 @@ class ConsoleErrorHandlerTest extends CakeTestCase { */ function testError500Exception() { $exception = new InternalErrorException('dont use me in cli.'); - $error = $this->getErrorHandler($exception); - $error->stderr->expects($this->once())->method('write') + ConsoleErrorHandler::$stderr->expects($this->once())->method('write') ->with($this->stringContains('dont use me in cli.')); - $error->render(); + ConsoleErrorHandler::handleException($exception); } -/** - * test that ConsoleErrorHandler has a stderr file handle. - * - * @return void - */ - function testStdErrFilehandle() { - $exception = new InternalErrorException('dont use me in cli.'); - $error = new ConsoleErrorHandler($exception); - - $this->assertType('ConsoleOutput', $error->stderr, 'No handle.'); - } } \ No newline at end of file From 14a6368b39e24e9487876260b9c11019b662b398 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 22:48:13 -0500 Subject: [PATCH 131/160] Adding missed isset() check Making ConsoleErrorHandler handle both errors, and exceptions in CLI. --- cake/console/shell_dispatcher.php | 6 ++++-- cake/libs/error_handler.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cake/console/shell_dispatcher.php b/cake/console/shell_dispatcher.php index 5b1b6a8fe..192801433 100644 --- a/cake/console/shell_dispatcher.php +++ b/cake/console/shell_dispatcher.php @@ -141,13 +141,15 @@ class ShellDispatcher { $boot = file_exists(ROOT . DS . APP_DIR . DS . 'config' . DS . 'bootstrap.php'); require CORE_PATH . 'cake' . DS . 'bootstrap.php'; - require_once CONSOLE_LIBS . 'console_error_handler.php'; - set_exception_handler(array('ConsoleErrorHandler', 'handleException')); if (!file_exists(APP_PATH . 'config' . DS . 'core.php')) { include_once CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'console' . DS . 'templates' . DS . 'skel' . DS . 'config' . DS . 'core.php'; App::build(); } + require_once CONSOLE_LIBS . 'console_error_handler.php'; + set_exception_handler(array('ConsoleErrorHandler', 'handleException')); + set_error_handler(array('ConsoleErrorHandler', 'handleError')); + if (!defined('FULL_BASE_URL')) { define('FULL_BASE_URL', '/'); } diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 33146a289..c22f3ddc6 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -93,7 +93,7 @@ class ErrorHandler { */ public static function handleError($code, $description, $file = null, $line = null, $context = null) { $errorConfig = Configure::read('Error'); - if ($errorConfig['level'] && ($code & ~$errorConfig['level'])) { + if (isset($errorConfig['level']) && ($code & ~$errorConfig['level'])) { return; } list($error, $log) = self::_mapErrorCode($code); From af4447d55d98dfb93acdd6fe8488758e6f9749ca Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 23:24:12 -0500 Subject: [PATCH 132/160] Removing Configure::write('log'). This feature is now part of Error configuration. Removing log check from Debugger::showError(). This method only show's errors, it shouldn't be logging them as well. --- app/config/core.php | 31 ++++++++++--------------------- cake/libs/debugger.php | 6 ------ 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/app/config/core.php b/app/config/core.php index 1674efd33..c119ea74e 100644 --- a/app/config/core.php +++ b/app/config/core.php @@ -35,21 +35,6 @@ */ Configure::write('debug', 2); -/** - * CakePHP Log Level: - * - * In case of Production Mode CakePHP gives you the possibility to continue logging errors. - * - * The following parameters can be used: - * Boolean: Set true/false to activate/deactivate logging - * Configure::write('log', true); - * - * Integer: Use built-in PHP constants to set the error level (see error_reporting) - * Configure::write('log', E_ERROR | E_WARNING); - * Configure::write('log', E_ALL ^ E_NOTICE); - */ - Configure::write('log', true); - /** * Configure the Error handler used to handle errors for your application. By default * ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0 @@ -57,18 +42,22 @@ * * Options: * - * - `handler` The callback to handle errors. You can set this to any callback type, including anonymous functions. - * - `level` The level of errors you are interested in capturing. + * - `handler` - callback - The callback to handle errors. You can set this to any callback type, + * including anonymous functions. + * - `level` - int - The level of errors you are interested in capturing. + * - `trace` - boolean - Include stack traces for errors in log files. */ Configure::write('Error', array( 'handler' => 'ErrorHandler::handleError', - 'level' => E_ALL & ~E_DEPRECATED + 'level' => E_ALL & ~E_DEPRECATED, + 'trace' => true )); /** - * Configure the default Exception handler. This method will be invoked each time there is an uncaught exception - * by default, ErrorHandler::handleException() is used. It will display a HTML page for the exception, and - * while debug > 0, framework errors like Missing Controller will be displayed. + * Configure the Exception handler used for uncaught exceptions. By default, + * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and + * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0, + * framework errors will be coerced into generic HTTP errors. */ Configure::write('Exception', array( 'handler' => 'ErrorHandler::handleException' diff --git a/cake/libs/debugger.php b/cake/libs/debugger.php index b18b1faed..f07ab78c6 100644 --- a/cake/libs/debugger.php +++ b/cake/libs/debugger.php @@ -293,12 +293,6 @@ class Debugger { ); echo $_this->outputError($data); - if (Configure::read('log')) { - $tpl = $_this->_templates['log']['error']; - $options = array('before' => '{:', 'after' => '}'); - CakeLog::write($level, String::insert($tpl, $data, $options)); - } - if ($error == 'Fatal Error') { exit(); } From f2f3f13c751adb31176407cec29c22d92fdf5122 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 23:33:46 -0500 Subject: [PATCH 133/160] Adding exception logging configuration setting. Allows uncaught exceptions to be logged. Implementing logging, and adding a test case. --- app/config/core.php | 9 +++++- cake/libs/error_handler.php | 6 ++++ cake/tests/cases/libs/error_handler.test.php | 30 +++++++++++++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/app/config/core.php b/app/config/core.php index c119ea74e..3cf9845c2 100644 --- a/app/config/core.php +++ b/app/config/core.php @@ -58,9 +58,16 @@ * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0, * framework errors will be coerced into generic HTTP errors. + * + * Options: + * + * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type, + * including anonymous functions. + * - `log` - boolean - Should Exceptions be logged? */ Configure::write('Exception', array( - 'handler' => 'ErrorHandler::handleException' + 'handler' => 'ErrorHandler::handleException', + 'log' => true )); /** diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index c22f3ddc6..686622761 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -72,6 +72,12 @@ class ErrorHandler { $AppError = new AppError($exception); return $AppError->render(); } + if (Configure::read('Exception.log')) { + if (!class_exists('CakeLog')) { + require LIBS . 'cake_log.php'; + } + CakeLog::write(LOG_ERR, '[' . get_class($exception) . '] ' . $exception->getMessage()); + } $error = new ExceptionRenderer($exception); $error->render(); } diff --git a/cake/tests/cases/libs/error_handler.test.php b/cake/tests/cases/libs/error_handler.test.php index b2f61da5f..446b9ec2c 100644 --- a/cake/tests/cases/libs/error_handler.test.php +++ b/cake/tests/cases/libs/error_handler.test.php @@ -18,7 +18,7 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', 'ErrorHandler'); +App::import('Core', array('ErrorHandler', 'Controller', 'Router')); /** * ErrorHandlerTest class @@ -145,9 +145,7 @@ class ErrorHandlerTest extends CakeTestCase { if ($this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.')) { return; } - if ($this->skipIf(PHP_SAPI == 'cli', 'This integration test can not be run in cli.')) { - return; - } + $error = new NotFoundException('Kaboom!'); ob_start(); ErrorHandler::handleException($error); @@ -155,4 +153,28 @@ class ErrorHandlerTest extends CakeTestCase { $this->assertPattern('/Kaboom!/', $result, 'message missing.'); } +/** + * test handleException generating a page. + * + * @return void + */ + function testHandleExceptionLog() { + if ($this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.')) { + return; + } + if (file_exists(LOGS . 'error.log')) { + unlink(LOGS . 'error.log'); + } + Configure::write('Exception.log', true); + $error = new NotFoundException('Kaboom!'); + + ob_start(); + ErrorHandler::handleException($error); + $result = ob_get_clean(); + $this->assertPattern('/Kaboom!/', $result, 'message missing.'); + + $log = file(LOGS . 'error.log'); + $this->assertPattern('/\[NotFoundException\] Kaboom!/', $log[0], 'message missing.'); + } + } From 55623ace928970786112d9a6475465b085676989 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 14 Nov 2010 23:37:09 -0500 Subject: [PATCH 134/160] Adding deprecated error level to the map switch. --- cake/libs/error_handler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 686622761..6a677162c 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -169,6 +169,10 @@ class ErrorHandler { $error = 'Strict'; $log = LOG_NOTICE; break; + case E_DEPRECATED: + $error = 'Deprecated'; + $log = LOG_NOTICE; + break; default: return array(); break; From e88cdc8a01ee2747a258411e4ec926f6289eea28 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 00:59:14 -0500 Subject: [PATCH 135/160] Adding more documentation. --- cake/libs/error_handler.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 6a677162c..e79a4cb1b 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -49,6 +49,18 @@ * Finally, in your `app/config/bootstrap.php` you can configure use `set_exception_handler()` * to take total control over application exception handling. * + * #### Logging exceptions + * + * You can log all the exceptions that are dealt with by ErrorHandler by setting `Exception.log` to true + * in your core.php. Enabling this will log every exception to CakeLog and the configured loggers. + * + * ### PHP errors + * + * Error handler also provides the built in features for handling php errors (trigger_error). + * While in debug mode, errors will be output to the screen using debugger. While in production mode, + * errors will be logged to CakeLog. You can control which errors are logged by setting + * `Error.level` in your core.php. + * * @package cake * @subpackage cake.cake.libs */ From 845edf38e1bf2a09cca314eefa3b8da571211a56 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 22:11:59 -0500 Subject: [PATCH 136/160] Removing core classes using App::import() with an array(). This usage incurs an additional call to App::import(). Removing Set from core class imports, as Set is required as part of the framework bootstrapping. --- cake/libs/cake_session.php | 2 +- cake/libs/controller/components/auth.php | 3 ++- cake/libs/controller/components/email.php | 2 +- cake/libs/controller/components/security.php | 3 ++- cake/libs/dispatcher.php | 4 +++- cake/libs/http_socket.php | 3 ++- cake/libs/i18n.php | 3 ++- cake/libs/model/cake_schema.php | 3 ++- cake/libs/model/datasources/dbo_source.php | 2 +- cake/libs/model/model.php | 4 +++- 10 files changed, 19 insertions(+), 10 deletions(-) diff --git a/cake/libs/cake_session.php b/cake/libs/cake_session.php index 28a69c4d7..aa4b0a95c 100644 --- a/cake/libs/cake_session.php +++ b/cake/libs/cake_session.php @@ -141,7 +141,7 @@ class CakeSession { * @param boolean $start Should session be started right now */ public static function init($base = null, $start = true) { - App::import('Core', array('Set', 'Security')); + App::import('Core', 'Security'); self::$time = time(); $checkAgent = Configure::read('Session.checkAgent'); diff --git a/cake/libs/controller/components/auth.php b/cake/libs/controller/components/auth.php index e91351874..a41d88e54 100644 --- a/cake/libs/controller/components/auth.php +++ b/cake/libs/controller/components/auth.php @@ -20,7 +20,8 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', array('Router', 'Security'), false); +App::import('Core', 'Router', false); +App::import('Core', 'Security', false); /** * Authentication control component class diff --git a/cake/libs/controller/components/email.php b/cake/libs/controller/components/email.php index 75022b071..a4cb6dd02 100755 --- a/cake/libs/controller/components/email.php +++ b/cake/libs/controller/components/email.php @@ -810,7 +810,7 @@ class EmailComponent extends Component { * @access private */ function _smtp() { - App::import('Core', array('CakeSocket')); + App::import('Core', 'CakeSocket'); $defaults = array( 'host' => 'localhost', diff --git a/cake/libs/controller/components/security.php b/cake/libs/controller/components/security.php index da7f86e67..49632a1c6 100644 --- a/cake/libs/controller/components/security.php +++ b/cake/libs/controller/components/security.php @@ -17,7 +17,8 @@ * @since CakePHP(tm) v 0.10.8.2156 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', array('String', 'Security')); +App::import('Core', 'String', false); +App::import('Core', 'Security', false); /** * SecurityComponent diff --git a/cake/libs/dispatcher.php b/cake/libs/dispatcher.php index 5bfa749cb..cb14d18ba 100644 --- a/cake/libs/dispatcher.php +++ b/cake/libs/dispatcher.php @@ -24,7 +24,9 @@ /** * List of helpers to include */ -App::import('Core', array('Router', 'CakeRequest', 'CakeResponse'), false); +App::import('Core', 'Router', false); +App::import('Core', 'CakeRequest', false); +App::import('Core', 'CakeResponse', false); App::import('Controller', 'Controller', false); /** diff --git a/cake/libs/http_socket.php b/cake/libs/http_socket.php index 91b18d4d2..aaf3b504c 100644 --- a/cake/libs/http_socket.php +++ b/cake/libs/http_socket.php @@ -17,7 +17,8 @@ * @since CakePHP(tm) v 1.2.0 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', array('CakeSocket', 'Set', 'Router')); +App::import('Core', 'CakeSocket'); +App::import('Core', 'Router'); /** * Cake network socket connection class. diff --git a/cake/libs/i18n.php b/cake/libs/i18n.php index d12cbb3dc..05ec9c9e8 100644 --- a/cake/libs/i18n.php +++ b/cake/libs/i18n.php @@ -21,7 +21,8 @@ /** * Included libraries. */ -App::import('Core', array('l10n', 'Multibyte')); +App::import('Core', 'L10n'); +App::import('Core', 'Multibyte'); /** * I18n handles translation of Text and time format strings. diff --git a/cake/libs/model/cake_schema.php b/cake/libs/model/cake_schema.php index 12e6f09c0..dbf5d3c3f 100644 --- a/cake/libs/model/cake_schema.php +++ b/cake/libs/model/cake_schema.php @@ -17,7 +17,8 @@ * @since CakePHP(tm) v 1.2.0.5550 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', array('Model', 'ConnectionManager')); +App::import('Core', 'Model'); +App::import('Core', 'ConnectionManager'); /** * Base Class for Schema management diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index cb5e8d4be..2e4387852 100755 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -17,7 +17,7 @@ * @since CakePHP(tm) v 0.10.0.1076 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import('Core', array('Set', 'String')); +App::import('Core', 'String'); /** * DboSource diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index 962461f05..b34d175e0 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -23,7 +23,9 @@ /** * Included libs */ -App::import('Core', array('ClassRegistry', 'Validation', 'Set', 'String')); +App::import('Core', 'ClassRegistry', false); +App::import('Core', 'Validation', false); +App::import('Core', 'String', false); App::import('Model', 'BehaviorCollection', false); App::import('Model', 'ModelBehavior', false); App::import('Model', 'ConnectionManager', false); From 04d3feb6c06bba019fd5d62d237955e98ffc74e0 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 21 Nov 2010 23:02:02 -0500 Subject: [PATCH 137/160] Unknown errors cannot be mapped as they generate another error. Having a default case doesn't make much sense here. Adding additional coverage to ErrorHandler. --- cake/libs/error_handler.php | 3 -- cake/tests/cases/libs/error_handler.test.php | 30 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index e79a4cb1b..57b16f575 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -185,9 +185,6 @@ class ErrorHandler { $error = 'Deprecated'; $log = LOG_NOTICE; break; - default: - return array(); - break; } return array($error, $log); } diff --git a/cake/tests/cases/libs/error_handler.test.php b/cake/tests/cases/libs/error_handler.test.php index 446b9ec2c..c95d7566a 100644 --- a/cake/tests/cases/libs/error_handler.test.php +++ b/cake/tests/cases/libs/error_handler.test.php @@ -83,6 +83,36 @@ class ErrorHandlerTest extends CakeTestCase { $this->assertPattern('/variable:\s+wrong/', $result); } +/** + * provides errors for mapping tests. + * + * @return void + */ + public static function errorProvider() { + return array( + array(E_USER_NOTICE, 'Notice'), + array(E_USER_WARNING, 'Warning'), + array(E_USER_ERROR, 'Fatal Error'), + ); + } + +/** + * test error mappings + * + * @dataProvider errorProvider + * @return void + */ + function testErrorMapping($error, $expected) { + set_error_handler('ErrorHandler::handleError'); + $this->_restoreError = true; + + ob_start(); + trigger_error('Test error', $error); + + $result = ob_get_clean(); + $this->assertPattern('/' . $expected . '<\/b>/', $result); + } + /** * Test that errors go into CakeLog when debug = 0. * From 1cffea379f5cf5a7b222d919f300cb63fc71b400 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 22 Nov 2010 21:06:43 -0500 Subject: [PATCH 138/160] More documentation. --- cake/libs/error_handler.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 57b16f575..087e1063a 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -21,7 +21,9 @@ */ /** - * Error Handler. + * Error Handler provides basic error and exception handling for your application. + * + * ### Uncaught exception handling * * Captures and handles all unhandled exceptions. Displays helpful framework errors when debug > 1. * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown @@ -31,6 +33,7 @@ * * You can implement application specific exception handling in one of a few ways: * + * - Set Configure::write('Exception.handler', 'YourClass::yourMethod'); * - Create a AppController::appError(); * - Create an AppError class. * @@ -63,6 +66,7 @@ * * @package cake * @subpackage cake.cake.libs + * @see ExceptionRenderer for more information on how to customize exception rendering. */ class ErrorHandler { From f3feb1575c0f42f08b93c44c16661c46cb44c5fb Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 22 Nov 2010 23:02:01 -0500 Subject: [PATCH 139/160] Removing support for AppError. It doesn't make sense to have hardcoded class references when there is better configuration available. Updating doc blocks for exceptions. Updating core.php file. --- app/config/core.php | 3 ++ cake/libs/error_handler.php | 57 +++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/app/config/core.php b/app/config/core.php index 3cf9845c2..cb6eff8c6 100644 --- a/app/config/core.php +++ b/app/config/core.php @@ -63,10 +63,13 @@ * * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type, * including anonymous functions. + * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you + * should place the file for that class in app/libs. This class needs to implement a render method. * - `log` - boolean - Should Exceptions be logged? */ Configure::write('Exception', array( 'handler' => 'ErrorHandler::handleException', + 'renderer' => 'ExceptionRenderer', 'log' => true )); diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 087e1063a..787c905f9 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -21,41 +21,45 @@ */ /** - * Error Handler provides basic error and exception handling for your application. - * - * ### Uncaught exception handling - * - * Captures and handles all unhandled exceptions. Displays helpful framework errors when debug > 1. + * Error Handler provides basic error and exception handling for your application. It Captures and + * handles all unhandled exceptions. Displays helpful framework errors when debug > 1. * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown * and it is a type that ErrorHandler does not know about it will be treated as a 500 error. * * ### Implementing application specific exception handling * - * You can implement application specific exception handling in one of a few ways: + * You can implement application specific exception handling in one of a few ways. Each approach + * gives you different amounts of control over the exception handling process. * * - Set Configure::write('Exception.handler', 'YourClass::yourMethod'); - * - Create a AppController::appError(); - * - Create an AppError class. + * - Create AppController::appError(); + * - Set Configure::write('Exception.renderer', 'YourClass'); * - * #### Using AppController::appError(); + * #### Create your own Exception handler with `Exception.handler` * - * This controller method is called instead of the default exception handling. It receives the + * This gives you full control over the exception handling process. The class you choose should be + * loaded in your app/config/bootstrap.php, so its available to handle any exceptions. You can + * define the handler as any callback type. You can't combine this with other Exception settings. + * + * #### Using `AppController::appError();` + * + * This controller method is called instead of the default exception rendering. It receives the * thrown exception as its only argument. You should implement your error handling in that method. * - * #### Using an AppError class + * #### Using a custom renderer with `Exception.renderer` * - * This approach gives more flexibility and power in how you handle exceptions. You can create - * `app/libs/app_error.php` and create a class called `AppError`. The core ErrorHandler class - * will attempt to construct this class and let it handle the exception. This provides a more - * flexible way to handle exceptions in your application. + * If you don't want to take control of the exception handling, but want to change how exceptions are + * rendered you can use `Exception.renderer` to choose a class to render exception pages. By default + * `ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/libs. * - * Finally, in your `app/config/bootstrap.php` you can configure use `set_exception_handler()` - * to take total control over application exception handling. + * Your custom renderer should expect an exception in its constructor, and implement a render method. + * Failing to do so will cause additional errors. * * #### Logging exceptions * - * You can log all the exceptions that are dealt with by ErrorHandler by setting `Exception.log` to true - * in your core.php. Enabling this will log every exception to CakeLog and the configured loggers. + * Using the built-in exception handling, you can log all the exceptions + * that are dealt with by ErrorHandler by setting `Exception.log` to true in your core.php. + * Enabling this will log every exception to CakeLog and the configured loggers. * * ### PHP errors * @@ -81,20 +85,17 @@ class ErrorHandler { */ public static function handleException(Exception $exception) { App::import('Core', 'ExceptionRenderer'); - if (file_exists(APP . 'app_error.php') || class_exists('AppError')) { - if (!class_exists('AppError')) { - require(APP . 'app_error.php'); - } - $AppError = new AppError($exception); - return $AppError->render(); - } - if (Configure::read('Exception.log')) { + $config = Configure::read('Exception'); + if (!empty($config['log'])) { if (!class_exists('CakeLog')) { require LIBS . 'cake_log.php'; } CakeLog::write(LOG_ERR, '[' . get_class($exception) . '] ' . $exception->getMessage()); } - $error = new ExceptionRenderer($exception); + if ($config['renderer'] !== 'ExceptionRenderer') { + App::import('Lib', $config['renderer']); + } + $error = new $config['renderer']($exception); $error->render(); } From 9b4f7a1a1599418bfd264fc4fed8be37a826649f Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 25 Nov 2010 07:23:37 -0500 Subject: [PATCH 140/160] More documentation. --- cake/libs/error_handler.php | 22 ++++++++++++++++++++-- cake/libs/exception_renderer.php | 13 ++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 787c905f9..48f06c1fd 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -21,8 +21,12 @@ */ /** - * Error Handler provides basic error and exception handling for your application. It Captures and - * handles all unhandled exceptions. Displays helpful framework errors when debug > 1. + * + * Error Handler provides basic error and exception handling for your application. It captures and + * handles all unhandled exceptions and errors. Displays helpful framework errors when debug > 1. + * + * ### Uncaught exceptions + * * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown * and it is a type that ErrorHandler does not know about it will be treated as a 500 error. * @@ -68,6 +72,20 @@ * errors will be logged to CakeLog. You can control which errors are logged by setting * `Error.level` in your core.php. * + * #### Logging errors + * + * When ErrorHandler is used for handling errors, you can enable error logging by setting `Error.log` to true. + * This will log all errors to the configured log handlers. + * + * #### Controlling what errors are logged/displayed + * + * You can control which errors are logged / displayed by ErrorHandler by setting `Error.level`. Setting this + * to one or a combination of a few of the E_* constants will only enable the specified errors. + * + * e.g. `Configure::write('Error.level', E_ALL & ~E_NOTICE);` + * + * Would enable handling for all non Notice errors. + * * @package cake * @subpackage cake.cake.libs * @see ExceptionRenderer for more information on how to customize exception rendering. diff --git a/cake/libs/exception_renderer.php b/cake/libs/exception_renderer.php index cb795d212..a83e25cb4 100644 --- a/cake/libs/exception_renderer.php +++ b/cake/libs/exception_renderer.php @@ -27,24 +27,23 @@ * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown * and it is a type that ExceptionHandler does not know about it will be treated as a 500 error. * - * ### Implementing application specific exception handling + * ### Implementing application specific exception rendering * * You can implement application specific exception handling in one of a few ways: * * - Create a AppController::appError(); - * - Create an AppError class. + * - Create a subclass of ExceptionRenderer and configure it to be the `Exception.renderer` * * #### Using AppController::appError(); * * This controller method is called instead of the default exception handling. It receives the * thrown exception as its only argument. You should implement your error handling in that method. * - * #### Using an AppError class + * #### Using a subclass of ExceptionRenderer * - * This approach gives more flexibility and power in how you handle exceptions. You can create - * `app/libs/app_error.php` and create a class called `AppError`. The core ErrorHandler class - * will attempt to construct this class and let it handle the exception. This provides a more - * flexible way to handle exceptions in your application. + * Using a subclass of ExceptionRenderer gives you full control over how Exceptions are rendered, you + * can configure your class in your core.php, with `Configure::write('Exception.renderer', 'MyClass');` + * You should place any custom exception renderers in `app/libs`. * * @package cake * @subpackage cake.cake.libs From 0d5ed014d193d03f841de32e282311ddd61a78f5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 25 Nov 2010 23:16:03 -0500 Subject: [PATCH 141/160] Removing constants and configuration settings that don't are repeated or deprecated/not used. --- cake/console/shell_dispatcher.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/cake/console/shell_dispatcher.php b/cake/console/shell_dispatcher.php index 192801433..67fe4f37e 100644 --- a/cake/console/shell_dispatcher.php +++ b/cake/console/shell_dispatcher.php @@ -80,8 +80,6 @@ class ShellDispatcher { */ function __initConstants() { if (function_exists('ini_set')) { - ini_set('display_errors', '1'); - ini_set('error_reporting', E_ALL & ~E_DEPRECATED); ini_set('html_errors', false); ini_set('implicit_flush', true); ini_set('max_execution_time', 0); @@ -90,7 +88,6 @@ class ShellDispatcher { if (!defined('CAKE_CORE_INCLUDE_PATH')) { define('DS', DIRECTORY_SEPARATOR); define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__)))); - define('DISABLE_DEFAULT_ERROR_HANDLING', false); define('CAKEPHP_SHELL', true); if (!defined('CORE_PATH')) { if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ini_get('include_path'))) { From c717ff2e72bd33d02769c2fa2b579fc968ad0be2 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 25 Nov 2010 23:16:27 -0500 Subject: [PATCH 142/160] Adding logging of errors when debug = 0 for console applications. Fixes #1311 --- cake/console/libs/console_error_handler.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cake/console/libs/console_error_handler.php b/cake/console/libs/console_error_handler.php index fc8414767..0ee83ae43 100644 --- a/cake/console/libs/console_error_handler.php +++ b/cake/console/libs/console_error_handler.php @@ -76,9 +76,13 @@ class ConsoleErrorHandler extends ErrorHandler { } $stderr = self::getStderr(); list($name, $log) = self::_mapErrorCode($code); - $stderr->write(sprintf( - __("%s Error: %s in [%s, line %s]\n"), $name, $description, $file, $line - )); + $message = sprintf(__('%s in [%s, line %s]'), $description, $file, $line); + $stderr->write(sprintf(__("%s Error: %s\n"), $name, $message)); + + if (Configure::read('debug') == 0) { + App::import('Core', 'CakeLog'); + CakeLog::write($log, $message); + } } /** From d3f0d25c030ad5affe1d5c560a8d4ee2098f86a5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 27 Nov 2010 14:32:43 -0500 Subject: [PATCH 143/160] Removing error masking in ErrorHandler, instead correctly calling set_error_handler() works better. --- cake/libs/configure.php | 9 +++++---- cake/libs/error_handler.php | 3 --- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cake/libs/configure.php b/cake/libs/configure.php index bd88c5a18..34b6bbc52 100644 --- a/cake/libs/configure.php +++ b/cake/libs/configure.php @@ -102,12 +102,13 @@ class Configure { if (!include(CONFIGS . 'bootstrap.php')) { trigger_error(sprintf(__("Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP."), CONFIGS), E_USER_ERROR); } - - if (!empty(self::$_values['Error']['handler'])) { - set_error_handler(self::$_values['Error']['handler']); - } + $level = -1; if (isset(self::$_values['Error']['level'])) { error_reporting(self::$_values['Error']['level']); + $level = self::$_values['Error']['level']; + } + if (!empty(self::$_values['Error']['handler'])) { + set_error_handler(self::$_values['Error']['handler'], $level); } if (!empty(self::$_values['Exception']['handler'])) { set_exception_handler(self::$_values['Exception']['handler']); diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 48f06c1fd..2b9731d1a 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -134,9 +134,6 @@ class ErrorHandler { */ public static function handleError($code, $description, $file = null, $line = null, $context = null) { $errorConfig = Configure::read('Error'); - if (isset($errorConfig['level']) && ($code & ~$errorConfig['level'])) { - return; - } list($error, $log) = self::_mapErrorCode($code); $debug = Configure::read('debug'); From 345779772d6a2b3e3d53c0ce51908bfe4b2949da Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 27 Nov 2010 14:35:36 -0500 Subject: [PATCH 144/160] Fixing issue where an AppController::appError would cause errors as $method was not a real method. --- cake/libs/exception_renderer.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cake/libs/exception_renderer.php b/cake/libs/exception_renderer.php index a83e25cb4..0d6c71b83 100644 --- a/cake/libs/exception_renderer.php +++ b/cake/libs/exception_renderer.php @@ -159,7 +159,9 @@ class ExceptionRenderer { * @return void */ public function render() { - call_user_func_array(array($this, $this->method), array($this->error)); + if ($this->method) { + call_user_func_array(array($this, $this->method), array($this->error)); + } } /** From f08fa52a60e2880cd2b31e3a36d68f7d894c4c1b Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 27 Nov 2010 14:36:34 -0500 Subject: [PATCH 145/160] Syncing skel/config/core.php --- cake/console/templates/skel/config/core.php | 47 +++++++++++++++------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/cake/console/templates/skel/config/core.php b/cake/console/templates/skel/config/core.php index 2f8f49f83..cb6eff8c6 100644 --- a/cake/console/templates/skel/config/core.php +++ b/cake/console/templates/skel/config/core.php @@ -36,19 +36,42 @@ Configure::write('debug', 2); /** - * CakePHP Log Level: + * Configure the Error handler used to handle errors for your application. By default + * ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0 + * and log errors with CakeLog when debug = 0. * - * In case of Production Mode CakePHP gives you the possibility to continue logging errors. + * Options: * - * The following parameters can be used: - * Boolean: Set true/false to activate/deactivate logging - * Configure::write('log', true); - * - * Integer: Use built-in PHP constants to set the error level (see error_reporting) - * Configure::write('log', E_ERROR | E_WARNING); - * Configure::write('log', E_ALL ^ E_NOTICE); + * - `handler` - callback - The callback to handle errors. You can set this to any callback type, + * including anonymous functions. + * - `level` - int - The level of errors you are interested in capturing. + * - `trace` - boolean - Include stack traces for errors in log files. */ - Configure::write('log', true); + Configure::write('Error', array( + 'handler' => 'ErrorHandler::handleError', + 'level' => E_ALL & ~E_DEPRECATED, + 'trace' => true + )); + +/** + * Configure the Exception handler used for uncaught exceptions. By default, + * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and + * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0, + * framework errors will be coerced into generic HTTP errors. + * + * Options: + * + * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type, + * including anonymous functions. + * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you + * should place the file for that class in app/libs. This class needs to implement a render method. + * - `log` - boolean - Should Exceptions be logged? + */ + Configure::write('Exception', array( + 'handler' => 'ErrorHandler::handleException', + 'renderer' => 'ExceptionRenderer', + 'log' => true + )); /** * Application wide charset encoding @@ -121,14 +144,14 @@ * - `Session.name` - The name of the cookie to use. Defaults to 'CAKEPHP' * - `Session.timeout` - The number of minutes you want sessions to live for. This timeout is handled by CakePHP * - `Session.cookieTimeout` - The number of minutes you want session cookies to live for. - * - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the + * - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the * value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX * - `Session.defaults` - The default configuration set to use as a basis for your session. * There are four builtins: php, cake, cache, database. * - `Session.handler` - Can be used to enable a custom session handler. Expects an array of of callables, * that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler` * to the ini array. - * - `Session.autoRegenerate` - Enabling this setting, turns on automatic regeneration of sessions, and + * - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and * sessionids that change frequently. See CakeSession::$requestCountdown. * - `Session.ini` - An associative array of additional ini values to set. * From da98791e14951a61cf022613dc571999a3bf58bd Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 27 Nov 2010 19:37:25 -0500 Subject: [PATCH 146/160] Adding some more documentation about precedence of configuration. --- cake/libs/error_handler.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cake/libs/error_handler.php b/cake/libs/error_handler.php index 2b9731d1a..15d86b247 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error_handler.php @@ -43,12 +43,14 @@ * * This gives you full control over the exception handling process. The class you choose should be * loaded in your app/config/bootstrap.php, so its available to handle any exceptions. You can - * define the handler as any callback type. You can't combine this with other Exception settings. + * define the handler as any callback type. Using Exception.handler overrides all other exception + * handling settings and logic. * * #### Using `AppController::appError();` * * This controller method is called instead of the default exception rendering. It receives the * thrown exception as its only argument. You should implement your error handling in that method. + * Using AppController::appError(), will superseed any configuration for Exception.renderer. * * #### Using a custom renderer with `Exception.renderer` * From 7bfdbff3772dda0ab1f264a9fa25f5e18e6fd621 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 27 Nov 2010 19:39:55 -0500 Subject: [PATCH 147/160] Adding more documentation to core.php. --- app/config/core.php | 4 ++++ cake/console/templates/skel/config/core.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/app/config/core.php b/app/config/core.php index cb6eff8c6..c9560d15a 100644 --- a/app/config/core.php +++ b/app/config/core.php @@ -46,6 +46,8 @@ * including anonymous functions. * - `level` - int - The level of errors you are interested in capturing. * - `trace` - boolean - Include stack traces for errors in log files. + * + * @see ErrorHandler for more information on error handling and configuration. */ Configure::write('Error', array( 'handler' => 'ErrorHandler::handleError', @@ -66,6 +68,8 @@ * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you * should place the file for that class in app/libs. This class needs to implement a render method. * - `log` - boolean - Should Exceptions be logged? + * + * @see ErrorHandler for more information on exception handling and configuration. */ Configure::write('Exception', array( 'handler' => 'ErrorHandler::handleException', diff --git a/cake/console/templates/skel/config/core.php b/cake/console/templates/skel/config/core.php index cb6eff8c6..c9560d15a 100644 --- a/cake/console/templates/skel/config/core.php +++ b/cake/console/templates/skel/config/core.php @@ -46,6 +46,8 @@ * including anonymous functions. * - `level` - int - The level of errors you are interested in capturing. * - `trace` - boolean - Include stack traces for errors in log files. + * + * @see ErrorHandler for more information on error handling and configuration. */ Configure::write('Error', array( 'handler' => 'ErrorHandler::handleError', @@ -66,6 +68,8 @@ * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you * should place the file for that class in app/libs. This class needs to implement a render method. * - `log` - boolean - Should Exceptions be logged? + * + * @see ErrorHandler for more information on exception handling and configuration. */ Configure::write('Exception', array( 'handler' => 'ErrorHandler::handleException', From e40ee2576b04d94b1afd432cb120d990845359fa Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 28 Nov 2010 00:33:01 -0500 Subject: [PATCH 148/160] Minor optimization in h() Minor optimizations in FormHelper, as calls to ArrayAccess methods are avoided now. --- cake/basics.php | 6 +----- cake/libs/view/helpers/form.php | 10 +++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/cake/basics.php b/cake/basics.php index c41301ea1..ca935acde 100644 --- a/cake/basics.php +++ b/cake/basics.php @@ -186,11 +186,7 @@ if (!function_exists('sortByKey')) { if (is_string($double)) { $charset = $double; } - if ($charset) { - return htmlspecialchars($text, ENT_QUOTES, $charset, $double); - } else { - return htmlspecialchars($text, ENT_QUOTES, $defaultCharset, $double); - } + return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double); } /** diff --git a/cake/libs/view/helpers/form.php b/cake/libs/view/helpers/form.php index b347b69ed..0fe0e0ad2 100644 --- a/cake/libs/view/helpers/form.php +++ b/cake/libs/view/helpers/form.php @@ -243,12 +243,12 @@ class FormHelper extends AppHelper { if (empty($options['url']['controller'])) { if (!empty($model) && $model != $this->defaultModel) { $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model)); - } elseif (!empty($this->request['controller'])) { - $options['url']['controller'] = Inflector::underscore($this->request['controller']); + } elseif (!empty($this->request->params['controller'])) { + $options['url']['controller'] = Inflector::underscore($this->request->params['controller']); } } if (empty($options['action'])) { - $options['action'] = $this->request['action']; + $options['action'] = $this->request->params['action']; } $actionDefaults = array( @@ -307,9 +307,9 @@ class FormHelper extends AppHelper { $htmlAttributes = array_merge($options, $htmlAttributes); $this->fields = array(); - if (isset($this->request['_Token']) && !empty($this->request['_Token'])) { + if (isset($this->request->params['_Token']) && !empty($this->request->params['_Token'])) { $append .= $this->hidden('_Token.key', array( - 'value' => $this->request['_Token']['key'], 'id' => 'Token' . mt_rand()) + 'value' => $this->request->params['_Token']['key'], 'id' => 'Token' . mt_rand()) ); } From 284a8db3f41d7a13ddb8440ecb7ab74a75d6d340 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 28 Nov 2010 12:27:51 -0500 Subject: [PATCH 149/160] Moving error handling classes into a separate directory. Moving error handling test cases into a directory that matches the one in libs. Updating imports. --- cake/bootstrap.php | 4 ++-- cake/libs/{ => error}/error_handler.php | 2 +- cake/libs/{ => error}/exception_renderer.php | 0 cake/libs/{ => error}/exceptions.php | 0 cake/tests/cases/libs/all_error.test.php | 4 ++-- cake/tests/cases/libs/{ => error}/error_handler.test.php | 0 cake/tests/cases/libs/{ => error}/exception_renderer.test.php | 0 7 files changed, 5 insertions(+), 5 deletions(-) rename cake/libs/{ => error}/error_handler.php (99%) rename cake/libs/{ => error}/exception_renderer.php (100%) rename cake/libs/{ => error}/exceptions.php (100%) rename cake/tests/cases/libs/{ => error}/error_handler.test.php (100%) rename cake/tests/cases/libs/{ => error}/exception_renderer.test.php (100%) diff --git a/cake/bootstrap.php b/cake/bootstrap.php index e35c9b41d..acfc7bb2f 100644 --- a/cake/bootstrap.php +++ b/cake/bootstrap.php @@ -26,14 +26,14 @@ error_reporting(E_ALL & ~E_DEPRECATED); require CORE_PATH . 'cake' . DS . 'basics.php'; require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php'; -require LIBS . 'exceptions.php'; +require LIBS . 'error' . DS . 'exceptions.php'; require LIBS . 'object.php'; require LIBS . 'inflector.php'; require LIBS . 'app.php'; require LIBS . 'configure.php'; require LIBS . 'set.php'; require LIBS . 'cache.php'; -require LIBS . 'error_handler.php'; +require LIBS . 'error' . DS . 'error_handler.php'; Configure::bootstrap(isset($boot) ? $boot : true); diff --git a/cake/libs/error_handler.php b/cake/libs/error/error_handler.php similarity index 99% rename from cake/libs/error_handler.php rename to cake/libs/error/error_handler.php index 15d86b247..daa6b3234 100644 --- a/cake/libs/error_handler.php +++ b/cake/libs/error/error_handler.php @@ -104,7 +104,7 @@ class ErrorHandler { * @see http://php.net/manual/en/function.set-exception-handler.php */ public static function handleException(Exception $exception) { - App::import('Core', 'ExceptionRenderer'); + App::import('Core', 'error/ExceptionRenderer'); $config = Configure::read('Exception'); if (!empty($config['log'])) { if (!class_exists('CakeLog')) { diff --git a/cake/libs/exception_renderer.php b/cake/libs/error/exception_renderer.php similarity index 100% rename from cake/libs/exception_renderer.php rename to cake/libs/error/exception_renderer.php diff --git a/cake/libs/exceptions.php b/cake/libs/error/exceptions.php similarity index 100% rename from cake/libs/exceptions.php rename to cake/libs/error/exceptions.php diff --git a/cake/tests/cases/libs/all_error.test.php b/cake/tests/cases/libs/all_error.test.php index cfd994393..e37176908 100644 --- a/cake/tests/cases/libs/all_error.test.php +++ b/cake/tests/cases/libs/all_error.test.php @@ -38,8 +38,8 @@ class AllErrorTest extends PHPUnit_Framework_TestSuite { $libs = CORE_TEST_CASES . DS . 'libs' . DS; - $suite->addTestFile($libs . 'error_handler.test.php'); - $suite->addTestFile($libs . 'exception_renderer.test.php'); + $suite->addTestFile($libs . 'error' . DS . 'error_handler.test.php'); + $suite->addTestFile($libs . 'error' . DS . 'exception_renderer.test.php'); return $suite; } } diff --git a/cake/tests/cases/libs/error_handler.test.php b/cake/tests/cases/libs/error/error_handler.test.php similarity index 100% rename from cake/tests/cases/libs/error_handler.test.php rename to cake/tests/cases/libs/error/error_handler.test.php diff --git a/cake/tests/cases/libs/exception_renderer.test.php b/cake/tests/cases/libs/error/exception_renderer.test.php similarity index 100% rename from cake/tests/cases/libs/exception_renderer.test.php rename to cake/tests/cases/libs/error/exception_renderer.test.php From 91b5a5265e017bd27d7a8186d8fa2c571133336d Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 20:43:48 -0500 Subject: [PATCH 150/160] Making ConsoleErrorHandler be invoked with the correct error reporting level. --- cake/console/libs/console_error_handler.php | 4 ---- cake/console/shell_dispatcher.php | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/cake/console/libs/console_error_handler.php b/cake/console/libs/console_error_handler.php index 0ee83ae43..f70e34e6d 100644 --- a/cake/console/libs/console_error_handler.php +++ b/cake/console/libs/console_error_handler.php @@ -70,10 +70,6 @@ class ConsoleErrorHandler extends ErrorHandler { * @return void */ public static function handleError($code, $description, $file = null, $line = null, $context = null) { - $errorConfig = Configure::read('Error'); - if (isset($errorConfig['level']) && ($code & ~$errorConfig['level'])) { - return; - } $stderr = self::getStderr(); list($name, $log) = self::_mapErrorCode($code); $message = sprintf(__('%s in [%s, line %s]'), $description, $file, $line); diff --git a/cake/console/shell_dispatcher.php b/cake/console/shell_dispatcher.php index 67fe4f37e..3037b8d4f 100644 --- a/cake/console/shell_dispatcher.php +++ b/cake/console/shell_dispatcher.php @@ -145,7 +145,7 @@ class ShellDispatcher { } require_once CONSOLE_LIBS . 'console_error_handler.php'; set_exception_handler(array('ConsoleErrorHandler', 'handleException')); - set_error_handler(array('ConsoleErrorHandler', 'handleError')); + set_error_handler(array('ConsoleErrorHandler', 'handleError'), Configure::read('Error.level')); if (!defined('FULL_BASE_URL')) { define('FULL_BASE_URL', '/'); From 1f72e504d5b5969b7946da4562512b9f84806879 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 20:49:42 -0500 Subject: [PATCH 151/160] Fixing incorrect imports that caused test case to fail in CLI when run by itself. --- cake/tests/cases/libs/controller/components/acl.test.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cake/tests/cases/libs/controller/components/acl.test.php b/cake/tests/cases/libs/controller/components/acl.test.php index 8608ad63b..7222aad78 100644 --- a/cake/tests/cases/libs/controller/components/acl.test.php +++ b/cake/tests/cases/libs/controller/components/acl.test.php @@ -17,7 +17,8 @@ * @since CakePHP(tm) v 1.2.0.5435 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -App::import(array('controller' .DS . 'components' . DS . 'acl', 'model' . DS . 'db_acl')); +App::import('Component', 'Acl'); +App::import('model' . DS . 'db_acl'); /** * AclNodeTwoTestBase class From 43c184b2d254b2b8d1c18b5187d4713def7447fc Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 21:05:12 -0500 Subject: [PATCH 152/160] Fixing issues with CLI test runner where the error handler would continue to be cakephp's instead of PHPUnit's. --- cake/console/shells/testsuite.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cake/console/shells/testsuite.php b/cake/console/shells/testsuite.php index 67f2743d5..8814242a2 100644 --- a/cake/console/shells/testsuite.php +++ b/cake/console/shells/testsuite.php @@ -253,6 +253,10 @@ class TestSuiteShell extends Shell { */ protected function run($runnerArgs, $options = array()) { require_once CAKE . 'tests' . DS . 'lib' . DS . 'test_runner.php'; + + restore_error_handler(); + restore_error_handler(); + $testCli = new TestRunner($runnerArgs); $testCli->run($options); } From cc18c15e61fd6f2cf2f84f2ccbcb9e4722d0e92d Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 28 Nov 2010 00:40:41 -0500 Subject: [PATCH 153/160] Fixing coding standards. --- cake/libs/controller/components/acl.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cake/libs/controller/components/acl.php b/cake/libs/controller/components/acl.php index 49fc77aa3..13173dc1e 100644 --- a/cake/libs/controller/components/acl.php +++ b/cake/libs/controller/components/acl.php @@ -622,7 +622,7 @@ class IniAcl extends Object implements AclInterface { foreach ($userGroups as $group) { if (array_key_exists($group, $aclConfig)) { if (isset($aclConfig[$group]['deny'])) { - $groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny'])); + $groupDenies = $this->arrayTrim(explode(",", $aclConfig[$group]['deny'])); if (array_search($aco, $groupDenies)) { return false; @@ -669,13 +669,13 @@ class IniAcl extends Object implements AclInterface { $value = substr($value, 1, -1); } - $iniSetting[$sectionName][$key]=stripcslashes($value); + $iniSetting[$sectionName][$key] = stripcslashes($value); } else { if (!isset($sectionName)) { $sectionName = ''; } - $iniSetting[$sectionName][strtolower(trim($dataLine))]=''; + $iniSetting[$sectionName][strtolower(trim($dataLine))] = ''; } } } From 9d3b3a72cefabc78ef9302ba98f5c285cfd1b87f Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 28 Nov 2010 12:54:32 -0500 Subject: [PATCH 154/160] Starting to extract Ini file parsing out of IniAcl as it breaks single responsibility, and ini file parsing should be generic enough to be reused. Adding a test case. --- cake/libs/config/ini_file.php | 37 +++++++++++++++++++ .../tests/cases/libs/config/ini_file.test.php | 27 ++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 cake/libs/config/ini_file.php create mode 100644 cake/tests/cases/libs/config/ini_file.test.php diff --git a/cake/libs/config/ini_file.php b/cake/libs/config/ini_file.php new file mode 100644 index 000000000..cb5c8df73 --- /dev/null +++ b/cake/libs/config/ini_file.php @@ -0,0 +1,37 @@ +file = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS . 'acl.ini.php'; + } +/** + * test constrction + * + * @return void + */ + function testConstruct() { + $config = new IniFile($this->file); + $this->assertTrue(isset($config->admin)); + } +} \ No newline at end of file From 071cd9b477459c538b266ef1432bcd6bf8f2b26c Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 19:58:59 -0500 Subject: [PATCH 155/160] Adding very naive implementation of an ini file parser. --- cake/libs/config/ini_file.php | 31 +++++++++++++++++-- .../tests/cases/libs/config/ini_file.test.php | 11 ++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/cake/libs/config/ini_file.php b/cake/libs/config/ini_file.php index cb5c8df73..e31218bd0 100644 --- a/cake/libs/config/ini_file.php +++ b/cake/libs/config/ini_file.php @@ -23,7 +23,14 @@ * * @package cake.config */ -class IniFile { +class IniFile implements ArrayAccess { + +/** + * Values inside the ini file. + * + * @var array + */ + protected $_values = array(); /** * Build and construct a new ini file parser, the parser will be a representation of the ini @@ -32,6 +39,26 @@ class IniFile { * @param string $filename Full path to the file to parse. */ public function __construct($filename) { - + $contents = parse_ini_file($filename, true); + $this->_values = $contents; + } + + public function offsetExists($name) { + return isset($this->_values[$name]); + } + + public function offsetGet($name) { + if (!isset($this->_values[$name])) { + return null; + } + return $this->_values[$name]; + } + + public function offsetSet($name, $value) { + $this->_values[$name] = $value; + } + + public function offsetUnset($name) { + unset($this->_values[$name]); } } \ No newline at end of file diff --git a/cake/tests/cases/libs/config/ini_file.test.php b/cake/tests/cases/libs/config/ini_file.test.php index c41b74203..56535dc57 100644 --- a/cake/tests/cases/libs/config/ini_file.test.php +++ b/cake/tests/cases/libs/config/ini_file.test.php @@ -4,6 +4,11 @@ App::import('Core', 'config/IniFile'); class IniFileTest extends CakeTestCase { +/** + * The test file that will be read. + * + * @var string + */ var $file; /** @@ -15,6 +20,7 @@ class IniFileTest extends CakeTestCase { parent::setup(); $this->file = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS . 'acl.ini.php'; } + /** * test constrction * @@ -22,6 +28,9 @@ class IniFileTest extends CakeTestCase { */ function testConstruct() { $config = new IniFile($this->file); - $this->assertTrue(isset($config->admin)); + + $this->assertTrue(isset($config['admin'])); + $this->assertTrue(isset($config['paul']['groups'])); + $this->assertEquals('ads', $config['admin']['deny']); } } \ No newline at end of file From 35611d50c35896b4ff4880e14eedf6370450a94e Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 20:27:45 -0500 Subject: [PATCH 156/160] Fleshing out IniFile a bit more. --- cake/libs/config/ini_file.php | 51 ++++++++++++++++--- .../tests/cases/libs/config/ini_file.test.php | 35 +++++++++++++ 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/cake/libs/config/ini_file.php b/cake/libs/config/ini_file.php index e31218bd0..4b150a119 100644 --- a/cake/libs/config/ini_file.php +++ b/cake/libs/config/ini_file.php @@ -19,9 +19,12 @@ */ /** - * Ini file configuration parser. + * Ini file configuration parser. Since IniFile uses parse_ini_file underneath, + * you should be aware that this class shares the same behavior, especially with + * regards to boolean and null values. * * @package cake.config + * @see http://php.net/parse_ini_file */ class IniFile implements ArrayAccess { @@ -37,27 +40,61 @@ class IniFile implements ArrayAccess { * file as an object. * * @param string $filename Full path to the file to parse. + * @param string $section Only get one section. */ - public function __construct($filename) { + public function __construct($filename, $section = null) { $contents = parse_ini_file($filename, true); - $this->_values = $contents; + if (!empty($section) && isset($contents[$section])) { + $this->_values = $contents[$section]; + } else { + $this->_values = $contents; + } } +/** + * Get the contents of the ini file as a plain array. + * + * @return array + */ + public function asArray() { + return $this->_values; + } + +/** + * Part of ArrayAccess implementation. + * + * @param string $name + */ public function offsetExists($name) { return isset($this->_values[$name]); } - + +/** + * Part of ArrayAccess implementation. + * + * @param string $name + */ public function offsetGet($name) { if (!isset($this->_values[$name])) { return null; } return $this->_values[$name]; } - + +/** + * Part of ArrayAccess implementation. + * + * @param string $name + */ public function offsetSet($name, $value) { - $this->_values[$name] = $value; + throw new LogicException('You cannot modify an IniFile parse result.'); } - + +/** + * Part of ArrayAccess implementation. + * + * @param string $name + */ public function offsetUnset($name) { unset($this->_values[$name]); } diff --git a/cake/tests/cases/libs/config/ini_file.test.php b/cake/tests/cases/libs/config/ini_file.test.php index 56535dc57..73ad715c0 100644 --- a/cake/tests/cases/libs/config/ini_file.test.php +++ b/cake/tests/cases/libs/config/ini_file.test.php @@ -33,4 +33,39 @@ class IniFileTest extends CakeTestCase { $this->assertTrue(isset($config['paul']['groups'])); $this->assertEquals('ads', $config['admin']['deny']); } + +/** + * no other sections should exist. + * + * @return void + */ + function testReadingOnlyOneSection() { + $config = new IniFile($this->file, 'admin'); + + $this->assertTrue(isset($config['groups'])); + $this->assertEquals('administrators', $config['groups']); + } + +/** + * test getting all the values as an array + * + * @return void + */ + function testAsArray() { + $config = new IniFile($this->file); + $content = $config->asArray(); + + $this->assertTrue(isset($content['admin']['groups'])); + $this->assertTrue(isset($content['paul']['groups'])); + } + +/** + * test that values cannot be modified + * + * @expectedException LogicException + */ + function testNoModification() { + $config = new IniFile($this->file); + $config['admin'] = 'something'; + } } \ No newline at end of file From 3ddff879b150b77e21f7cb5308213d864ee59752 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 20:46:04 -0500 Subject: [PATCH 157/160] Converting IniAcl to use IniFile, this removes one of the classes responsibilities. --- cake/libs/controller/components/acl.php | 40 ++-------------- .../libs/controller/components/acl.test.php | 47 ------------------- 2 files changed, 5 insertions(+), 82 deletions(-) diff --git a/cake/libs/controller/components/acl.php b/cake/libs/controller/components/acl.php index 13173dc1e..f5d3febb8 100644 --- a/cake/libs/controller/components/acl.php +++ b/cake/libs/controller/components/acl.php @@ -645,43 +645,13 @@ class IniAcl extends Object implements AclInterface { /** * Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly. * - * @param string $fileName File + * @param string $filename File * @return array INI section structure */ - public function readConfigFile($fileName) { - $fileLineArray = file($fileName); - - foreach ($fileLineArray as $fileLine) { - $dataLine = trim($fileLine); - $firstChar = substr($dataLine, 0, 1); - - if ($firstChar != ';' && $dataLine != '') { - if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') { - $sectionName = preg_replace('/[\[\]]/', '', $dataLine); - } else { - $delimiter = strpos($dataLine, '='); - - if ($delimiter > 0) { - $key = strtolower(trim(substr($dataLine, 0, $delimiter))); - $value = trim(substr($dataLine, $delimiter + 1)); - - if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { - $value = substr($value, 1, -1); - } - - $iniSetting[$sectionName][$key] = stripcslashes($value); - } else { - if (!isset($sectionName)) { - $sectionName = ''; - } - - $iniSetting[$sectionName][strtolower(trim($dataLine))] = ''; - } - } - } - } - - return $iniSetting; + public function readConfigFile($filename) { + App::import('Core', 'config/IniFile'); + $iniFile = new IniFile($filename); + return $iniFile->asArray(); } /** diff --git a/cake/tests/cases/libs/controller/components/acl.test.php b/cake/tests/cases/libs/controller/components/acl.test.php index 7222aad78..b056e4842 100644 --- a/cake/tests/cases/libs/controller/components/acl.test.php +++ b/cake/tests/cases/libs/controller/components/acl.test.php @@ -260,53 +260,6 @@ class AclComponentTest extends CakeTestCase { */ class IniAclTest extends CakeTestCase { -/** - * testIniReadConfigFile - * - * @access public - * @return void - */ - function testReadConfigFile() { - $Ini = new IniAcl(); - $iniFile = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS . 'acl.ini.php'; - $result = $Ini->readConfigFile($iniFile); - $expected = array( - 'admin' => array( - 'groups' => 'administrators', - 'allow' => '', - 'deny' => 'ads', - ), - 'paul' => array( - 'groups' => 'users', - 'allow' =>'', - 'deny' => '', - ), - 'jenny' => array( - 'groups' => 'users', - 'allow' => 'ads', - 'deny' => 'images, files', - ), - 'nobody' => array( - 'groups' => 'anonymous', - 'allow' => '', - 'deny' => '', - ), - 'administrators' => array( - 'deny' => '', - 'allow' => 'posts, comments, images, files, stats, ads', - ), - 'users' => array( - 'allow' => 'posts, comments, images, files', - 'deny' => 'stats, ads', - ), - 'anonymous' => array( - 'allow' => '', - 'deny' => 'posts, comments, images, files, stats, ads', - ), - ); - $this->assertEqual($result, $expected); - } - /** * testIniCheck method * From 2495b3cd4c669d18a1723bda26081c8a4399575b Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 21:11:18 -0500 Subject: [PATCH 158/160] Trimming whitespace and adding a file header. --- cake/libs/config/ini_file.php | 12 +++++------ .../tests/cases/libs/config/ini_file.test.php | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/cake/libs/config/ini_file.php b/cake/libs/config/ini_file.php index 4b150a119..722dbcb08 100644 --- a/cake/libs/config/ini_file.php +++ b/cake/libs/config/ini_file.php @@ -19,7 +19,7 @@ */ /** - * Ini file configuration parser. Since IniFile uses parse_ini_file underneath, + * Ini file configuration parser. Since IniFile uses parse_ini_file underneath, * you should be aware that this class shares the same behavior, especially with * regards to boolean and null values. * @@ -36,7 +36,7 @@ class IniFile implements ArrayAccess { protected $_values = array(); /** - * Build and construct a new ini file parser, the parser will be a representation of the ini + * Build and construct a new ini file parser, the parser will be a representation of the ini * file as an object. * * @param string $filename Full path to the file to parse. @@ -63,7 +63,7 @@ class IniFile implements ArrayAccess { /** * Part of ArrayAccess implementation. * - * @param string $name + * @param string $name */ public function offsetExists($name) { return isset($this->_values[$name]); @@ -72,7 +72,7 @@ class IniFile implements ArrayAccess { /** * Part of ArrayAccess implementation. * - * @param string $name + * @param string $name */ public function offsetGet($name) { if (!isset($this->_values[$name])) { @@ -84,7 +84,7 @@ class IniFile implements ArrayAccess { /** * Part of ArrayAccess implementation. * - * @param string $name + * @param string $name */ public function offsetSet($name, $value) { throw new LogicException('You cannot modify an IniFile parse result.'); @@ -93,7 +93,7 @@ class IniFile implements ArrayAccess { /** * Part of ArrayAccess implementation. * - * @param string $name + * @param string $name */ public function offsetUnset($name) { unset($this->_values[$name]); diff --git a/cake/tests/cases/libs/config/ini_file.test.php b/cake/tests/cases/libs/config/ini_file.test.php index 73ad715c0..566c1113b 100644 --- a/cake/tests/cases/libs/config/ini_file.test.php +++ b/cake/tests/cases/libs/config/ini_file.test.php @@ -1,5 +1,22 @@ + * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice + * + * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests + * @package cake + * @subpackage cake.tests.cases + * @since CakePHP(tm) v 2.0 + * @license MIT License (http://www.opensource.org/licenses/mit-license.php) + */ App::import('Core', 'config/IniFile'); class IniFileTest extends CakeTestCase { @@ -54,7 +71,7 @@ class IniFileTest extends CakeTestCase { function testAsArray() { $config = new IniFile($this->file); $content = $config->asArray(); - + $this->assertTrue(isset($content['admin']['groups'])); $this->assertTrue(isset($content['paul']['groups'])); } From 40585a34e8ac1b7e04a9f8f84f2cb1beee5e4987 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 28 Nov 2010 21:22:10 -0500 Subject: [PATCH 159/160] Adding support for userPath in IniAcl. Test case added. Fixes #1291 --- cake/libs/controller/components/acl.php | 13 +++++++++++++ .../libs/controller/components/acl.test.php | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/cake/libs/controller/components/acl.php b/cake/libs/controller/components/acl.php index f5d3febb8..77f2cccc2 100644 --- a/cake/libs/controller/components/acl.php +++ b/cake/libs/controller/components/acl.php @@ -538,6 +538,15 @@ class IniAcl extends Object implements AclInterface { */ public $config = null; +/** + * The Set::classicExtract() path to the user/aro identifier in the + * acl.ini file. This path will be used to extract the string + * representation of a user used in the ini file. + * + * @var string + */ + public $userPath = 'User.username'; + /** * Initialize method * @@ -599,6 +608,10 @@ class IniAcl extends Object implements AclInterface { $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php'); } $aclConfig = $this->config; + + if (is_array($aro)) { + $aro = Set::classicExtract($aro, $this->userPath); + } if (isset($aclConfig[$aro]['deny'])) { $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny'])); diff --git a/cake/tests/cases/libs/controller/components/acl.test.php b/cake/tests/cases/libs/controller/components/acl.test.php index b056e4842..600b69069 100644 --- a/cake/tests/cases/libs/controller/components/acl.test.php +++ b/cake/tests/cases/libs/controller/components/acl.test.php @@ -283,6 +283,24 @@ class IniAclTest extends CakeTestCase { $this->assertFalse($Ini->check('nobody', 'comments')); } + +/** + * check should accept a user array. + * + * @return void + */ + function testCheckArray() { + $iniFile = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS . 'acl.ini.php'; + + $Ini = new IniAcl(); + $Ini->config = $Ini->readConfigFile($iniFile); + $Ini->userPath = 'User.username'; + + $user = array( + 'User' => array('username' => 'admin') + ); + $this->assertTrue($Ini->check($user, 'posts')); + } } From ffaec10a7c1a1cb50eddbdaebd5c471946360ee3 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Mon, 29 Nov 2010 22:37:08 -0200 Subject: [PATCH 160/160] Fixing the result of App::import() when name of class have slash. --- cake/libs/app.php | 6 +++++- cake/tests/cases/libs/app.test.php | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cake/libs/app.php b/cake/libs/app.php index 2812219c1..f18bb0719 100644 --- a/cake/libs/app.php +++ b/cake/libs/app.php @@ -505,7 +505,11 @@ class App { $file = Inflector::underscore($name) . ".{$ext}"; } $ext = self::__settings($type, $plugin, $parent); - if ($name != null && !class_exists($name . $ext['class'])) { + $className = $name; + if (strpos($className, '/') !== false) { + $className = substr($className, strrpos($className, '/') + 1); + } + if ($name != null && !class_exists($className . $ext['class'])) { if ($load = self::__mapped($name . $ext['class'], $type, $plugin)) { if (self::__load($load)) { if (self::$return) { diff --git a/cake/tests/cases/libs/app.test.php b/cake/tests/cases/libs/app.test.php index f9519057b..5a03cb623 100644 --- a/cake/tests/cases/libs/app.test.php +++ b/cake/tests/cases/libs/app.test.php @@ -211,6 +211,10 @@ class AppImportTest extends CakeTestCase { $this->assertTrue($file); $this->assertTrue(class_exists('Shell')); + $file = App::import('Lib', 'cache/Apc'); + $this->assertTrue($file); + $this->assertTrue(class_exists('ApcEngine')); + $file = App::import('Model', 'SomeRandomModelThatDoesNotExist', false); $this->assertFalse($file);