From 215333e56f32f06fd107966cf508ea5df4672ec0 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Thu, 22 Apr 2010 22:50:04 -0400 Subject: [PATCH 01/28] Making tests more accurate to normal use, removing extra params and adding some tests for sortKey. Refs #614 --- .../cases/libs/view/helpers/paginator.test.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/paginator.test.php b/cake/tests/cases/libs/view/helpers/paginator.test.php index 65c716b2c..a658f0dca 100644 --- a/cake/tests/cases/libs/view/helpers/paginator.test.php +++ b/cake/tests/cases/libs/view/helpers/paginator.test.php @@ -45,12 +45,12 @@ class PaginatorHelperTest extends CakeTestCase { 'nextPage' => true, 'pageCount' => 7, 'defaults' => array( - 'order' => 'Article.date ASC', + 'order' => array('Article.date' => 'asc'), 'limit' => 9, 'conditions' => array() ), 'options' => array( - 'order' => 'Article.date ASC', + 'order' => array('Article.date' => 'asc'), 'limit' => 9, 'page' => 1, 'conditions' => array() @@ -134,7 +134,7 @@ class PaginatorHelperTest extends CakeTestCase { Router::reload(); Router::parse('/'); Router::setRequestInfo(array( - array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'form' => array(), 'url' => array('url' => 'accounts/', 'mod_rewrite' => 'true'), 'bare' => 0), + array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'form' => array(), 'url' => array('url' => 'accounts/'), 'bare' => 0), array('plugin' => null, 'controller' => null, 'action' => null, 'base' => '/officespace', 'here' => '/officespace/accounts/', 'webroot' => '/officespace/', 'passedArgs' => array()) )); $this->Paginator->options(array('url' => array('param'))); @@ -302,9 +302,15 @@ class PaginatorHelperTest extends CakeTestCase { */ function testSortKey() { $result = $this->Paginator->sortKey(null, array( - 'order' => array('Article.title' => 'desc' + 'order' => array('Article.title' => 'desc' ))); $this->assertEqual('Article.title', $result); + + $result = $this->Paginator->sortKey('Article', array('sort' => 'Article.title')); + $this->assertEqual($result, 'Article.title'); + + $result = $this->Paginator->sortKey('Article', array('sort' => 'Article')); + $this->assertEqual($result, 'Article'); } /** From 813a3af19c8918b00ca1067a2c78886fa3bcd9bb Mon Sep 17 00:00:00 2001 From: Mark Story Date: Thu, 22 Apr 2010 23:17:11 -0400 Subject: [PATCH 02/28] Fixing security vulnerabilities in the test suite runner. --- cake/tests/lib/test_manager.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/cake/tests/lib/test_manager.php b/cake/tests/lib/test_manager.php index 5bfbc6279..6b4a6182d 100644 --- a/cake/tests/lib/test_manager.php +++ b/cake/tests/lib/test_manager.php @@ -70,7 +70,7 @@ class TestManager { $this->appTest = true; } if (isset($_GET['plugin'])) { - $this->pluginTest = $_GET['plugin']; + $this->pluginTest = htmlentities($_GET['plugin']); } } @@ -131,8 +131,11 @@ class TestManager { function runTestCase($testCaseFile, &$reporter, $testing = false) { $testCaseFileWithPath = $this->_getTestsPath() . DS . $testCaseFile; - if (!file_exists($testCaseFileWithPath)) { - trigger_error(sprintf(__('Test case %s cannot be found', true), $testCaseFile), E_USER_ERROR); + if (!file_exists($testCaseFileWithPath) || strpos($testCaseFileWithPath, '..')) { + trigger_error( + sprintf(__("Test case %s cannot be found", true), htmlentities($testCaseFile)), + E_USER_ERROR + ); return false; } @@ -156,8 +159,14 @@ class TestManager { function runGroupTest($groupTestName, &$reporter) { $filePath = $this->_getTestsPath('groups') . DS . strtolower($groupTestName) . $this->_groupExtension; - if (!file_exists($filePath)) { - trigger_error(sprintf(__('Group test %s cannot be found at %s', true), $groupTestName, $filePath), E_USER_ERROR); + if (!file_exists($filePath) || strpos($testCaseFileWithPath, '..')) { + trigger_error(sprintf( + __("Group test %s cannot be found at %s", true), + htmlentities($groupTestName), + htmlentities($filePath) + ), + E_USER_ERROR + ); } require_once $filePath; From c404ae54007690dca3a501c3042e9c8ac56e1d64 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Thu, 22 Apr 2010 23:36:20 -0400 Subject: [PATCH 03/28] Adding htmlentities() to all parameters passed into the HtmlReporter. --- cake/tests/lib/reporter/cake_html_reporter.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cake/tests/lib/reporter/cake_html_reporter.php b/cake/tests/lib/reporter/cake_html_reporter.php index 1144a3f00..e202a80cc 100755 --- a/cake/tests/lib/reporter/cake_html_reporter.php +++ b/cake/tests/lib/reporter/cake_html_reporter.php @@ -27,7 +27,17 @@ include_once dirname(__FILE__) . DS . 'cake_base_reporter.php'; * @subpackage cake.tests.lib */ class CakeHtmlReporter extends CakeBaseReporter { - +/** + * Constructor + * + * @param string $charset + * @param string $params + * @return void + */ + function CakeHtmlReporter($charset = 'utf-8', $params = array()) { + $params = array_map(array($this, '_htmlEntities'), $params); + $this->CakeBaseReporter($charset, $params); + } /** * Paints the top of the web page setting the * title to the name of the starting test. @@ -40,7 +50,7 @@ class CakeHtmlReporter extends CakeBaseReporter { $this->sendNoCacheHeaders(); $this->paintDocumentStart(); $this->paintTestMenu(); - echo "

$testName

\n"; + printf("

%s

