From a993a7a50d90d0beb1b292979f521626ee753cf4 Mon Sep 17 00:00:00 2001 From: Paul Redmond Date: Fri, 24 Aug 2012 23:11:25 -0700 Subject: [PATCH 01/20] Fixing typo in view property during unset() --- lib/Cake/View/View.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/View/View.php b/lib/Cake/View/View.php index 59ce0aca4..3ba3e5d2e 100644 --- a/lib/Cake/View/View.php +++ b/lib/Cake/View/View.php @@ -919,7 +919,7 @@ class View extends Object { include $this->__viewFile; - unset($this->_viewFile); + unset($this->__viewFile); return ob_get_clean(); } From 60eb228ddf9277f64e38d2914bd74e6f2d2f8ee2 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sat, 25 Aug 2012 13:29:16 +0200 Subject: [PATCH 02/20] Fixing issues with validation rules not being reset after calling create() on the model or when calling validates() multiple times This had interesting side effects when deep saving --- lib/Cake/Model/Validator/CakeValidationRule.php | 11 +++++++++++ lib/Cake/Model/Validator/CakeValidationSet.php | 12 ++++++++++++ lib/Cake/Test/Case/Model/ModelWriteTest.php | 6 +----- lib/Cake/Test/Case/Model/models.php | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Model/Validator/CakeValidationRule.php b/lib/Cake/Model/Validator/CakeValidationRule.php index 8ebf82589..a59a01c7b 100644 --- a/lib/Cake/Model/Validator/CakeValidationRule.php +++ b/lib/Cake/Model/Validator/CakeValidationRule.php @@ -282,6 +282,17 @@ class CakeValidationRule { return true; } +/** + * Resets interal state for this rule, by default it will become valid + * and it will set isUpdate() to false + * + * @return void + **/ + public function reset() { + $this->_valid = true; + $this->_recordExists = false; + } + /** * Returns passed options for this rule * diff --git a/lib/Cake/Model/Validator/CakeValidationSet.php b/lib/Cake/Model/Validator/CakeValidationSet.php index fdecdc191..1cd32c617 100644 --- a/lib/Cake/Model/Validator/CakeValidationSet.php +++ b/lib/Cake/Model/Validator/CakeValidationSet.php @@ -117,6 +117,7 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable { * @return array list of validation errors for this field */ public function validate($data, $isUpdate = false) { + $this->reset(); $errors = array(); foreach ($this->getRules() as $name => $rule) { $rule->isUpdate($isUpdate); @@ -143,6 +144,17 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable { return $errors; } +/** + * Resets interal state for all validation rules in this set + * + * @return void + **/ + public function reset() { + foreach ($this->getRules() as $rule) { + $rule->reset(); + } + } + /** * Gets a rule for a given name if exists * diff --git a/lib/Cake/Test/Case/Model/ModelWriteTest.php b/lib/Cake/Test/Case/Model/ModelWriteTest.php index d46a6db27..f8601f4a9 100644 --- a/lib/Cake/Test/Case/Model/ModelWriteTest.php +++ b/lib/Cake/Test/Case/Model/ModelWriteTest.php @@ -3242,7 +3242,6 @@ class ModelWriteTest extends BaseModelTest { ) ), 1 => array( - 'body' => array('This field cannot be left blank'), 'Comment' => array( 0 => array( 'User' => array( @@ -3687,9 +3686,6 @@ class ModelWriteTest extends BaseModelTest { $expected = array( 0 => array( 'body' => array('This field cannot be left blank') - ), - 1 => array( - 'body' => array('This field cannot be left blank') ) ); $result = $TestModel->validationErrors; @@ -3703,7 +3699,7 @@ class ModelWriteTest extends BaseModelTest { ) ), array( - 'Article' => array('id' => 2, 'body' => 'Same here'), + 'Article' => array('id' => 2), 'Comment' => array( array('comment' => '', 'published' => 'Y', 'user_id' => 2) ) diff --git a/lib/Cake/Test/Case/Model/models.php b/lib/Cake/Test/Case/Model/models.php index b550a0ac6..b86a4b583 100644 --- a/lib/Cake/Test/Case/Model/models.php +++ b/lib/Cake/Test/Case/Model/models.php @@ -276,7 +276,7 @@ class Article extends CakeTestModel { public $validate = array( 'user_id' => 'numeric', 'title' => array('required' => false, 'rule' => 'notEmpty'), - 'body' => 'notEmpty', + 'body' => array('required' => false, 'rule' => 'notEmpty'), ); /** From f6278488af024c305a64048d4c0264e1160b8d80 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sat, 25 Aug 2012 14:05:19 +0200 Subject: [PATCH 03/20] Ensuring list of behavior methods are refreshed between calls of validates() in the model, fixes #3071 --- lib/Cake/Model/ModelValidator.php | 26 ++++++++++++++--- .../Test/Case/Model/ModelValidationTest.php | 29 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/Cake/Model/ModelValidator.php b/lib/Cake/Model/ModelValidator.php index dbe58ceb9..1a1937939 100644 --- a/lib/Cake/Model/ModelValidator.php +++ b/lib/Cake/Model/ModelValidator.php @@ -63,6 +63,20 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable { */ protected $_methods = array(); +/** + * Holds the available custom callback methods from the model + * + * @var array + */ + protected $_modelMethods = array(); + +/** + * Holds the list of behavior names that were attached when this object was created + * + * @var array + */ + protected $_behaviors = array(); + /** * Constructor * @@ -280,15 +294,19 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable { * @return array List of callables to be used as validation methods */ public function getMethods() { - if (!empty($this->_methods)) { + $behaviors = $this->_model->Behaviors->enabled(); + if (!empty($this->_methods) && $behaviors === $this->_behaviors) { return $this->_methods; } + $this->_behaviors = $behaviors; - $methods = array(); - foreach (get_class_methods($this->_model) as $method) { - $methods[strtolower($method)] = array($this->_model, $method); + if (empty($this->_modelMethods)) { + foreach (get_class_methods($this->_model) as $method) { + $this->_modelMethods[strtolower($method)] = array($this->_model, $method); + } } + $methods = $this->_modelMethods; foreach (array_keys($this->_model->Behaviors->methods()) as $method) { $methods += array(strtolower($method) => array($this->_model, $method)); } diff --git a/lib/Cake/Test/Case/Model/ModelValidationTest.php b/lib/Cake/Test/Case/Model/ModelValidationTest.php index 713e578a7..6c6fdd914 100644 --- a/lib/Cake/Test/Case/Model/ModelValidationTest.php +++ b/lib/Cake/Test/Case/Model/ModelValidationTest.php @@ -1700,6 +1700,35 @@ class ModelValidationTest extends BaseModelTest { $this->assertEquals($expected, array_keys($result)); } +/** + * Tests that methods are refreshed when the list of behaviors change + * + * @return void + */ + public function testGetMethodsRefresh() { + $this->loadFixtures('Article', 'Comment'); + $TestModel = new Article(); + $Validator = $TestModel->validator(); + + $result = $Validator->getMethods(); + + $expected = array_map('strtolower', get_class_methods('Article')); + $this->assertEquals($expected, array_keys($result)); + + $TestModel->Behaviors->attach('Containable'); + $newList = array( + 'contain', + 'resetbindings', + 'containments', + 'fielddependencies', + 'containmentsmap' + ); + $this->assertEquals(array_merge($expected, $newList), array_keys($Validator->getMethods())); + + $TestModel->Behaviors->detach('Containable'); + $this->assertEquals($expected, array_keys($Validator->getMethods())); + } + /** * testSetValidationDomain method * From 7484007fa72b0b806b80e2fe590f99e37365a198 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sat, 25 Aug 2012 20:49:40 +0000 Subject: [PATCH 04/20] Fix #3148 MediaView does not support Microsoft Office default formats --- lib/Cake/Network/CakeResponse.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Cake/Network/CakeResponse.php b/lib/Cake/Network/CakeResponse.php index 7f8ea4507..79be981ac 100644 --- a/lib/Cake/Network/CakeResponse.php +++ b/lib/Cake/Network/CakeResponse.php @@ -98,6 +98,7 @@ class CakeResponse { 'dir' => 'application/x-director', 'dms' => 'application/octet-stream', 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'drw' => 'application/drafting', 'dvi' => 'application/x-dvi', 'dwg' => 'application/acad', @@ -134,6 +135,7 @@ class CakeResponse { 'pot' => 'application/vnd.ms-powerpoint', 'pps' => 'application/vnd.ms-powerpoint', 'ppt' => 'application/vnd.ms-powerpoint', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'ppz' => 'application/vnd.ms-powerpoint', 'pre' => 'application/x-freelance', 'prt' => 'application/pro_eng', @@ -178,6 +180,7 @@ class CakeResponse { 'xll' => 'application/vnd.ms-excel', 'xlm' => 'application/vnd.ms-excel', 'xls' => 'application/vnd.ms-excel', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlw' => 'application/vnd.ms-excel', 'zip' => 'application/zip', 'aif' => 'audio/x-aiff', From 6c4ba233baefa0ea6b8e3f68d2e9a1c9c104703a Mon Sep 17 00:00:00 2001 From: James Hall Date: Sun, 26 Aug 2012 00:23:32 +0100 Subject: [PATCH 05/20] Fix testSendRenderWithImage when non running on port 80 --- lib/Cake/Test/Case/Network/Email/CakeEmailTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index cde649558..872dbfef3 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1118,8 +1118,12 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->config(array('empty')); $this->CakeEmail->template('image'); $this->CakeEmail->emailFormat('html'); - $server = env('SERVER_NAME') ? env('SERVER_NAME') : 'localhost'; + + if (env('SERVER_PORT') != 80) { + $server .= ':' . env('SERVER_PORT'); + } + $expected = 'cool image'; $result = $this->CakeEmail->send(); $this->assertContains($expected, $result['message']); From a3b5065f8a7e76828596168c91202873b3280ad1 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sun, 26 Aug 2012 00:33:32 +0100 Subject: [PATCH 06/20] Make sure the environment variable is set --- lib/Cake/Test/Case/Network/Email/CakeEmailTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index 872dbfef3..912f3fa4e 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1119,8 +1119,8 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->template('image'); $this->CakeEmail->emailFormat('html'); $server = env('SERVER_NAME') ? env('SERVER_NAME') : 'localhost'; - - if (env('SERVER_PORT') != 80) { + + if (env('SERVER_PORT') != NULL && env('SERVER_PORT') != 80) { $server .= ':' . env('SERVER_PORT'); } From 20baeb83db292ef8989a092818540091f5791674 Mon Sep 17 00:00:00 2001 From: James Hall Date: Sun, 26 Aug 2012 02:11:43 +0100 Subject: [PATCH 07/20] Change to match coding standards --- lib/Cake/Test/Case/Network/Email/CakeEmailTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php index 912f3fa4e..cefef163c 100644 --- a/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php +++ b/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php @@ -1120,7 +1120,7 @@ class CakeEmailTest extends CakeTestCase { $this->CakeEmail->emailFormat('html'); $server = env('SERVER_NAME') ? env('SERVER_NAME') : 'localhost'; - if (env('SERVER_PORT') != NULL && env('SERVER_PORT') != 80) { + if (env('SERVER_PORT') != null && env('SERVER_PORT') != 80) { $server .= ':' . env('SERVER_PORT'); } From b68a2ed84da6fe7025f2992c9345107ecfcf9160 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 26 Aug 2012 22:15:04 -0400 Subject: [PATCH 08/20] Update API docs. --- lib/Cake/Utility/CakeTime.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/Cake/Utility/CakeTime.php b/lib/Cake/Utility/CakeTime.php index 4788d53f0..67e9cc342 100644 --- a/lib/Cake/Utility/CakeTime.php +++ b/lib/Cake/Utility/CakeTime.php @@ -923,13 +923,16 @@ class CakeTime { * This function also accepts a time string and a format string as first and second parameters. * In that case this function behaves as a wrapper for TimeHelper::i18nFormat() * - * ## Examples: - * {{{ - * CakeTime::format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012 - * CakeTime::format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale - * CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed - * CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone - * }}} + * ## Examples + * + * Create localized & formatted time: + * + * {{{ + * CakeTime::format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012 + * CakeTime::format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale + * CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed + * CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone + * }}} * * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string) * @param integer|string|DateTime $format date format string (or UNIX timestamp, strtotime() valid string or DateTime object) @@ -937,6 +940,7 @@ class CakeTime { * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object * @return string Formatted date string * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + * @see CakeTime::i18nFormat() */ public static function format($date, $format = null, $default = false, $timezone = null) { //Backwards compatible params order From cbb64bd08204c2d23888e07d51f201b58a2c9f37 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 26 Aug 2012 22:53:48 -0400 Subject: [PATCH 09/20] Fix blackhole requests with empty select boxes. When a select box was entirely empty (no option element) secured form submission should not fail. Fixes #3153 --- .../Test/Case/View/Helper/FormHelperTest.php | 24 +++++++++++++++++++ lib/Cake/View/Helper/FormHelper.php | 9 +++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 69f709910..0b964cc20 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -4256,6 +4256,30 @@ class FormHelperTest extends CakeTestCase { $this->assertRegExp('/"' . $key . '"/', $result); } +/** + * When a select box has no options it should not be added to the fields list + * as it always fail post validation. + * + * @return void + */ + public function testSelectNoSecureWithNoOptions() { + $this->Form->request['_Token'] = array('key' => 'testkey'); + $this->assertEquals(array(), $this->Form->fields); + + $this->Form->select( + 'Model.select', + array() + ); + $this->assertEquals(array(), $this->Form->fields); + + $this->Form->select( + 'Model.select', + array(), + array('empty' => true) + ); + $this->assertEquals(array('Model.select'), $this->Form->fields); + } + /** * testInputMultipleCheckboxes method * diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index c9e193017..17b0569a5 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -817,7 +817,7 @@ class FormHelper extends AppHelper { * - `fieldset` Set to false to disable the fieldset. If a string is supplied it will be used as * the classname for the fieldset element. * - `legend` Set to false to disable the legend for the generated input set. Or supply a string - * to customize the legend text. + * to customize the legend text. * * @param array $fields An array of fields to generate inputs for, or null. * @param array $blacklist a simple array of fields to not create inputs for. @@ -1843,7 +1843,12 @@ class FormHelper extends AppHelper { } if (!empty($tag) || isset($template)) { - if ((!isset($secure) || $secure == true) && empty($attributes['disabled'])) { + $hasOptions = (count($options) > 0 || $showEmpty); + if ( + (!isset($secure) || $secure == true) && + empty($attributes['disabled']) && + $hasOptions + ) { $this->_secure(true); } $select[] = $this->Html->useTag($tag, $attributes['name'], array_diff_key($attributes, array('name' => '', 'value' => ''))); From bdac857293144ff144ae26089b6741b982181d08 Mon Sep 17 00:00:00 2001 From: Ber Clausen Date: Sun, 26 Aug 2012 21:02:09 -0300 Subject: [PATCH 10/20] Add plugin support to IniReader, and harden tests. The actual config file must always have .ini extension. For backwards compatibility, acl.ini.php will be treated specially until 3.0. --- lib/Cake/Configure/IniReader.php | 43 +++-- .../Test/Case/Configure/IniReaderTest.php | 149 +++++++++++++++--- lib/Cake/Test/test_app/Config/acl.ini | 60 +++++++ lib/Cake/Test/test_app/Config/empty.ini | 1 + .../Test/test_app/Config/no_ini_extension | 3 + .../Plugin/TestPlugin/Config/acl.ini.php | 60 +++++++ .../Plugin/TestPlugin/Config/nested.ini | 4 + 7 files changed, 286 insertions(+), 34 deletions(-) create mode 100644 lib/Cake/Test/test_app/Config/acl.ini create mode 100644 lib/Cake/Test/test_app/Config/empty.ini create mode 100644 lib/Cake/Test/test_app/Config/no_ini_extension create mode 100644 lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php create mode 100644 lib/Cake/Test/test_app/Plugin/TestPlugin/Config/nested.ini diff --git a/lib/Cake/Configure/IniReader.php b/lib/Cake/Configure/IniReader.php index f8fe2077f..900d65489 100644 --- a/lib/Cake/Configure/IniReader.php +++ b/lib/Cake/Configure/IniReader.php @@ -84,20 +84,41 @@ class IniReader implements ConfigReaderInterface { /** * Read an ini file and return the results as an array. * - * @param string $file Name of the file to read. The chosen file - * must be on the reader's path. - * @return array + * For backwards compatibility, acl.ini.php will be treated specially until 3.0. + * + * @param string $key The identifier to read from. If the key has a . it will be treated + * as a plugin prefix. The chosen file must be on the reader's path. + * @return array Parsed configuration values. + * @throws ConfigureException when files don't exist. + * Or when files contain '..' as this could lead to abusive reads. * @throws ConfigureException */ - public function read($file) { - $filename = $this->_path . $file; - if (!file_exists($filename)) { - $filename .= '.ini'; - if (!file_exists($filename)) { - throw new ConfigureException(__d('cake_dev', 'Could not load configuration files: %s or %s', substr($filename, 0, -4), $filename)); - } + public function read($key) { + if (strpos($key, '..') !== false) { + throw new ConfigureException(__d('cake_dev', 'Cannot load configuration files with ../ in them.')); } - $contents = parse_ini_file($filename, true); + if (substr($key, -8) === '.ini.php') { + $key = substr($key, 0, -8); + list($plugin, $key) = pluginSplit($key); + $key .= '.ini.php'; + } else { + if (substr($key, -4) === '.ini') { + $key = substr($key, 0, -4); + } + list($plugin, $key) = pluginSplit($key); + $key .= '.ini'; + } + + if ($plugin) { + $file = App::pluginPath($plugin) . 'Config' . DS . $key; + } else { + $file = $this->_path . $key; + } + if (!is_file($file)) { + throw new ConfigureException(__d('cake_dev', 'Could not load configuration file: %s', $file)); + } + + $contents = parse_ini_file($file, true); if (!empty($this->_section) && isset($contents[$this->_section])) { $values = $this->_parseNestedValues($contents[$this->_section]); } else { diff --git a/lib/Cake/Test/Case/Configure/IniReaderTest.php b/lib/Cake/Test/Case/Configure/IniReaderTest.php index dd1f087b4..5bbbe57c1 100644 --- a/lib/Cake/Test/Case/Configure/IniReaderTest.php +++ b/lib/Cake/Test/Case/Configure/IniReaderTest.php @@ -56,6 +56,47 @@ class IniReaderTest extends CakeTestCase { * @return void */ public function testConstruct() { + $reader = new IniReader($this->path); + $config = $reader->read('acl.ini'); + + $this->assertTrue(isset($config['admin'])); + $this->assertTrue(isset($config['paul']['groups'])); + $this->assertEquals('ads', $config['admin']['deny']); + } + +/** + * Test reading files. + * + * @return void + */ + public function testRead() { + $reader = new IniReader($this->path); + $config = $reader->read('nested'); + $this->assertTrue($config['bools']['test_on']); + + $config = $reader->read('nested.ini'); + $this->assertTrue($config['bools']['test_on']); + } + +/** + * No other sections should exist. + * + * @return void + */ + public function testReadOnlyOneSection() { + $reader = new IniReader($this->path, 'admin'); + $config = $reader->read('acl.ini'); + + $this->assertTrue(isset($config['groups'])); + $this->assertEquals('administrators', $config['groups']); + } + +/** + * Test reading acl.ini.php. + * + * @return void + */ + public function testReadSpecialAclIniPhp() { $reader = new IniReader($this->path); $config = $reader->read('acl.ini.php'); @@ -65,24 +106,11 @@ class IniReaderTest extends CakeTestCase { } /** - * no other sections should exist. + * Test without section. * * @return void */ - public function testReadingOnlyOneSection() { - $reader = new IniReader($this->path, 'admin'); - $config = $reader->read('acl.ini.php'); - - $this->assertTrue(isset($config['groups'])); - $this->assertEquals('administrators', $config['groups']); - } - -/** - * test without section - * - * @return void - */ - public function testReadingWithoutSection() { + public function testReadWithoutSection() { $reader = new IniReader($this->path); $config = $reader->read('no_section.ini'); @@ -94,11 +122,11 @@ class IniReaderTest extends CakeTestCase { } /** - * test that names with .'s get exploded into arrays. + * Test that names with .'s get exploded into arrays. * * @return void */ - public function testReadingValuesWithDots() { + public function testReadValuesWithDots() { $reader = new IniReader($this->path); $config = $reader->read('nested.ini'); @@ -110,7 +138,7 @@ class IniReaderTest extends CakeTestCase { } /** - * test boolean reading + * Test boolean reading. * * @return void */ @@ -131,18 +159,93 @@ class IniReaderTest extends CakeTestCase { } /** - * test read file without extension + * Test an exception is thrown by reading files that exist without .ini extension. * + * @expectedException ConfigureException * @return void */ - public function testReadingWithoutExtension() { + public function testReadWithExistentFileWithoutExtension() { $reader = new IniReader($this->path); - $config = $reader->read('nested'); - $this->assertTrue($config['bools']['test_on']); + $reader->read('no_ini_extension'); } /** - * test dump method. + * Test an exception is thrown by reading files that don't exist. + * + * @expectedException ConfigureException + * @return void + */ + public function testReadWithNonExistentFile() { + $reader = new IniReader($this->path); + $reader->read('fake_values'); + } + +/** + * Test reading an empty file. + * + * @return void + */ + public function testReadEmptyFile() { + $reader = new IniReader($this->path); + $config = $reader->read('empty'); + $this->assertEquals(array(), $config); + } + +/** + * Test reading keys with ../ doesn't work. + * + * @expectedException ConfigureException + * @return void + */ + public function testReadWithDots() { + $reader = new IniReader($this->path); + $reader->read('../empty'); + } + +/** + * Test reading from plugins. + * + * @return void + */ + public function testReadPluginValue() { + App::build(array( + 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS) + ), App::RESET); + CakePlugin::load('TestPlugin'); + $reader = new IniReader($this->path); + $result = $reader->read('TestPlugin.nested'); + + $this->assertTrue(isset($result['database']['db']['username'])); + $this->assertEquals('bar', $result['database']['db']['username']); + $this->assertFalse(isset($result['database.db.username'])); + $this->assertFalse(isset($result['database']['db.username'])); + + $result = $reader->read('TestPlugin.nested.ini'); + $this->assertEquals('foo', $result['database']['db']['password']); + CakePlugin::unload(); + } + +/** + * Test reading acl.ini.php from plugins. + * + * @return void + */ + public function testReadPluginSpecialAclIniPhpValue() { + App::build(array( + 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS) + ), App::RESET); + CakePlugin::load('TestPlugin'); + $reader = new IniReader($this->path); + $result = $reader->read('TestPlugin.acl.ini.php'); + + $this->assertTrue(isset($result['admin'])); + $this->assertTrue(isset($result['paul']['groups'])); + $this->assertEquals('ads', $result['admin']['deny']); + CakePlugin::unload(); + } + +/** + * Test dump method. * * @return void */ diff --git a/lib/Cake/Test/test_app/Config/acl.ini b/lib/Cake/Test/test_app/Config/acl.ini new file mode 100644 index 000000000..b9215b4ca --- /dev/null +++ b/lib/Cake/Test/test_app/Config/acl.ini @@ -0,0 +1,60 @@ +; +; SVN FILE: $Id$ +;/** +; * Test App Ini Based Acl Config File +; * +; * +; * PHP 5 +; * +; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) +; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) +; * +; * Licensed under The MIT License +; * Redistributions of files must retain the above copyright notice. +; * +; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) +; * @link http://cakephp.org CakePHP(tm) Project +;; * @package Cake.Test.test_app.Config +; * @since CakePHP(tm) v 0.10.0.1076 +; * @license MIT License (http://www.opensource.org/licenses/mit-license.php) +; */ + +;------------------------------------- +;Users +;------------------------------------- + +[admin] +groups = administrators +allow = +deny = ads + +[paul] +groups = users +allow = +deny = + +[jenny] +groups = users +allow = ads +deny = images, files + +[nobody] +groups = anonymous +allow = +deny = + +;------------------------------------- +;Groups +;------------------------------------- + +[administrators] +deny = +allow = posts, comments, images, files, stats, ads + +[users] +allow = posts, comments, images, files +deny = stats, ads + +[anonymous] +allow = +deny = posts, comments, images, files, stats, ads diff --git a/lib/Cake/Test/test_app/Config/empty.ini b/lib/Cake/Test/test_app/Config/empty.ini new file mode 100644 index 000000000..15623bc79 --- /dev/null +++ b/lib/Cake/Test/test_app/Config/empty.ini @@ -0,0 +1 @@ +; do nothing this is an empty file. diff --git a/lib/Cake/Test/test_app/Config/no_ini_extension b/lib/Cake/Test/test_app/Config/no_ini_extension new file mode 100644 index 000000000..12f09f056 --- /dev/null +++ b/lib/Cake/Test/test_app/Config/no_ini_extension @@ -0,0 +1,3 @@ +; Test file for testing config file without .ini extension. +some_key = some_value +bool_key = 1 diff --git a/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php b/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php new file mode 100644 index 000000000..b9215b4ca --- /dev/null +++ b/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php @@ -0,0 +1,60 @@ +; +; SVN FILE: $Id$ +;/** +; * Test App Ini Based Acl Config File +; * +; * +; * PHP 5 +; * +; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) +; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) +; * +; * Licensed under The MIT License +; * Redistributions of files must retain the above copyright notice. +; * +; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) +; * @link http://cakephp.org CakePHP(tm) Project +;; * @package Cake.Test.test_app.Config +; * @since CakePHP(tm) v 0.10.0.1076 +; * @license MIT License (http://www.opensource.org/licenses/mit-license.php) +; */ + +;------------------------------------- +;Users +;------------------------------------- + +[admin] +groups = administrators +allow = +deny = ads + +[paul] +groups = users +allow = +deny = + +[jenny] +groups = users +allow = ads +deny = images, files + +[nobody] +groups = anonymous +allow = +deny = + +;------------------------------------- +;Groups +;------------------------------------- + +[administrators] +deny = +allow = posts, comments, images, files, stats, ads + +[users] +allow = posts, comments, images, files +deny = stats, ads + +[anonymous] +allow = +deny = posts, comments, images, files, stats, ads diff --git a/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/nested.ini b/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/nested.ini new file mode 100644 index 000000000..1ae279986 --- /dev/null +++ b/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/nested.ini @@ -0,0 +1,4 @@ +; Test file for testing ini files with . syntax +[database] +db.username = bar +db.password = foo From 988a847f491730356a802d1801a2c8ed62aff6a9 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 27 Aug 2012 14:48:07 -0400 Subject: [PATCH 11/20] Fix unescaped entities. --- lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php b/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php index 5bd2695ce..31bcab6d0 100644 --- a/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php +++ b/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php @@ -201,8 +201,8 @@ class CakeHtmlReporter extends CakeBaseReporter { $show = $this->_queryString($show); $query = $this->_queryString($query); - echo "

Run more tests | Show Passes | \n"; - echo "Enable Debug Output | \n"; + echo "

Run more tests | Show Passes | \n"; + echo "Enable Debug Output | \n"; echo "Analyze Code Coverage

\n"; } From fba17cffe969ab18ab5245bd97849d1ecd8a30e6 Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 27 Aug 2012 22:07:28 -0400 Subject: [PATCH 12/20] Move OptionParser initialization out of try block. This allows exceptions that result from creating the optionparser to display to the developer, making debugging easier. Fixes #3157 --- lib/Cake/Console/Shell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php index 801410ba5..74e5e033b 100644 --- a/lib/Cake/Console/Shell.php +++ b/lib/Cake/Console/Shell.php @@ -361,8 +361,8 @@ class Shell extends Object { array_shift($argv); } + $this->OptionParser = $this->getOptionParser(); try { - $this->OptionParser = $this->getOptionParser(); list($this->params, $this->args) = $this->OptionParser->parse($argv, $command); } catch (ConsoleException $e) { $this->out($this->OptionParser->help($command)); From b27c8a05bda2f87b9de5141e519743238168ad2e Mon Sep 17 00:00:00 2001 From: mark_story Date: Mon, 27 Aug 2012 22:12:05 -0400 Subject: [PATCH 13/20] Make invalid short option error more helpful. Refs #3157 --- lib/Cake/Console/ConsoleInputOption.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Cake/Console/ConsoleInputOption.php b/lib/Cake/Console/ConsoleInputOption.php index 9323c64f7..a6841fa16 100644 --- a/lib/Cake/Console/ConsoleInputOption.php +++ b/lib/Cake/Console/ConsoleInputOption.php @@ -93,7 +93,7 @@ class ConsoleInputOption { } if (strlen($this->_short) > 1) { throw new ConsoleException( - __d('cake_console', 'Short options must be one letter.') + __d('cake_console', 'Short option "%s" is invalid, short options must be one letter.', $this->_short) ); } } From 63548267e981b7dd2374850a91d4f2d08f713f8b Mon Sep 17 00:00:00 2001 From: Ber Clausen Date: Mon, 27 Aug 2012 22:16:33 -0300 Subject: [PATCH 14/20] Refactor Validator::decimal() to be more flexible with decimal separators and PHP magic. Lots of testing added. --- lib/Cake/Test/Case/Utility/ValidationTest.php | 108 ++++++++++++++---- lib/Cake/Utility/Validation.php | 40 +++++-- 2 files changed, 113 insertions(+), 35 deletions(-) diff --git a/lib/Cake/Test/Case/Utility/ValidationTest.php b/lib/Cake/Test/Case/Utility/ValidationTest.php index 6c87e08bf..d9886a663 100644 --- a/lib/Cake/Test/Case/Utility/ValidationTest.php +++ b/lib/Cake/Test/Case/Utility/ValidationTest.php @@ -1487,39 +1487,77 @@ class ValidationTest extends CakeTestCase { } /** - * testDecimal method + * Test numbers with any number of decimal places, including none. * * @return void */ - public function testDecimal() { - $this->assertTrue(Validation::decimal('+1234.54321')); - $this->assertTrue(Validation::decimal('-1234.54321')); - $this->assertTrue(Validation::decimal('1234.54321')); - $this->assertTrue(Validation::decimal('+0123.45e6')); - $this->assertTrue(Validation::decimal('-0123.45e6')); - $this->assertTrue(Validation::decimal('0123.45e6')); - $this->assertTrue(Validation::decimal(1234.56)); - $this->assertTrue(Validation::decimal(1234.00)); - $this->assertTrue(Validation::decimal('1234.00')); - $this->assertTrue(Validation::decimal(.0)); - $this->assertTrue(Validation::decimal(.00)); - $this->assertTrue(Validation::decimal('.00')); - $this->assertTrue(Validation::decimal(.01)); - $this->assertTrue(Validation::decimal('.01')); + public function testDecimalWithPlacesNull() { + $this->assertTrue(Validation::decimal('+1234.54321', null)); + $this->assertTrue(Validation::decimal('-1234.54321', null)); + $this->assertTrue(Validation::decimal('1234.54321', null)); + $this->assertTrue(Validation::decimal('+0123.45e6', null)); + $this->assertTrue(Validation::decimal('-0123.45e6', null)); + $this->assertTrue(Validation::decimal('0123.45e6', null)); + $this->assertTrue(Validation::decimal(1234.56, null)); + $this->assertTrue(Validation::decimal(1234.00, null)); + $this->assertTrue(Validation::decimal(1234., null)); + $this->assertTrue(Validation::decimal('1234.00', null)); + $this->assertTrue(Validation::decimal(.0, null)); + $this->assertTrue(Validation::decimal(.00, null)); + $this->assertTrue(Validation::decimal('.00', null)); + $this->assertTrue(Validation::decimal(.01, null)); + $this->assertTrue(Validation::decimal('.01', null)); + $this->assertTrue(Validation::decimal('1234', null)); + $this->assertTrue(Validation::decimal('-1234', null)); + $this->assertTrue(Validation::decimal('+1234', null)); + $this->assertTrue(Validation::decimal((float) 1234, null)); + $this->assertTrue(Validation::decimal((double) 1234, null)); + $this->assertTrue(Validation::decimal((int) 1234, null)); - $this->assertFalse(Validation::decimal('')); - $this->assertFalse(Validation::decimal('string')); - $this->assertFalse(Validation::decimal('1234')); - $this->assertFalse(Validation::decimal('-1234')); - $this->assertFalse(Validation::decimal('+1234')); + $this->assertFalse(Validation::decimal('', null)); + $this->assertFalse(Validation::decimal('string', null)); + $this->assertFalse(Validation::decimal('1234.', null)); } /** - * testDecimalWithPlaces method + * Test numbers with any number of decimal places greater than 0, or a float|double. * * @return void */ - public function testDecimalWithPlaces() { + public function testDecimalWithPlacesTrue() { + $this->assertTrue(Validation::decimal('+1234.54321', true)); + $this->assertTrue(Validation::decimal('-1234.54321', true)); + $this->assertTrue(Validation::decimal('1234.54321', true)); + $this->assertTrue(Validation::decimal('+0123.45e6', true)); + $this->assertTrue(Validation::decimal('-0123.45e6', true)); + $this->assertTrue(Validation::decimal('0123.45e6', true)); + $this->assertTrue(Validation::decimal(1234.56, true)); + $this->assertTrue(Validation::decimal(1234.00, true)); + $this->assertTrue(Validation::decimal(1234., true)); + $this->assertTrue(Validation::decimal('1234.00', true)); + $this->assertTrue(Validation::decimal(.0, true)); + $this->assertTrue(Validation::decimal(.00, true)); + $this->assertTrue(Validation::decimal('.00', true)); + $this->assertTrue(Validation::decimal(.01, true)); + $this->assertTrue(Validation::decimal('.01', true)); + $this->assertTrue(Validation::decimal((float) 1234, true)); + $this->assertTrue(Validation::decimal((double) 1234, true)); + + $this->assertFalse(Validation::decimal('', true)); + $this->assertFalse(Validation::decimal('string', true)); + $this->assertFalse(Validation::decimal('1234.', true)); + $this->assertFalse(Validation::decimal((int) 1234, true)); + $this->assertFalse(Validation::decimal('1234', true)); + $this->assertFalse(Validation::decimal('-1234', true)); + $this->assertFalse(Validation::decimal('+1234', true)); + } + +/** + * Test numbers with exactly that many number of decimal places. + * + * @return void + */ + public function testDecimalWithPlacesNumeric() { $this->assertTrue(Validation::decimal('.27', '2')); $this->assertTrue(Validation::decimal(0.27, 2)); $this->assertTrue(Validation::decimal(-0.27, 2)); @@ -1532,12 +1570,36 @@ class ValidationTest extends CakeTestCase { $this->assertTrue(Validation::decimal(1234.5678, 4)); $this->assertTrue(Validation::decimal(-1234.5678, 4)); $this->assertTrue(Validation::decimal(1234.5678, 4)); + $this->assertTrue(Validation::decimal('.00', 2)); + $this->assertTrue(Validation::decimal(.01, 2)); + $this->assertTrue(Validation::decimal('.01', 2)); + + $this->assertFalse(Validation::decimal('', 1)); + $this->assertFalse(Validation::decimal('string', 1)); + $this->assertFalse(Validation::decimal(1234., 1)); + $this->assertFalse(Validation::decimal('1234.', 1)); + $this->assertFalse(Validation::decimal(.0, 1)); + $this->assertFalse(Validation::decimal(.00, 2)); + $this->assertFalse(Validation::decimal((float) 1234, 1)); + $this->assertFalse(Validation::decimal((double) 1234, 1)); + $this->assertFalse(Validation::decimal((int) 1234, 1)); $this->assertFalse(Validation::decimal('1234.5678', '3')); $this->assertFalse(Validation::decimal(1234.5678, 3)); $this->assertFalse(Validation::decimal(-1234.5678, 3)); $this->assertFalse(Validation::decimal(1234.5678, 3)); } +/** + * Test decimal() with invalid places parameter. + * + * @return void + */ + public function testDecimalWithInvalidPlaces() { + $this->assertFalse(Validation::decimal('.27', 'string')); + $this->assertFalse(Validation::decimal(1234.5678, (array) true)); + $this->assertFalse(Validation::decimal(-1234.5678, (object) true)); + } + /** * testDecimalCustomRegex method * diff --git a/lib/Cake/Utility/Validation.php b/lib/Cake/Utility/Validation.php index bb33e2605..43347e37d 100644 --- a/lib/Cake/Utility/Validation.php +++ b/lib/Cake/Utility/Validation.php @@ -372,23 +372,39 @@ class Validation { } /** - * Checks that a value is a valid decimal. If $places is null, the $check is allowed to be a scientific float - * If no decimal point is found a false will be returned. Both the sign and exponent are optional. + * Checks that a value is a valid decimal. Both the sign and exponent are optional. + * + * Valid Places: + * + * - null => Any number of decimal places, including none. The '.' is not required. + * - true => Any number of decimal places greater than 0, or a float|double. The '.' is required. + * - 1..N => Exactly that many number of decimal places. The '.' is required. * * @param integer $check The value the test for decimal - * @param integer $places if set $check value must have exactly $places after the decimal point - * @param string $regex If a custom regular expression is used this is the only validation that will occur. + * @param integer $places + * @param string $regex If a custom regular expression is used, this is the only validation that will occur. * @return boolean Success */ public static function decimal($check, $places = null, $regex = null) { - if (is_float($check) && floor($check) === $check) { - $check = sprintf("%.1f", $check); - } if (is_null($regex)) { - if (is_null($places)) { - $regex = '/^[-+]?[0-9]*\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/'; - } else { - $regex = '/^[-+]?[0-9]*\\.{1}[0-9]{' . $places . '}$/'; + $lnum = '[0-9]+'; + $dnum = "[0-9]*[\.]{$lnum}"; + $sign = '[+-]?'; + $exp = "(?:[eE]{$sign}{$lnum})?"; + + if ($places === null) { + $regex = "/^{$sign}(?:{$lnum}|{$dnum}){$exp}$/"; + + } elseif ($places === true) { + if (is_float($check) && floor($check) === $check) { + $check = sprintf("%.1f", $check); + } + $regex = "/^{$sign}{$dnum}{$exp}$/"; + + } elseif (is_numeric($places)) { + $places = '[0-9]{' . $places . '}'; + $dnum = "(?:[0-9]*[\.]{$places}|{$lnum}[\.]{$places})"; + $regex = "/^{$sign}{$dnum}{$exp}$/"; } } return self::_check($check, $regex); @@ -796,7 +812,7 @@ class Validation { * @return boolean Success of match */ protected static function _check($check, $regex) { - if (preg_match($regex, $check)) { + if (is_string($regex) && preg_match($regex, $check)) { self::$errors[] = false; return true; } else { From 4fdd5e5d4595e9719a598bc12877709fc36a0b4e Mon Sep 17 00:00:00 2001 From: mark_story Date: Tue, 28 Aug 2012 21:58:32 -0400 Subject: [PATCH 15/20] Ignore non-scalar values for length. Fixes #3159 --- lib/Cake/View/Helper/FormHelper.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 17b0569a5..d24bb997e 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -1005,7 +1005,11 @@ class FormHelper extends AppHelper { } } - $autoLength = (!array_key_exists('maxlength', $options) && isset($fieldDef['length'])); + $autoLength = ( + !array_key_exists('maxlength', $options) && + isset($fieldDef['length']) && + is_scalar($fieldDef['length']) + ); if ($autoLength && $options['type'] == 'text') { $options['maxlength'] = $fieldDef['length']; } From 0b7f141deb1b53c1322dbe24311677161b2734ed Mon Sep 17 00:00:00 2001 From: Ivoz Date: Thu, 30 Aug 2012 11:02:06 +1000 Subject: [PATCH 16/20] Updated the readme to be cool, and down with it. --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From d077724cf78965579068c591156123f10e3bda23 Mon Sep 17 00:00:00 2001 From: Ivoz Date: Thu, 30 Aug 2012 11:03:31 +1000 Subject: [PATCH 17/20] Now with pics! --- README.md | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index ddf42020f..bf6cf499e 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,37 @@ -CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC. Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility. +Cakephp +======= -The Cake Software Foundation - promoting development related to CakePHP -http://cakefoundation.org/ +![CakePHP](http://cakephp.org/img/cake-logo.png) -CakePHP - the rapid development PHP framework -http://www.cakephp.org +[CakePHP](http://cakephp.org) is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC. +Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility. -Cookbook - user documentation for learning about CakePHP -http://book.cakephp.org +Some Handy Links +---------------- -API - quick reference to CakePHP -http://api.cakephp.org +[CakePHP](http://www.cakephp.org) - The rapid development PHP framework -The Bakery - everything CakePHP -http://bakery.cakephp.org +[Cookbook](http://book.cakephp.org) - THE Cake user documentation; start learning here! -The Show - live and archived podcasts about CakePHP and more -http://live.cakephp.org +[Plugins](http://plugins.cakephp.org/) - A repository of extensions to the framework -CakePHP TV - screen casts from events and video tutorials -http://tv.cakephp.org +[The Bakery](http://bakery.cakephp.org) - Tips, tutorials and articles -CakePHP Google Group - community mailing list and forum -http://groups.google.com/group/cake-php +[API](http://api.cakephp.org) - A reference to Cake's classes -#cakephp on irc.freenode.net - chat with CakePHP developers -irc://irc.freenode.net/cakephp +[CakePHP TV](http://tv.cakephp.org) - Screen casts from events and video tutorials + +[The Cake Software Foundation](http://cakefoundation.org/) - promoting development related to CakePHP + +Get Support! +------------ + +[Our Google Group](http://groups.google.com/group/cake-php) - community mailing list and forum + +[#cakephp](irc://irc.freenode.net/cakephp) on irc.freenode.net - Come chat with us, we have cake. + +[Q & A](http://ask.cakephp.org/) - Ask questions here, all questions welcome + +[Lighthouse](http://cakephp.lighthouseapp.com/) - Got issues? Please tell us! + +![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif) From 5f7f0727cd80e5240b6b783643ec1265206902da Mon Sep 17 00:00:00 2001 From: Ivoz Date: Thu, 30 Aug 2012 11:22:52 +1000 Subject: [PATCH 18/20] Fixed Capitalization... --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf6cf499e..035ba3d40 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Cakephp +CakePHP ======= ![CakePHP](http://cakephp.org/img/cake-logo.png) From 949dfd3819d45d10b9ef17db0ebb53f9e05715c9 Mon Sep 17 00:00:00 2001 From: Ivoz Date: Thu, 30 Aug 2012 11:25:03 +1000 Subject: [PATCH 19/20] Made IRC a webchat link, for noobs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 035ba3d40..74379272a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Get Support! [Our Google Group](http://groups.google.com/group/cake-php) - community mailing list and forum -[#cakephp](irc://irc.freenode.net/cakephp) on irc.freenode.net - Come chat with us, we have cake. +[#cakephp](http://webchat.freenode.net/?channels=#cakephp) on irc.freenode.net - Come chat with us, we have cake. [Q & A](http://ask.cakephp.org/) - Ask questions here, all questions welcome From 027c464e2dc4508de8ce9e9dacb1a75b772fb804 Mon Sep 17 00:00:00 2001 From: Ivoz Date: Thu, 30 Aug 2012 12:01:24 +1000 Subject: [PATCH 20/20] Travis status going in... --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 74379272a..611729f08 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ CakePHP ======= -![CakePHP](http://cakephp.org/img/cake-logo.png) +[![CakePHP](http://cakephp.org/img/cake-logo.png)](http://www.cakephp.org) -[CakePHP](http://cakephp.org) is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC. +CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC. Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility. Some Handy Links @@ -34,4 +34,6 @@ Get Support! [Lighthouse](http://cakephp.lighthouseapp.com/) - Got issues? Please tell us! +[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp) + ![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif)