diff --git a/lib/Cake/Console/Command/Task/PluginTask.php b/lib/Cake/Console/Command/Task/PluginTask.php index a49047d4b..e37e437c3 100644 --- a/lib/Cake/Console/Command/Task/PluginTask.php +++ b/lib/Cake/Console/Command/Task/PluginTask.php @@ -191,9 +191,11 @@ class PluginTask extends AppShell { $valid = false; foreach ($pathOptions as $i => $path) { if (!is_dir($path)) { - array_splice($pathOptions, $i, 1); + unset($pathOptions[$i]); } } + $pathOptions = array_values($pathOptions); + $max = count($pathOptions); while (!$valid) { foreach ($pathOptions as $i => $option) { diff --git a/lib/Cake/Model/Datasource/Database/Postgres.php b/lib/Cake/Model/Datasource/Database/Postgres.php index f524cbe73..1a5e78eed 100644 --- a/lib/Cake/Model/Datasource/Database/Postgres.php +++ b/lib/Cake/Model/Datasource/Database/Postgres.php @@ -530,14 +530,17 @@ class Postgres extends DboSource { } break; case 'change': + $schema = $this->describe($curTable); foreach ($column as $field => $col) { if (!isset($col['name'])) { $col['name'] = $field; } + $original = $schema[$field]; $fieldName = $this->name($field); $default = isset($col['default']) ? $col['default'] : null; $nullable = isset($col['null']) ? $col['null'] : null; + $boolToInt = $original['type'] == 'boolean' && $col['type'] == 'integer'; unset($col['default'], $col['null']); if ($field !== $col['name']) { $newName = $this->name($col['name']); @@ -545,14 +548,23 @@ class Postgres extends DboSource { $out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n"; $fieldName = $newName; } - $colList[] = 'ALTER COLUMN ' . $fieldName . ' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col)); + + if ($boolToInt) { + $colList[] = 'ALTER COLUMN ' . $fieldName . ' SET DEFAULT NULL'; + $colList[] = 'ALTER COLUMN ' . $fieldName . ' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col)) . ' USING CASE WHEN TRUE THEN 1 ELSE 0 END'; + } else { + $colList[] = 'ALTER COLUMN ' . $fieldName . ' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col)); + } + if (isset($nullable)) { $nullable = ($nullable) ? 'DROP NOT NULL' : 'SET NOT NULL'; $colList[] = 'ALTER COLUMN ' . $fieldName . ' ' . $nullable; } if (isset($default)) { - $colList[] = 'ALTER COLUMN ' . $fieldName . ' SET DEFAULT ' . $this->value($default, $col['type']); + if (!$boolToInt) { + $colList[] = 'ALTER COLUMN ' . $fieldName . ' SET DEFAULT ' . $this->value($default, $col['type']); + } } else { $colList[] = 'ALTER COLUMN ' . $fieldName . ' DROP DEFAULT'; } diff --git a/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php b/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php index 1d2065db5..2bf983e5f 100644 --- a/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php +++ b/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php @@ -185,7 +185,9 @@ class PluginTaskTest extends CakeTestCase { public function testFindPathNonExistant() { $paths = App::path('plugins'); $last = count($paths); - $paths[] = '/fake/path'; + + array_unshift($paths, '/fake/path'); + $paths[] = '/fake/path2'; $this->Task = $this->getMock('PluginTask', array('in', 'out', 'err', 'createFile', '_stop'), diff --git a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php index 3ac8882c2..512e32a40 100644 --- a/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php @@ -699,6 +699,34 @@ class PostgresTest extends CakeTestCase { $this->assertNotRegExp('/varchar\(36\) NOT NULL/i', $result); } +/** + * Test the alterSchema changing boolean to integer + * + * @return void + */ + public function testAlterSchemaBooleanToIntegerField() { + $default = array( + 'connection' => 'test', + 'name' => 'BoolField', + 'bool_fields' => array( + 'id' => array('type' => 'integer', 'key' => 'primary'), + 'name' => array('type' => 'string', 'length' => 50), + 'active' => array('type' => 'boolean', 'null' => false), + ) + ); + $Old = new CakeSchema($default); + $result = $this->Dbo->query($this->Dbo->createSchema($Old)); + $this->assertTrue($result); + + $modified = $default; + $modified['bool_fields']['active'] = array('type' => 'integer', 'null' => true); + + $New = new CakeSchema($modified); + $query = $this->Dbo->alterSchema($New->compare($Old)); + $result = $this->Dbo->query($query); + $this->Dbo->query($this->Dbo->dropSchema($Old)); + } + /** * Test the alter index capabilities of postgres * diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 85285f7e3..1f03e7696 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -3353,8 +3353,8 @@ class FormHelperTest extends CakeTestCase { $expected = array( 'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'), array('div' => array('class' => 'checkbox')), - array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1/2', 'id' => 'ModelMultiField1/2')), - array('label' => array('for' => 'ModelMultiField1/2')), + array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1/2', 'id' => 'ModelMultiField12')), + array('label' => array('for' => 'ModelMultiField12')), 'half', '/label', '/div', @@ -3634,8 +3634,8 @@ class FormHelperTest extends CakeTestCase { $result = $this->Form->radio('Model.field', array('1/2' => 'half')); $expected = array( 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'), - array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1/2', 'id' => 'ModelField1/2')), - 'label' => array('for' => 'ModelField1/2'), + array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1/2', 'id' => 'ModelField12')), + 'label' => array('for' => 'ModelField12'), 'half', '/label' ); @@ -4320,16 +4320,16 @@ class FormHelperTest extends CakeTestCase { */ public function testDomIdSuffix() { $result = $this->Form->domIdSuffix('1 string with 1$-dollar signs'); - $this->assertEquals('1StringWith1$-dollarSigns', $result); + $this->assertEquals('1StringWith1DollarSigns', $result); $result = $this->Form->domIdSuffix(''); - $this->assertEquals('AbcX=FooY=Bar', $result); - - $result = $this->Form->domIdSuffix('1 string with 1$-dollar signs', 'xhtml'); - $this->assertEquals('1StringWith1-dollarSigns', $result); - - $result = $this->Form->domIdSuffix('', 'xhtml'); $this->assertEquals('AbcXFooYBar', $result); + + $result = $this->Form->domIdSuffix('1 string with 1$-dollar signs', 'html5'); + $this->assertEquals('1StringWith1$-dollarSigns', $result); + + $result = $this->Form->domIdSuffix('', 'html5'); + $this->assertEquals('AbcX=FooY=Bar', $result); } /** @@ -4347,14 +4347,14 @@ class FormHelperTest extends CakeTestCase { $result = $this->Form->domIdSuffix('a\'b'); $this->assertEquals('AB2', $result); - $result = $this->Form->domIdSuffix('1 string with 1$-dollar', 'xhtml'); - $this->assertEquals('1StringWith1-dollar', $result); + $result = $this->Form->domIdSuffix('1 string with 1$-dollar'); + $this->assertEquals('1StringWith1Dollar', $result); - $result = $this->Form->domIdSuffix('1 string with 1€-dollar', 'xhtml'); - $this->assertEquals('1StringWith1-dollar1', $result); + $result = $this->Form->domIdSuffix('1 string with 1$-dollar'); + $this->assertEquals('1StringWith1Dollar1', $result); - $result = $this->Form->domIdSuffix('1 string with 1$-dollar', 'xhtml'); - $this->assertEquals('1StringWith1-dollar2', $result); + $result = $this->Form->domIdSuffix('1 string with 1$-dollar'); + $this->assertEquals('1StringWith1Dollar2', $result); } /** @@ -5246,31 +5246,32 @@ class FormHelperTest extends CakeTestCase { array('div' => array('class' => 'checkbox')), array('input' => array( 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]', - 'value' => 'a+', 'id' => 'ModelMultiFieldA+' + 'value' => 'a+', 'id' => 'ModelMultiFieldA2' )), - array('label' => array('for' => 'ModelMultiFieldA+')), + array('label' => array('for' => 'ModelMultiFieldA2')), 'first', '/label', '/div', array('div' => array('class' => 'checkbox')), array('input' => array( 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]', - 'value' => 'a++', 'id' => 'ModelMultiFieldA++' + 'value' => 'a++', 'id' => 'ModelMultiFieldA1' )), - array('label' => array('for' => 'ModelMultiFieldA++')), + array('label' => array('for' => 'ModelMultiFieldA1')), 'second', '/label', '/div', array('div' => array('class' => 'checkbox')), array('input' => array( 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]', - 'value' => 'a+++', 'id' => 'ModelMultiFieldA+++' + 'value' => 'a+++', 'id' => 'ModelMultiFieldA' )), - array('label' => array('for' => 'ModelMultiFieldA+++')), + array('label' => array('for' => 'ModelMultiFieldA')), 'third', '/label', '/div' ); + $this->assertTags($result, $expected); $result = $this->Form->select( @@ -5902,6 +5903,35 @@ class FormHelperTest extends CakeTestCase { $this->assertTags($result, $expected); } +/** + * Test that a checkbox can have 0 for the value and 1 for the hidden input. + * + * @return void + */ + public function testCheckboxZeroValue() { + $result = $this->Form->input('User.get_spam', array( + 'type' => 'checkbox', + 'value' => '0', + 'hiddenField' => '1', + )); + $expected = array( + 'div' => array('class' => 'input checkbox'), + array('input' => array( + 'type' => 'hidden', 'name' => 'data[User][get_spam]', + 'value' => '1', 'id' => 'UserGetSpam_' + )), + array('input' => array( + 'type' => 'checkbox', 'name' => 'data[User][get_spam]', + 'value' => '0', 'id' => 'UserGetSpam' + )), + 'label' => array('for' => 'UserGetSpam'), + 'Get Spam', + '/label', + '/div' + ); + $this->assertTags($result, $expected); + } + /** * testDateTime method * diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index b690c4ac0..5c7c34025 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -1407,14 +1407,11 @@ class FormHelper extends AppHelper { unset($options['default']); } - $options += array('required' => false); + $options += array('value' => 1, 'required' => false); $options = $this->_initInputField($fieldName, $options) + array('hiddenField' => true); $value = current($this->value($valueOptions)); $output = ''; - if (empty($options['value'])) { - $options['value'] = 1; - } if ( (!isset($options['checked']) && !empty($value) && $value == $options['value']) || !empty($options['checked']) @@ -2103,14 +2100,14 @@ class FormHelper extends AppHelper { * limitation, but to avoid layout issues it still filters out some sensitive chars. * * @param string $value The value that should be transferred into a DOM ID suffix. - * @param string $type Doctype to use. Defaults to html5. Anything else will use limited chars. + * @param string $type Doctype to use. Defaults to html4. * @return string DOM ID */ - public function domIdSuffix($value, $type = 'html5') { + public function domIdSuffix($value, $type = 'html4') { if ($type === 'html5') { - $value = str_replace(array('<', '>', ' ', '"', '\''), '_', $value); + $value = str_replace(array('@', '<', '>', ' ', '"', '\''), '_', $value); } else { - $value = preg_replace('~[^\\pL\d-_]+~u', '_', $value); + $value = Inflector::camelize(Inflector::slug($value)); } $value = Inflector::camelize($value); $count = 1; diff --git a/lib/Cake/basics.php b/lib/Cake/basics.php index ff258ba64..3d9990020 100644 --- a/lib/Cake/basics.php +++ b/lib/Cake/basics.php @@ -259,7 +259,7 @@ if (!function_exists('am')) { * @param array Third array * @param array Etc... * @return array All array parameters merged into one - * @link http://book.cakephp.org/2.0/en/development/debugging.html#am + * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#am */ function am() { $r = array();