\n", $this->_htmlEntities($testName)); echo "
    \n"; } From bc6b8e5dfdc8a4272f819a722d39c8319cf56871 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 23 Apr 2010 00:04:15 -0400 Subject: [PATCH 04/28] Fixing parameters from leaking into the script tag when calling JsHelper::submit(). Added test cases and refactored JsHelper::link(). Fixes #613 --- cake/libs/view/helpers/js.php | 8 ++-- .../tests/cases/libs/view/helpers/js.test.php | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/cake/libs/view/helpers/js.php b/cake/libs/view/helpers/js.php index 5ad10191d..f8caa21e1 100644 --- a/cake/libs/view/helpers/js.php +++ b/cake/libs/view/helpers/js.php @@ -319,10 +319,7 @@ class JsHelper extends AppHelper { $event = $this->event('click', $requestString, $options); } if (isset($options['buffer']) && $options['buffer'] == false) { - $opts = array(); - if (isset($options['safe'])) { - $opts['safe'] = $options['safe']; - } + $opts = array_intersect_key(array('safe' => null), $options); $out .= $this->Html->scriptBlock($event, $opts); } return $out; @@ -397,7 +394,8 @@ class JsHelper extends AppHelper { $event = $this->event('click', $requestString, $options); } if (isset($options['buffer']) && $options['buffer'] == false) { - $out .= $this->Html->scriptBlock($event, $options); + $opts = array_intersect_key(array('safe' => null), $options); + $out .= $this->Html->scriptBlock($event, $opts); } return $out; } diff --git a/cake/tests/cases/libs/view/helpers/js.test.php b/cake/tests/cases/libs/view/helpers/js.test.php index 292bbb19e..0b6f573a0 100644 --- a/cake/tests/cases/libs/view/helpers/js.test.php +++ b/cake/tests/cases/libs/view/helpers/js.test.php @@ -456,6 +456,43 @@ CODE; $this->assertTags($result, $expected); } +/** + * test that no buffer works with submit() and that parameters are leaking into the script tag. + * + * @return void + */ + function testSubmitWithNoBuffer() { + $this->_useMock(); + $options = array('update' => '#content', 'id' => 'test-submit', 'buffer' => false, 'safe' => false); + $this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'serialize-code', array('serializeform', '*')); + $this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'serialize-code', array('serializeForm', '*')); + $this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'ajax-code', array('request', '*')); + $this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'event-handler', array('event', '*')); + + $this->Js->TestJsEngine->expectAt(0, 'dispatchMethod', array('get', '*')); + $this->Js->TestJsEngine->expectAt(1, 'dispatchMethod', array(new PatternExpectation('/serializeForm/i'), '*')); + $this->Js->TestJsEngine->expectAt(2, 'dispatchMethod', array('request', '*')); + + $params = array( + 'update' => $options['update'], 'buffer' => false, 'safe' => false, 'data' => 'serialize-code', + 'method' => 'post', 'dataExpression' => true + ); + $this->Js->TestJsEngine->expectAt(3, 'dispatchMethod', array( + 'event', array('click', "ajax-code", $params) + )); + + $result = $this->Js->submit('Save', $options); + $expected = array( + 'div' => array('class' => 'submit'), + 'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save'), + '/div', + 'script' => array('type' => 'text/javascript'), + 'event-handler', + '/script' + ); + $this->assertTags($result, $expected); + } + /** * Test that Object::Object() is not breaking json output in JsHelper * From 56967e71c1d198356ec509009d31e33222c1ab81 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 23 Apr 2010 00:46:13 -0400 Subject: [PATCH 05/28] Fixing group path checking in test manager. Conflicts: cake/tests/lib/test_manager.php --- cake/tests/lib/test_manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cake/tests/lib/test_manager.php b/cake/tests/lib/test_manager.php index 6b4a6182d..335fb37e4 100644 --- a/cake/tests/lib/test_manager.php +++ b/cake/tests/lib/test_manager.php @@ -159,7 +159,7 @@ class TestManager { function runGroupTest($groupTestName, &$reporter) { $filePath = $this->_getTestsPath('groups') . DS . strtolower($groupTestName) . $this->_groupExtension; - if (!file_exists($filePath) || strpos($testCaseFileWithPath, '..')) { + if (!file_exists($filePath) || strpos($filePath, '..')) { trigger_error(sprintf( __("Group test %s cannot be found at %s", true), htmlentities($groupTestName), From 5f03862f25ea7e8fbb711a76db56ae5874aa92cb Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 24 Apr 2010 10:40:15 -0700 Subject: [PATCH 06/28] Adding tests that show that Router is not chopping off periods from passed arguments. Refs #620 --- cake/tests/cases/libs/router.test.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cake/tests/cases/libs/router.test.php b/cake/tests/cases/libs/router.test.php index a68b83a88..b111d382a 100644 --- a/cake/tests/cases/libs/router.test.php +++ b/cake/tests/cases/libs/router.test.php @@ -1664,6 +1664,20 @@ class RouterTest extends CakeTestCase { $this->assertEqual($result, $expected); } +/** + * test that requests with a trailing dot don't loose the do. + * + * @return void + */ + function testParsingWithTrailingPeriod() { + Router::reload(); + $result = Router::parse('/posts/view/something.'); + $this->assertEqual($result['pass'][0], 'something.', 'Period was chopped off %s'); + + $result = Router::parse('/posts/view/something. . .'); + $this->assertEqual($result['pass'][0], 'something. . .', 'Period was chopped off %s'); + } + /** * testParsingWithPrefixes method * From 3e85577c1f77fad6edfe3a62ad419cfae1e07e26 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 24 Apr 2010 10:42:19 -0700 Subject: [PATCH 07/28] Adding tests for dispatcher to show periods not being removed. Refs #620 --- cake/tests/cases/dispatcher.test.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cake/tests/cases/dispatcher.test.php b/cake/tests/cases/dispatcher.test.php index 8be94da50..44a13b85f 100644 --- a/cake/tests/cases/dispatcher.test.php +++ b/cake/tests/cases/dispatcher.test.php @@ -1366,6 +1366,11 @@ class DispatcherTest extends CakeTestCase { $url = 'test_dispatch_pages/camelCased'; $controller = $Dispatcher->dispatch($url, array('return' => 1)); $this->assertEqual('TestDispatchPages', $controller->name); + + $url = 'test_dispatch_pages/camelCased/something. .'; + $controller = $Dispatcher->dispatch($url, array('return' => 1)); + $this->assertEqual($controller->params['pass'][0], 'something. .', 'Period was chopped off. %s'); + } /** From 46df1be3844286dd875dff91e47c9fa345619ab0 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 25 Apr 2010 02:34:18 +0530 Subject: [PATCH 08/28] Model::deleteAll() now returns false if the 'find' to fetch records ids returns false (in case of sql error). Closes #272 --- cake/libs/model/model.php | 13 +++++++------ cake/tests/cases/libs/model/model_delete.test.php | 6 ++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index f017c7bc5..8bf362710 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -1907,14 +1907,15 @@ class Model extends Overloadable { if (!$cascade && !$callbacks) { return $db->delete($this, $conditions); } else { - $ids = Set::extract( - $this->find('all', array_merge(array( - 'fields' => "{$this->alias}.{$this->primaryKey}", - 'recursive' => 0), compact('conditions')) - ), - "{n}.{$this->alias}.{$this->primaryKey}" + $ids = $this->find('all', array_merge(array( + 'fields' => "{$this->alias}.{$this->primaryKey}", + 'recursive' => 0), compact('conditions')) ); + if ($ids === false) { + return false; + } + $ids = Set::extract($ids, "{n}.{$this->alias}.{$this->primaryKey}"); if (empty($ids)) { return true; } diff --git a/cake/tests/cases/libs/model/model_delete.test.php b/cake/tests/cases/libs/model/model_delete.test.php index 68088b42c..1cc81cd77 100644 --- a/cake/tests/cases/libs/model/model_delete.test.php +++ b/cake/tests/cases/libs/model/model_delete.test.php @@ -423,6 +423,12 @@ class ModelDeleteTest extends BaseModelTest { $result = $TestModel->deleteAll(array('Article.user_id' => 999)); $this->assertTrue($result, 'deleteAll returned false when all no records matched conditions. %s'); + + $this->expectError(); + ob_start(); + $result = $TestModel->deleteAll(array('Article.non_existent_field' => 999)); + ob_get_clean(); + $this->assertFalse($result, 'deleteAll returned true when find query generated sql error. %s'); } /** From ce260debbc0ebd25a396b59f432f4818be2f59a4 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sat, 24 Apr 2010 17:30:00 -0700 Subject: [PATCH 09/28] Adding tests for passed arguments with dots when parseExtensions() has been called. Refs #620 --- cake/tests/cases/libs/router.test.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cake/tests/cases/libs/router.test.php b/cake/tests/cases/libs/router.test.php index b111d382a..d6fdc303a 100644 --- a/cake/tests/cases/libs/router.test.php +++ b/cake/tests/cases/libs/router.test.php @@ -1678,6 +1678,22 @@ class RouterTest extends CakeTestCase { $this->assertEqual($result['pass'][0], 'something. . .', 'Period was chopped off %s'); } +/** + * test that requests with a trailing dot don't loose the do. + * + * @return void + */ + function testParsingWithTrailingPeriodAndParseExtensions() { + Router::reload(); + Router::parseExtensions('json'); + + $result = Router::parse('/posts/view/something.'); + $this->assertEqual($result['pass'][0], 'something.', 'Period was chopped off %s'); + + $result = Router::parse('/posts/view/something. . .'); + $this->assertEqual($result['pass'][0], 'something. . .', 'Period was chopped off %s'); + } + /** * testParsingWithPrefixes method * From 1c064788c5ccc80eae8bbb2385350a8983867acc Mon Sep 17 00:00:00 2001 From: predominant Date: Sun, 25 Apr 2010 14:27:29 +1000 Subject: [PATCH 10/28] Updated vesion numbers to 1.3.0 --- 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 6d2b7a2db..4276a6cf6 100644 --- a/cake/VERSION.txt +++ b/cake/VERSION.txt @@ -18,4 +18,5 @@ // @license MIT License (http://www.opensource.org/licenses/mit-license.php) // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -1.3.0-RC4 +1.3.0 + diff --git a/cake/config/config.php b/cake/config/config.php index f71dfa725..2b603aede 100644 --- a/cake/config/config.php +++ b/cake/config/config.php @@ -17,5 +17,5 @@ * @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.0-RC4'; +return $config['Cake.version'] = '1.3.0'; ?> \ No newline at end of file diff --git a/cake/libs/view/pages/home.ctp b/cake/libs/view/pages/home.ctp index d9692ccb1..a217acde2 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 af6435ece8ced3a83ba9aa0a1ed076cf71d746e1 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 25 Apr 2010 00:22:57 -0700 Subject: [PATCH 11/28] Fixing issue where table name was not using fully qualified table names, causing issues with models using table prefixes. Tests added. Fixes #623 --- cake/libs/model/cake_schema.php | 18 +++---- .../cases/libs/model/cake_schema.test.php | 51 +++++++++++++++++-- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/cake/libs/model/cake_schema.php b/cake/libs/model/cake_schema.php index ae745c76e..3314548be 100644 --- a/cake/libs/model/cake_schema.php +++ b/cake/libs/model/cake_schema.php @@ -249,10 +249,10 @@ class CakeSchema extends Object { if (in_array($table, $currentTables)) { $key = array_search($table, $currentTables); - if (empty($tables[$Object->table])) { - $tables[$Object->table] = $this->__columns($Object); - $tables[$Object->table]['indexes'] = $db->index($Object); - $tables[$Object->table]['tableParameters'] = $db->readTableParameters($table); + if (empty($tables[$table])) { + $tables[$table] = $this->__columns($Object); + $tables[$table]['indexes'] = $db->index($Object); + $tables[$table]['tableParameters'] = $db->readTableParameters($table); unset($currentTables[$key]); } if (!empty($Object->hasAndBelongsToMany)) { @@ -261,12 +261,12 @@ class CakeSchema extends Object { $class = $assocData['with']; } if (is_object($Object->$class)) { - $table = $db->fullTableName($Object->$class, false); - if (in_array($table, $currentTables)) { + $withTable = $db->fullTableName($Object->$class, false); + if (in_array($withTable, $currentTables)) { $key = array_search($table, $currentTables); - $tables[$Object->$class->table] = $this->__columns($Object->$class); - $tables[$Object->$class->table]['indexes'] = $db->index($Object->$class); - $tables[$Object->$class->table]['tableParameters'] = $db->readTableParameters($table); + $tables[$withTable] = $this->__columns($Object->$class); + $tables[$withTable]['indexes'] = $db->index($Object->$class); + $tables[$withTable]['tableParameters'] = $db->readTableParameters($withTable); unset($currentTables[$key]); } } diff --git a/cake/tests/cases/libs/model/cake_schema.test.php b/cake/tests/cases/libs/model/cake_schema.test.php index cb6e2cb1a..9711b3d42 100644 --- a/cake/tests/cases/libs/model/cake_schema.test.php +++ b/cake/tests/cases/libs/model/cake_schema.test.php @@ -448,6 +448,33 @@ class SchemaCrossDatabaseFixture extends CakeTestFixture { ); } +/** + * SchemaPrefixAuthUser class + * + * @package cake + * @subpackage cake.tests.cases.libs.model + */ +class SchemaPrefixAuthUser extends CakeTestModel { +/** + * name property + * + * @var string + */ + var $name = 'SchemaPrefixAuthUser'; +/** + * table prefix + * + * @var string + */ + var $tablePrefix = 'auth_'; +/** + * useTable + * + * @var string + */ + var $useTable = 'users'; +} + /** * CakeSchemaTest * @@ -463,7 +490,7 @@ class CakeSchemaTest extends CakeTestCase { * @access public */ var $fixtures = array( - 'core.post', 'core.tag', 'core.posts_tag', 'core.test_plugin_comment', + 'core.post', 'core.tag', 'core.posts_tag', 'core.test_plugin_comment', 'core.datatype', 'core.auth_user', 'core.author', 'core.test_plugin_article', 'core.user', 'core.comment' ); @@ -523,7 +550,6 @@ class CakeSchemaTest extends CakeTestCase { $expected = array('comments', 'datatypes', 'posts', 'posts_tags', 'tags'); $this->assertEqual(array_keys($read['tables']), $expected); - foreach ($read['tables'] as $table => $fields) { $this->assertEqual(array_keys($fields), array_keys($this->Schema->tables[$table])); } @@ -551,6 +577,25 @@ class CakeSchemaTest extends CakeTestCase { $this->assertFalse(isset($read['tables']['missing']['posts']), 'Posts table was not read from tablePrefix %s'); } +/** + * test read() with tablePrefix properties. + * + * @return void + */ + function testSchemaReadWithTablePrefix() { + $model =& new SchemaPrefixAuthUser(); + + $Schema =& new CakeSchema(); + $read = $Schema->read(array( + 'connection' => 'test_suite', + 'name' => 'TestApp', + 'models' => array('SchemaPrefixAuthUser') + )); + unset($read['tables']['missing']); + $this->assertTrue(isset($read['tables']['auth_users']), 'auth_users key missing %s'); + + } + /** * test reading schema from plugins. * @@ -575,7 +620,7 @@ class CakeSchemaTest extends CakeTestCase { $this->assertTrue(isset($read['tables']['test_plugin_comments'])); $this->assertTrue(isset($read['tables']['posts'])); $this->assertEqual(count($read['tables']), 4); - + App::build(); } From c2bd87144e3e81acb9004055d329f45a90728422 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 27 Apr 2010 00:17:19 +0530 Subject: [PATCH 12/28] Adding test case for HtmlHelper::url() showing use of key 'full_base' for parameter. Refs #627 --- .../cases/libs/view/helpers/html.test.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index 8800e6eec..84c964208 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -20,6 +20,10 @@ App::import('Core', array('Helper', 'AppHelper', 'ClassRegistry', 'Controller', 'Model')); App::import('Helper', array('Html', 'Form')); +if (!defined('FULL_BASE_URL')) { + define('FULL_BASE_URL', 'http://cakephp.org'); +} + /** * TheHtmlTestController class * @@ -157,6 +161,10 @@ class HtmlHelperTest extends CakeTestCase { $expected = array('a' => array('href' => '/home'), 'preg:/\/home/', '/a'); $this->assertTags($result, $expected); + $result = $this->Html->link('Posts', array('controller' => 'posts', 'action' => 'index', 'full_base' => true)); + $expected = array('a' => array('href' => FULL_BASE_URL . '/posts'), 'Posts', '/a'); + $this->assertTags($result, $expected); + $result = $this->Html->link('Home', '/home', array('confirm' => 'Are you sure you want to do this?')); $expected = array( 'a' => array('href' => '/home', 'onclick' => 'return confirm('Are you sure you want to do this?');'), @@ -358,18 +366,18 @@ class HtmlHelperTest extends CakeTestCase { $webroot = $this->Html->webroot; $this->Html->webroot = '/testing/'; $result = $this->Html->image('__cake_test_image.gif'); - + $this->assertTags($result, array( 'img' => array( 'src' => 'preg:/\/testing\/theme\/test_theme\/img\/__cake_test_image\.gif\?\d+/', 'alt' => '' ))); $this->Html->webroot = $webroot; - + $dir =& new Folder(WWW_ROOT . 'theme' . DS . 'test_theme'); $dir->delete(); } - + /** * test theme assets in main webroot path * @@ -383,7 +391,7 @@ class HtmlHelperTest extends CakeTestCase { )); $webRoot = Configure::read('App.www_root'); Configure::write('App.www_root', TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'webroot' . DS); - + $webroot = $this->Html->webroot; $this->Html->theme = 'test_theme'; $result = $this->Html->css('webroot_test'); @@ -399,7 +407,7 @@ class HtmlHelperTest extends CakeTestCase { 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*theme\/test_theme\/css\/theme_webroot\.css/') ); $this->assertTags($result, $expected); - + Configure::write('App.www_root', $webRoot); } From bb239e3816263b1bac72786a272fa5794562bc27 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 27 Apr 2010 22:42:33 -0400 Subject: [PATCH 13/28] Fixing parse error in php4 for MediaView. Also fixing undefined variable error in Dispatcher. Fixes #628 --- cake/dispatcher.php | 1 + cake/libs/view/media.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cake/dispatcher.php b/cake/dispatcher.php index 7ede6203a..6d590cd9b 100644 --- a/cake/dispatcher.php +++ b/cake/dispatcher.php @@ -620,6 +620,7 @@ class Dispatcher extends Object { } App::import('View', 'Media', false); + $controller = null; $Media = new MediaView($controller); if (isset($Media->mimeType[$ext])) { $contentType = $Media->mimeType[$ext]; diff --git a/cake/libs/view/media.php b/cake/libs/view/media.php index e85924b64..93c394a38 100644 --- a/cake/libs/view/media.php +++ b/cake/libs/view/media.php @@ -95,7 +95,7 @@ class MediaView extends View { * * @param object $controller */ - function __construct(&$controller = null) { + function __construct(&$controller) { parent::__construct($controller); } From 2fab47e740de096cdd5bc72a4b0dcef7c6549461 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 27 Apr 2010 22:50:34 -0400 Subject: [PATCH 14/28] Updating doc block for EmailComponent::send(). Fixes #633 --- cake/libs/controller/components/email.php | 1 + 1 file changed, 1 insertion(+) diff --git a/cake/libs/controller/components/email.php b/cake/libs/controller/components/email.php index 32ae8defb..19d7fc379 100755 --- a/cake/libs/controller/components/email.php +++ b/cake/libs/controller/components/email.php @@ -326,6 +326,7 @@ class EmailComponent extends Object{ * Send an email using the specified content, template and layout * * @param mixed $content Either an array of text lines, or a string with contents + * If you are rendering a template this variable will be sent to the templates as `$content` * @param string $template Template to use when sending email * @param string $layout Layout to use to enclose email body * @return boolean Success From 328c58635bdda19ff521a88564bc5cb6e9f07d84 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 27 Apr 2010 23:03:19 -0400 Subject: [PATCH 15/28] Fixing inflection of words ending in analysis. Fixes #619 --- cake/libs/inflector.php | 2 +- cake/tests/cases/libs/inflector.test.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cake/libs/inflector.php b/cake/libs/inflector.php index 1f1fd002c..95ca9f945 100644 --- a/cake/libs/inflector.php +++ b/cake/libs/inflector.php @@ -133,7 +133,7 @@ class Inflector { '/(drive)s$/i' => '\1', '/([^fo])ves$/i' => '\1fe', '/(^analy)ses$/i' => '\1sis', - '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', + '/(analy|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', '/([ti])a$/i' => '\1um', '/(p)eople$/i' => '\1\2erson', '/(m)en$/i' => '\1an', diff --git a/cake/tests/cases/libs/inflector.test.php b/cake/tests/cases/libs/inflector.test.php index e8aa61597..9a01c0dd7 100644 --- a/cake/tests/cases/libs/inflector.test.php +++ b/cake/tests/cases/libs/inflector.test.php @@ -116,6 +116,10 @@ class InflectorTest extends CakeTestCase { $this->assertEqual(Inflector::singularize('niches'), 'niche'); $this->assertEqual(Inflector::singularize('waves'), 'wave'); $this->assertEqual(Inflector::singularize('bureaus'), 'bureau'); + $this->assertEqual(Inflector::singularize('genetic_analyses'), 'genetic_analysis'); + $this->assertEqual(Inflector::singularize('doctor_diagnoses'), 'doctor_diagnosis'); + $this->assertEqual(Inflector::singularize('parantheses'), 'paranthesis'); + $this->assertEqual(Inflector::singularize(''), ''); } From afa0e6b8f94842fa89bcb2f49f84c437ed66899d Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 27 Apr 2010 23:19:55 -0400 Subject: [PATCH 16/28] Adding cake.icon.png to the skel dir. Fixes the wrong asset being included when new projects are generated. Fixes. #637 --- .../templates/skel/webroot/img/cake.icon.gif | Bin 233 -> 0 bytes .../templates/skel/webroot/img/cake.icon.png | Bin 0 -> 943 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cake/console/templates/skel/webroot/img/cake.icon.gif create mode 100644 cake/console/templates/skel/webroot/img/cake.icon.png diff --git a/cake/console/templates/skel/webroot/img/cake.icon.gif b/cake/console/templates/skel/webroot/img/cake.icon.gif deleted file mode 100644 index f29f72ebef20ce39a1e3721d31b76d9054b1dc90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 233 zcmVOrfx~(a*Br=IF!2lMFyj!pzT(o0Foa zdn-*>Om~4(V_pR~MF2EGA^8La000jFEC2ui02BZe000D*@X1N5t>>`K@|6NJ6h&YL z1u`%~wUB3glC5+ga)976a!3oFOhFu(2DMubr5G5VhQ{x4NGt;hD1iW&9tgW!0iZB! z6O)6HG-waF&;)>@C@r&FLW6?XF3Wfe6jmrIZUbdo27(g_16K`ZTZ}-3IRcmfa});+ jCL}5ZNSK%y0t-u|r5FwZRfnys7YD7i0<9mpxe)+6uKiOz diff --git a/cake/console/templates/skel/webroot/img/cake.icon.png b/cake/console/templates/skel/webroot/img/cake.icon.png new file mode 100644 index 0000000000000000000000000000000000000000..394fa42d5131cdc7b0b1246af93b92179f3c887e GIT binary patch literal 943 zcmV;g15o^lP)9q)cr7> zIGsQFGn3| zCzs2iP$-yfVPOGVTU&6sT(-5fwHb2tVsLP9#{Vr9Ct?R7q(rf?v2A5#W$OI=e1YUJ zQ1YRnA&iWSQ1XYAm__>aYb6XIhMiYVD+-z8_pYi6+CsH{*^m;vOjqvbr=H&DFkeqxHQBh$Scsoy0Glw(T zsaSG*ok62V;~yXYNgP*DUw;o98^+0@vGFb{HC+As}XJ=;xg=B7N_;-mKbHH{|lXs_o+aPcs5~J?s%^P2Odb)Uz z$GvY6^!N9(C2-h?28B$qx7%_yHnt2eU%nQ0qThbl6a_+b)EirjBgQ`g1_07Fr&6R? RzIgxu002ovPDHLkV1mdlwUYn< literal 0 HcmV?d00001 From 5dce79e42488c8cc3e1c987bafba059b6d232748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lorenzo=20Rodr=C3=ADguez?= Date: Mon, 26 Apr 2010 02:32:32 -0430 Subject: [PATCH 17/28] First steps into removing internal usage of File and Folder class in favor of SPL equivalents --- cake/libs/cache/file.php | 70 +++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/cake/libs/cache/file.php b/cake/libs/cache/file.php index 0476f9872..9e54dfdd1 100644 --- a/cake/libs/cache/file.php +++ b/cake/libs/cache/file.php @@ -78,19 +78,11 @@ class FileEngine extends CacheEngine { ), $settings )); - if (!isset($this->_File)) { - $this->_File =& new File($this->settings['path'] . DS . 'cake'); - } if (DIRECTORY_SEPARATOR === '\\') { $this->settings['isWindows'] = true; } - - $path = $this->_File->Folder->cd($this->settings['path']); - if ($path) { - $this->settings['path'] = $path; - } - return $this->__active(); + return $this->_active(); } /** @@ -115,7 +107,7 @@ class FileEngine extends CacheEngine { return false; } - if ($this->_setKey($key) === false) { + if ($this->_setKey($key, true) === false) { return false; } @@ -134,12 +126,11 @@ class FileEngine extends CacheEngine { } if ($this->settings['lock']) { - $this->_File->lock = true; + //$this->_File->lock = true; } $expires = time() + $duration; $contents = $expires . $lineBreak . $data . $lineBreak; - $success = $this->_File->write($contents); - $this->_File->close(); + $success = $this->_File->ftruncate(0) && $this->_File->fwrite($contents); return $success; } @@ -150,20 +141,27 @@ class FileEngine extends CacheEngine { * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it */ public function read($key) { - if ($this->_setKey($key) === false || !$this->_init || !$this->_File->exists()) { + if (!$this->_init || $this->_setKey($key) === false) { return false; } if ($this->settings['lock']) { - $this->_File->lock = true; + //$this->_File->lock = true; } + $this->_File->rewind(); $time = time(); - $cachetime = intval($this->_File->read(11)); + $cachetime = intval($this->_File->current()); if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) { - $this->_File->close(); return false; } - $data = $this->_File->read(true); + + $data = ''; + $this->_File->next(); + while ($this->_File->valid()) { + $data .= $this->_File->current(); + $this->_File->next(); + } + $data = trim($data); if ($data !== '' && !empty($this->settings['serialize'])) { if ($this->settings['isWindows']) { @@ -171,7 +169,6 @@ class FileEngine extends CacheEngine { } $data = unserialize((string)$data); } - $this->_File->close(); return $data; } @@ -185,7 +182,7 @@ class FileEngine extends CacheEngine { if ($this->_setKey($key) === false || !$this->_init) { return false; } - return $this->_File->delete(); + return unlink($this->_File->getRealPath()); } /** @@ -208,20 +205,19 @@ class FileEngine extends CacheEngine { continue; } if ($check) { - $mtime = $this->_File->lastChange(); + $mtime = $this->_File->getMTime(); - if ($mtime === false || $mtime > $threshold) { + if ($mtime > $threshold) { continue; } - $expires = $this->_File->read(11); - $this->_File->close(); + $expires = (int)$this->_File->current(); if ($expires > $now) { continue; } } - $this->_File->delete(); + unlink($this->_File->getRealPath()); } $dir->close(); return true; @@ -252,27 +248,29 @@ class FileEngine extends CacheEngine { * * @param string $key The key * @return mixed Absolute cache file for the given key or false if erroneous - * @access private + * @access protected */ - function _setKey($key) { - $this->_File->Folder->cd($this->settings['path']); - if ($key !== $this->_File->name) { - $this->_File->name = $key; - $this->_File->path = null; - } - if (!$this->_File->Folder->inPath($this->_File->pwd(), true)) { + protected function _setKey($key, $createKey = false) { + $path = new SplFileInfo($this->settings['path'] . DS . $key); + + if (!$createKey && !$path->isFile()) { return false; } + + if (empty($this->_File) || $this->_File->getBaseName() !== $key) { + $this->_File = $path->openFile('a+'); + } } /** * Determine is cache directory is writable * * @return boolean - * @access private + * @access protected */ - function __active() { - if ($this->_init && !is_writable($this->settings['path'])) { + protected function _active() { + $dir = new SplFileInfo($this->settings['path']); + if ($this->_init && !($dir->isDir() && $dir->isWritable())) { $this->_init = false; trigger_error(sprintf(__('%s is not writable'), $this->settings['path']), E_USER_WARNING); } From a6f60c1abb4842c1d66a022fb76c05c9d28cd08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lorenzo=20Rodr=C3=ADguez?= Date: Mon, 26 Apr 2010 21:42:16 -0430 Subject: [PATCH 18/28] Implementing cache lockig in FileEngine using SplFileObject --- cake/libs/cache/file.php | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/cake/libs/cache/file.php b/cake/libs/cache/file.php index 9e54dfdd1..9b004c1ed 100644 --- a/cake/libs/cache/file.php +++ b/cake/libs/cache/file.php @@ -19,9 +19,6 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ -if (!class_exists('File')) { - require LIBS . 'file.php'; -} /** * File Storage engine for cache * @@ -32,9 +29,9 @@ if (!class_exists('File')) { class FileEngine extends CacheEngine { /** - * Instance of File class + * Instance of SplFileObject class * - * @var File + * @var _File * @access protected */ protected $_File = null; @@ -126,11 +123,17 @@ class FileEngine extends CacheEngine { } if ($this->settings['lock']) { - //$this->_File->lock = true; + $this->_File->flock(LOCK_EX); } + $expires = time() + $duration; $contents = $expires . $lineBreak . $data . $lineBreak; $success = $this->_File->ftruncate(0) && $this->_File->fwrite($contents); + + if ($this->settings['lock']) { + $this->_File->flock(LOCK_EX); + } + return $success; } @@ -144,9 +147,11 @@ class FileEngine extends CacheEngine { if (!$this->_init || $this->_setKey($key) === false) { return false; } + if ($this->settings['lock']) { - //$this->_File->lock = true; + $this->_File->flock(LOCK_SH); } + $this->_File->rewind(); $time = time(); $cachetime = intval($this->_File->current()); @@ -161,6 +166,11 @@ class FileEngine extends CacheEngine { $data .= $this->_File->current(); $this->_File->next(); } + + if ($this->settings['lock']) { + $this->_File->flock(LOCK_SH); + } + $data = trim($data); if ($data !== '' && !empty($this->settings['serialize'])) { @@ -244,10 +254,11 @@ class FileEngine extends CacheEngine { } /** - * Get absolute file for a given key + * Sets the current cache key this class is managing * * @param string $key The key - * @return mixed Absolute cache file for the given key or false if erroneous + * @param boolean $createKey Whether the key should be created if it doesn't exists, or not + * @return boolean true if the cache key could be set, false otherwise * @access protected */ protected function _setKey($key, $createKey = false) { @@ -260,6 +271,8 @@ class FileEngine extends CacheEngine { if (empty($this->_File) || $this->_File->getBaseName() !== $key) { $this->_File = $path->openFile('a+'); } + + return true; } /** From 6d092552e52afde662bce11f309dd7faab91b262 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Wed, 28 Apr 2010 23:56:07 -0400 Subject: [PATCH 19/28] Updating bake templates and Scaffold to use less sprintf() and more complete sentences in i18n strings. This should make translations easier to do in a gender correct way. Fixes #210 --- .../default/actions/controller_actions.ctp | 32 +++++++++---------- cake/console/templates/default/views/form.ctp | 8 ++--- .../console/templates/default/views/index.ctp | 10 +++--- cake/console/templates/default/views/view.ctp | 20 ++++++------ cake/libs/controller/scaffold.php | 30 ++++++++--------- 5 files changed, 50 insertions(+), 50 deletions(-) diff --git a/cake/console/templates/default/actions/controller_actions.ctp b/cake/console/templates/default/actions/controller_actions.ctp index 4be40637f..4dd9d23d2 100644 --- a/cake/console/templates/default/actions/controller_actions.ctp +++ b/cake/console/templates/default/actions/controller_actions.ctp @@ -27,10 +27,10 @@ function view($id = null) { if (!$id) { - $this->Session->setFlash(sprintf(__('Invalid %s', true), '')); + $this->Session->setFlash(__('Invalid ', true)); $this->redirect(array('action' => 'index')); - $this->flash(sprintf(__('Invalid %s', true), ''), array('action' => 'index')); + $this->flash(__('Invalid ', true), array('action' => 'index')); } $this->set('', $this->->read(null, $id)); @@ -42,14 +42,14 @@ $this->->create(); if ($this->->save($this->data)) { - $this->Session->setFlash(sprintf(__('The %s has been saved', true), '')); + $this->Session->setFlash(__('The has been saved', true)); $this->redirect(array('action' => 'index')); - $this->flash(sprintf(__('%s saved.', true), ''), array('action' => 'index')); + $this->flash(__(' saved.', true), array('action' => 'index')); } else { - $this->Session->setFlash(sprintf(__('The %s could not be saved. Please, try again.', true), '')); + $this->Session->setFlash(__('The could not be saved. Please, try again.', true)); } } @@ -74,23 +74,23 @@ function edit($id = null) { if (!$id && empty($this->data)) { - $this->Session->setFlash(sprintf(__('Invalid %s', true), '')); + $this->Session->setFlash(__('Invalid ', true)); $this->redirect(array('action' => 'index')); - $this->flash(sprintf(__('Invalid %s', true), ''), array('action' => 'index')); + $this->flash(sprintf(__('Invalid ', true)), array('action' => 'index')); } if (!empty($this->data)) { if ($this->->save($this->data)) { - $this->Session->setFlash(sprintf(__('The %s has been saved', true), '')); + $this->Session->setFlash(__('The has been saved', true)); $this->redirect(array('action' => 'index')); - $this->flash(sprintf(__('The %s has been saved.', true), ''), array('action' => 'index')); + $this->flash(__('The has been saved.', true), array('action' => 'index')); } else { - $this->Session->setFlash(sprintf(__('The %s could not be saved. Please, try again.', true), '')); + $this->Session->setFlash(__('The could not be saved. Please, try again.', true)); } } @@ -117,24 +117,24 @@ function delete($id = null) { if (!$id) { - $this->Session->setFlash(sprintf(__('Invalid id for %s', true), '')); + $this->Session->setFlash(__('Invalid id for ', true)); $this->redirect(array('action'=>'index')); - $this->flash(sprintf(__('Invalid %s', true), ''), array('action' => 'index')); + $this->flash(sprintf(__('Invalid ', true)), array('action' => 'index')); } if ($this->->delete($id)) { - $this->Session->setFlash(sprintf(__('%s deleted', true), '')); + $this->Session->setFlash(__(' deleted', true)); $this->redirect(array('action'=>'index')); - $this->flash(sprintf(__('%s deleted', true), ''), array('action' => 'index')); + $this->flash(__(' deleted', true), array('action' => 'index')); } - $this->Session->setFlash(sprintf(__('%s was not deleted', true), '')); + $this->Session->setFlash(__(' was not deleted', true)); - $this->flash(sprintf(__('%s was not deleted', true), ''), array('action' => 'index')); + $this->flash(__(' was not deleted', true), array('action' => 'index')); $this->redirect(array('action' => 'index')); } \ No newline at end of file diff --git a/cake/console/templates/default/views/form.ctp b/cake/console/templates/default/views/form.ctp index 218290ecf..4d986a748 100644 --- a/cake/console/templates/default/views/form.ctp +++ b/cake/console/templates/default/views/form.ctp @@ -20,7 +20,7 @@
    Form->create('{$modelClass}');?>\n";?>
    - ";?> + ", Inflector::humanize($action), $singularHumanName); ?>
  • Html->link(__('Delete', true), array('action' => 'delete', \$this->Form->value('{$modelClass}.{$primaryKey}')), null, sprintf(__('Are you sure you want to delete # %s?', true), \$this->Form->value('{$modelClass}.{$primaryKey}'))); ?>";?>
  • -
  • Html->link(sprintf(__('List %s', true), __('{$pluralHumanName}', true)), array('action' => 'index'));?>";?>
  • +
  • Html->link(__('List " . $pluralHumanName . "', true), array('action' => 'index'));?>";?>
  • $data) { foreach ($data as $alias => $details) { if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) { - echo "\t\t
  • Html->link(sprintf(__('List %s', true), __('" . Inflector::humanize($details['controller']) . "', true)), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
  • \n"; - echo "\t\t
  • Html->link(sprintf(__('New %s', true), __('" . Inflector::humanize(Inflector::underscore($alias)) . "', true)), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
  • \n"; + echo "\t\t
  • Html->link(__('List " . Inflector::humanize($details['controller']) . "', true), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
  • \n"; + echo "\t\t
  • Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "', true), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
  • \n"; $done[] = $details['controller']; } } diff --git a/cake/console/templates/default/views/index.ctp b/cake/console/templates/default/views/index.ctp index 35e059b8c..c71987b97 100644 --- a/cake/console/templates/default/views/index.ctp +++ b/cake/console/templates/default/views/index.ctp @@ -71,22 +71,22 @@

    - Paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?>\n";?> + Paginator->prev('<< ' . __('previous', true), array(), null, array('class'=>'disabled'));?>\n";?> | Paginator->numbers();?>\n"?> | - Paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>\n";?> + Paginator->next(__('next', true) . ' >>', array(), null, array('class' => 'disabled'));?>\n";?>

    "; ?>

      -
    • Html->link(sprintf(__('New %s', true), __('{$singularHumanName}', true)), array('action' => 'add')); ?>";?>
    • +
    • Html->link(__('New " . $singularHumanName . "', true), array('action' => 'add')); ?>";?>
    • $data) { foreach ($data as $alias => $details) { if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) { - echo "\t\t
    • Html->link(sprintf(__('List %s', true), __('" . Inflector::humanize($details['controller']) . "', true)), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
    • \n"; - echo "\t\t
    • Html->link(sprintf(__('New %s', true), __('" . Inflector::humanize(Inflector::underscore($alias)) . "', true)), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
    • \n"; + echo "\t\t
    • Html->link(__('List " . Inflector::humanize($details['controller']) . "', true), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
    • \n"; + echo "\t\t
    • Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "', true), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
    • \n"; $done[] = $details['controller']; } } diff --git a/cake/console/templates/default/views/view.ctp b/cake/console/templates/default/views/view.ctp index 545ea10f1..e9934cfa5 100644 --- a/cake/console/templates/default/views/view.ctp +++ b/cake/console/templates/default/views/view.ctp @@ -45,17 +45,17 @@ foreach ($fields as $field) {

      "; ?>

        Html->link(sprintf(__('Edit %s', true), __('{$singularHumanName}', true)), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?> \n"; - echo "\t\t
      • Html->link(sprintf(__('Delete %s', true), __('{$singularHumanName}', true)), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, sprintf(__('Are you sure you want to delete # %s?', true), \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
      • \n"; - echo "\t\t
      • Html->link(sprintf(__('List %s', true), __('{$pluralHumanName}', true)), array('action' => 'index')); ?>
      • \n"; - echo "\t\t
      • Html->link(sprintf(__('New %s', true), __('{$singularHumanName}', true)), array('action' => 'add')); ?>
      • \n"; + echo "\t\t
      • Html->link(__('Edit " . $singularHumanName ."', true), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
      • \n"; + echo "\t\t
      • Html->link(__('Delete " . $singularHumanName . "', true), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, sprintf(__('Are you sure you want to delete # %s?', true), \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
      • \n"; + echo "\t\t
      • Html->link(__('List " . $pluralHumanName . "', true), array('action' => 'index')); ?>
      • \n"; + echo "\t\t
      • Html->link(__('New " . $singularHumanName . "', true), array('action' => 'add')); ?>
      • \n"; $done = array(); foreach ($associations as $type => $data) { foreach ($data as $alias => $details) { if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) { - echo "\t\t
      • Html->link(sprintf(__('List %s', true), __('" . Inflector::humanize($details['controller']) . "', true)), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
      • \n"; - echo "\t\t
      • Html->link(sprintf(__('New %s', true), __('" . Inflector::humanize(Inflector::underscore($alias)) . "', true)), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
      • \n"; + echo "\t\t
      • Html->link(__('List " . Inflector::humanize($details['controller']) . "', true), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
      • \n"; + echo "\t\t
      • Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "', true), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
      • \n"; $done[] = $details['controller']; } } @@ -67,7 +67,7 @@ foreach ($fields as $field) { if (!empty($associations['hasOne'])) : foreach ($associations['hasOne'] as $alias => $details): ?> @@ -100,7 +100,7 @@ foreach ($relations as $alias => $details): $otherPluralHumanName = Inflector::humanize($details['controller']); ?>