From 41e1aa7eceaa40a4fe95927b4e0588a985f78ad2 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 11:05:51 -0200 Subject: [PATCH 01/15] Support to html5 in docType. --- cake/libs/view/helpers/html.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index c5165515f..951cd430c 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -122,6 +122,7 @@ class HtmlHelper extends AppHelper { 'html4-strict' => '', 'html4-trans' => '', 'html4-frame' => '', + 'html5' => '', 'xhtml-strict' => '', 'xhtml-trans' => '', 'xhtml-frame' => '', @@ -149,6 +150,7 @@ class HtmlHelper extends AppHelper { * - html4-strict: HTML4 Strict. * - html4-trans: HTML4 Transitional. * - html4-frame: HTML4 Frameset. + * - html5: HTML5. * - xhtml-strict: XHTML1 Strict. * - xhtml-trans: XHTML1 Transitional. * - xhtml-frame: XHTML1 Frameset. From 8cd54776f129175d48c30d9b549af32375d48979 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 12:25:52 -0200 Subject: [PATCH 02/15] Created the method useTag in html, avoiding sprintf with Html tags in others helpers. --- cake/libs/view/helpers/html.php | 20 +++++++++++++++++++ .../cases/libs/view/helpers/html.test.php | 16 +++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index 951cd430c..7e4db5fcb 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -763,6 +763,26 @@ class HtmlHelper extends AppHelper { return sprintf($this->tags[$tag], $name, $this->_parseAttributes($options, null, ' ', ''), $text, $name); } +/** + * Returns a formatted existent block of $tags + * + * @param string $tag Tag name + * @return string Formatted block + */ + public function useTag($tag) { + if (!isset($this->tags[$tag])) { + return ''; + } + $args = func_get_args(); + array_shift($args); + foreach ($args as &$arg) { + if (is_array($arg)) { + $arg = $this->_parseAttributes($arg, null, ' ', ''); + } + } + return vsprintf($this->tags[$tag], $args); + } + /** * Returns a formatted DIV tag for HTML FORMs. * diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index 142fe91b5..41d0aed9b 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -1231,6 +1231,22 @@ class HtmlHelperTest extends CakeTestCase { $this->assertTags($result, array('div' => array('class' => 'class-name'), '<text>', '/div')); } +/** + * testUseTag method + * + * @return void + */ + public function testUseTag() { + $result = $this->Html->useTag('formend'); + $this->assertTags($result, '/form'); + + $result = $this->Html->useTag('form', 'test'); + $this->assertEqual($result, '
'); + + $result = $this->Html->useTag('form', array('test' => 'ok')); + $this->assertTags($result, array('form' => array('test' => 'ok'))); + } + /** * testDiv method * From 5bc0f0c2a1ae915cdf7b3670823ee4843eaa1a53 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 12:26:14 -0200 Subject: [PATCH 03/15] Replacing sprintf using Html tags by useTag. --- cake/libs/view/helpers/form.php | 122 +++++------------- .../cases/libs/view/helpers/form.test.php | 4 +- 2 files changed, 34 insertions(+), 92 deletions(-) diff --git a/cake/libs/view/helpers/form.php b/cake/libs/view/helpers/form.php index f397c670d..1eb2b315f 100644 --- a/cake/libs/view/helpers/form.php +++ b/cake/libs/view/helpers/form.php @@ -314,12 +314,11 @@ class FormHelper extends AppHelper { } if (!empty($append)) { - $append = sprintf($this->Html->tags['block'], ' style="display:none;"', $append); + $append = $this->Html->useTag('block', ' style="display:none;"', $append); } $this->setEntity($model . '.', true); - $attributes = $this->_parseAttributes($htmlAttributes, null, ''); - return sprintf($this->Html->tags['form'], $attributes) . $append; + return $this->Html->useTag('form', $htmlAttributes) . $append; } /** @@ -372,7 +371,7 @@ class FormHelper extends AppHelper { $this->fields = array(); } $this->setEntity(null); - $out .= $this->Html->tags['formend']; + $out .= $this->Html->useTag('formend'); $this->_View->modelScope = false; return $out; @@ -407,8 +406,7 @@ class FormHelper extends AppHelper { 'value' => urlencode($fields . ':' . $locked), 'id' => 'TokenFields' . mt_rand() )); - $out = sprintf($this->Html->tags['block'], ' style="display:none;"', $out); - return $out; + return $this->Html->useTag('block', ' style="display:none;"', $out); } /** @@ -562,11 +560,7 @@ class FormHelper extends AppHelper { $labelFor = $this->domId($fieldName); } - return sprintf( - $this->Html->tags['label'], - $labelFor, - $this->_parseAttributes($options), $text - ); + return $this->Html->useTag('label', $labelFor, $options, $text); } /** @@ -657,13 +651,9 @@ class FormHelper extends AppHelper { } if ($fieldset && $legend) { - return sprintf( - $this->Html->tags['fieldset'], - $fieldsetClass, - sprintf($this->Html->tags['legend'], $legend) . $out - ); + return $this->Html->useTag('fieldset', $fieldsetClass, $this->Html->useTag('legend', $legend) . $out); } elseif ($fieldset) { - return sprintf($this->Html->tags['fieldset'], $fieldsetClass, $out); + return $this->Html->useTag('fieldset', $fieldsetClass, $out); } else { return $out; } @@ -1019,11 +1009,7 @@ class FormHelper extends AppHelper { } unset($options['hiddenField']); - return $output . sprintf( - $this->Html->tags['checkbox'], - $options['name'], - $this->_parseAttributes($options, array('name'), null, ' ') - ); + return $output . $this->Html->useTag('checkbox', $options['name'], array_diff_key($options, array('name' => ''))); } /** @@ -1085,20 +1071,17 @@ class FormHelper extends AppHelper { if (isset($value) && $optValue == $value) { $optionsHere['checked'] = 'checked'; } - $parsedOptions = $this->_parseAttributes( - array_merge($attributes, $optionsHere), - array('name', 'type', 'id'), '', ' ' - ); $tagName = Inflector::camelize( $attributes['id'] . '_' . Inflector::slug($optValue) ); if ($label) { - $optTitle = sprintf($this->Html->tags['label'], $tagName, null, $optTitle); + $optTitle = $this->Html->useTag('label', $tagName, '', $optTitle); } - $out[] = sprintf( - $this->Html->tags['radio'], $attributes['name'], - $tagName, $parsedOptions, $optTitle + $allOptions = array_merge($attributes, $optionsHere); + $out[] = $this->Html->useTag('radio', $attributes['name'], $tagName, + array_diff_key($allOptions, array('name' => '', 'type' => '', 'id' => '')), + $optTitle ); } $hidden = null; @@ -1113,10 +1096,7 @@ class FormHelper extends AppHelper { $out = $hidden . implode($inbetween, $out); if ($legend) { - $out = sprintf( - $this->Html->tags['fieldset'], '', - sprintf($this->Html->tags['legend'], $legend) . $out - ); + $out = $this->Html->useTag('fieldset', '', $this->Html->useTag('legend', $legend) . $out); } return $out; } @@ -1154,11 +1134,7 @@ class FormHelper extends AppHelper { $options['type'] = $method; } $options = $this->_initInputField($params[0], $options); - return sprintf( - $this->Html->tags['input'], - $options['name'], - $this->_parseAttributes($options, array('name'), null, ' ') - ); + return $this->Html->useTag('input', $options['name'], array_diff_key($options, array('name' => ''))); } /** @@ -1185,12 +1161,7 @@ class FormHelper extends AppHelper { } unset($options['value']); } - return sprintf( - $this->Html->tags['textarea'], - $options['name'], - $this->_parseAttributes($options, array('type', 'name'), null, ' '), - $value - ); + return $this->Html->useTag('textarea', $options['name'], array_diff_key($options, array('type' => '', 'name' => '')), $value); } /** @@ -1218,11 +1189,7 @@ class FormHelper extends AppHelper { $this->__secure(null, '' . $options['value']); } - return sprintf( - $this->Html->tags['hidden'], - $options['name'], - $this->_parseAttributes($options, array('name', 'class'), '', ' ') - ); + return $this->Html->useTag('hidden', $options['name'], array_diff_key($options, array('name' => '', 'class' => ''))); } /** @@ -1243,8 +1210,7 @@ class FormHelper extends AppHelper { $this->__secure(array_merge($field, array($suffix))); } - $attributes = $this->_parseAttributes($options, array('name'), '', ' '); - return sprintf($this->Html->tags['file'], $options['name'], $attributes); + return $this->Html->useTag('file', $options['name'], array_diff_key($options, array('name' => ''))); } /** @@ -1266,12 +1232,7 @@ class FormHelper extends AppHelper { if ($options['escape']) { $title = h($title); } - return sprintf( - $this->Html->tags['button'], - $options['type'], - $this->_parseAttributes($options, array('type'), ' ', ''), - $title - ); + return $this->Html->useTag('button', $options['type'], array_diff_key($options, array('type' => '')), $title); } /** @@ -1408,11 +1369,7 @@ class FormHelper extends AppHelper { if (strpos($caption, '://') !== false) { unset($options['type']); - $out .= $before . sprintf( - $this->Html->tags['submitimage'], - $caption, - $this->_parseAttributes($options, null, '', ' ') - ) . $after; + $out .= $before . $this->Html->useTag('submitimage', $caption, $options) . $after; } elseif (preg_match('/\.(jpg|jpe|jpeg|gif|png|ico)$/', $caption)) { unset($options['type']); if ($caption{0} !== '/') { @@ -1421,17 +1378,10 @@ class FormHelper extends AppHelper { $caption = trim($caption, '/'); $url = $this->webroot($caption); } - $out .= $before . sprintf( - $this->Html->tags['submitimage'], - $url, - $this->_parseAttributes($options, null, '', ' ') - ) . $after; + $out .= $before . $this->Html->useTag('submitimage', $url, $options) . $after; } else { $options['value'] = $caption; - $out .= $before . sprintf( - $this->Html->tags['submit'], - $this->_parseAttributes($options, null, '', ' ') - ). $after; + $out .= $before . $this->Html->useTag('submit', $options) . $after; } if (isset($divOptions)) { @@ -1524,7 +1474,7 @@ class FormHelper extends AppHelper { if (isset($attributes) && array_key_exists('multiple', $attributes)) { $style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null; $template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart'; - $tag = $this->Html->tags[$template]; + $tag = $template; $hiddenAttributes = array( 'value' => '', 'id' => $attributes['id'] . ($style ? '' : '_'), @@ -1533,16 +1483,14 @@ class FormHelper extends AppHelper { ); $select[] = $this->hidden(null, $hiddenAttributes); } else { - $tag = $this->Html->tags['selectstart']; + $tag = 'selectstart'; } if (!empty($tag) || isset($template)) { if (!isset($secure) || $secure == true) { $this->__secure(); } - $select[] = sprintf($tag, $attributes['name'], $this->_parseAttributes( - $attributes, array('name', 'value')) - ); + $select[] = $this->Html->useTag($tag, $attributes['name'], array_diff_key($attributes, array('name' => '', 'value' => ''))); } $emptyMulti = ( $showEmpty !== null && $showEmpty !== false && !( @@ -1566,7 +1514,7 @@ class FormHelper extends AppHelper { )); $template = ($style == 'checkbox') ? 'checkboxmultipleend' : 'selectend'; - $select[] = $this->Html->tags[$template]; + $select[] = $this->Html->useTag($template); return implode("\n", $select); } @@ -2057,9 +2005,9 @@ class FormHelper extends AppHelper { if (is_array($title) && (!isset($title['name']) || !isset($title['value']))) { if (!empty($name)) { if ($attributes['style'] === 'checkbox') { - $select[] = $this->Html->tags['fieldsetend']; + $select[] = $this->Html->useTag('fieldsetend'); } else { - $select[] = $this->Html->tags['optiongroupend']; + $select[] = $this->Html->useTag('optiongroupend'); } $parents[] = $name; } @@ -2070,9 +2018,9 @@ class FormHelper extends AppHelper { if (!empty($name)) { $name = $attributes['escape'] ? h($name) : $name; if ($attributes['style'] === 'checkbox') { - $select[] = sprintf($this->Html->tags['fieldsetstart'], $name); + $select[] = $this->Html->useTag('fieldsetstart', $name); } else { - $select[] = sprintf($this->Html->tags['optiongroup'], $name, ''); + $select[] = $this->Html->useTag('optiongroup', $name, ''); } } $name = null; @@ -2117,16 +2065,10 @@ class FormHelper extends AppHelper { $attributes['class'] = 'checkbox'; } $label = $this->label(null, $title, $label); - $item = sprintf( - $this->Html->tags['checkboxmultiple'], $name, - $this->_parseAttributes($htmlOptions) - ); + $item = $this->Html->useTag('checkboxmultiple', $name, $htmlOptions); $select[] = $this->Html->div($attributes['class'], $item . $label); } else { - $select[] = sprintf( - $this->Html->tags['selectoption'], - $name, $this->_parseAttributes($htmlOptions), $title - ); + $select[] = $this->Html->useTag('selectoption', $name, $htmlOptions, $title); } } } diff --git a/cake/tests/cases/libs/view/helpers/form.test.php b/cake/tests/cases/libs/view/helpers/form.test.php index c4f1e9dd7..bb389396a 100644 --- a/cake/tests/cases/libs/view/helpers/form.test.php +++ b/cake/tests/cases/libs/view/helpers/form.test.php @@ -5253,7 +5253,7 @@ class FormHelperTest extends CakeTestCase { )); $result = $this->Form->postButton('Send', '/', array('data' => array('extra' => 'value'))); - $this->assertTrue(strpos($result, '') !== false); + $this->assertTrue(strpos($result, '') !== false); } /** @@ -5293,7 +5293,7 @@ class FormHelperTest extends CakeTestCase { )); $result = $this->Form->postLink('Delete', '/posts/delete', array('data' => array('id' => 1))); - $this->assertTrue(strpos($result, '') !== false); + $this->assertTrue(strpos($result, '') !== false); } /** From 10d3dd5d2bd285a4b69cd49eaa49a6c76708ba7d Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 12:36:14 -0200 Subject: [PATCH 04/15] Moving the parseAttributes to Html helper. --- cake/libs/view/helper.php | 112 ----------------- cake/libs/view/helpers/html.php | 113 ++++++++++++++++++ cake/tests/cases/libs/view/helper.test.php | 55 --------- .../cases/libs/view/helpers/html.test.php | 71 +++++++++++ 4 files changed, 184 insertions(+), 167 deletions(-) diff --git a/cake/libs/view/helper.php b/cake/libs/view/helper.php index 16ea94798..88588f808 100644 --- a/cake/libs/view/helper.php +++ b/cake/libs/view/helper.php @@ -105,30 +105,6 @@ class Helper extends Object { */ protected $_View; -/** - * Minimized attributes - * - * @var array - */ - protected $_minimizedAttributes = array( - 'compact', 'checked', 'declare', 'readonly', 'disabled', 'selected', - 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize' - ); - -/** - * Format to attribute - * - * @var string - */ - protected $_attributeFormat = '%s="%s"'; - -/** - * Format to attribute - * - * @var string - */ - protected $_minimizedAttributeFormat = '%s="%s"'; - /** * Default Constructor * @@ -330,94 +306,6 @@ class Helper extends Object { return $this->__cleaned; } -/** - * Returns a space-delimited string with items of the $options array. If a - * key of $options array happens to be one of: - * - * - 'compact' - * - 'checked' - * - 'declare' - * - 'readonly' - * - 'disabled' - * - 'selected' - * - 'defer' - * - 'ismap' - * - 'nohref' - * - 'noshade' - * - 'nowrap' - * - 'multiple' - * - 'noresize' - * - * And its value is one of: - * - * - '1' (string) - * - 1 (integer) - * - true (boolean) - * - 'true' (string) - * - * Then the value will be reset to be identical with key's name. - * If the value is not one of these 3, the parameter is not output. - * - * 'escape' is a special option in that it controls the conversion of - * attributes to their html-entity encoded equivalents. Set to false to disable html-encoding. - * - * If value for any option key is set to `null` or `false`, that option will be excluded from output. - * - * @param array $options Array of options. - * @param array $exclude Array of options to be excluded, the options here will not be part of the return. - * @param string $insertBefore String to be inserted before options. - * @param string $insertAfter String to be inserted after options. - * @return string Composed attributes. - */ - public function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) { - if (is_array($options)) { - $options = array_merge(array('escape' => true), $options); - - if (!is_array($exclude)) { - $exclude = array(); - } - $filtered = array_diff_key($options, array_merge(array_flip($exclude), array('escape' => true))); - $escape = $options['escape']; - $attributes = array(); - - foreach ($filtered as $key => $value) { - if ($value !== false && $value !== null) { - $attributes[] = $this->_formatAttribute($key, $value, $escape); - } - } - $out = implode(' ', $attributes); - } else { - $out = $options; - } - return $out ? $insertBefore . $out . $insertAfter : ''; - } - -/** - * Formats an individual attribute, and returns the string value of the composed attribute. - * Works with minimized attributes that have the same value as their name such as 'disabled' and 'checked' - * - * @param string $key The name of the attribute to create - * @param string $value The value of the attribute to create. - * @return string The composed attribute. - */ - protected function _formatAttribute($key, $value, $escape = true) { - $attribute = ''; - if (is_array($value)) { - $value = ''; - } - - if (is_numeric($key)) { - $attribute = sprintf($this->_minimizedAttributeFormat, $value, $value); - } elseif (in_array($key, $this->_minimizedAttributes)) { - if ($value === 1 || $value === true || $value === 'true' || $value === '1' || $value == $key) { - $attribute = sprintf($this->_minimizedAttributeFormat, $key, $key); - } - } else { - $attribute = sprintf($this->_attributeFormat, $key, ($escape ? h($value) : $value)); - } - return $attribute; - } - /** * Sets this helper's model and field properties to the dot-separated value-pair in $entity. * diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index 7e4db5fcb..d4af24612 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -90,6 +90,30 @@ class HtmlHelper extends AppHelper { 'javascriptend' => '' ); +/** + * Minimized attributes + * + * @var array + */ + protected $_minimizedAttributes = array( + 'compact', 'checked', 'declare', 'readonly', 'disabled', 'selected', + 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize' + ); + +/** + * Format to attribute + * + * @var string + */ + protected $_attributeFormat = '%s="%s"'; + +/** + * Format to attribute + * + * @var string + */ + protected $_minimizedAttributeFormat = '%s="%s"'; + /** * Breadcrumbs. * @@ -881,4 +905,93 @@ class HtmlHelper extends AppHelper { } return $out; } + +/** + * Returns a space-delimited string with items of the $options array. If a + * key of $options array happens to be one of: + * + * - 'compact' + * - 'checked' + * - 'declare' + * - 'readonly' + * - 'disabled' + * - 'selected' + * - 'defer' + * - 'ismap' + * - 'nohref' + * - 'noshade' + * - 'nowrap' + * - 'multiple' + * - 'noresize' + * + * And its value is one of: + * + * - '1' (string) + * - 1 (integer) + * - true (boolean) + * - 'true' (string) + * + * Then the value will be reset to be identical with key's name. + * If the value is not one of these 3, the parameter is not output. + * + * 'escape' is a special option in that it controls the conversion of + * attributes to their html-entity encoded equivalents. Set to false to disable html-encoding. + * + * If value for any option key is set to `null` or `false`, that option will be excluded from output. + * + * @param array $options Array of options. + * @param array $exclude Array of options to be excluded, the options here will not be part of the return. + * @param string $insertBefore String to be inserted before options. + * @param string $insertAfter String to be inserted after options. + * @return string Composed attributes. + */ + public function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) { + if (is_array($options)) { + $options = array_merge(array('escape' => true), $options); + + if (!is_array($exclude)) { + $exclude = array(); + } + $filtered = array_diff_key($options, array_merge(array_flip($exclude), array('escape' => true))); + $escape = $options['escape']; + $attributes = array(); + + foreach ($filtered as $key => $value) { + if ($value !== false && $value !== null) { + $attributes[] = $this->_formatAttribute($key, $value, $escape); + } + } + $out = implode(' ', $attributes); + } else { + $out = $options; + } + return $out ? $insertBefore . $out . $insertAfter : ''; + } + +/** + * Formats an individual attribute, and returns the string value of the composed attribute. + * Works with minimized attributes that have the same value as their name such as 'disabled' and 'checked' + * + * @param string $key The name of the attribute to create + * @param string $value The value of the attribute to create. + * @return string The composed attribute. + */ + protected function _formatAttribute($key, $value, $escape = true) { + $attribute = ''; + if (is_array($value)) { + $value = ''; + } + + if (is_numeric($key)) { + $attribute = sprintf($this->_minimizedAttributeFormat, $value, $value); + } elseif (in_array($key, $this->_minimizedAttributes)) { + if ($value === 1 || $value === true || $value === 'true' || $value === '1' || $value == $key) { + $attribute = sprintf($this->_minimizedAttributeFormat, $key, $key); + } + } else { + $attribute = sprintf($this->_attributeFormat, $key, ($escape ? h($value) : $value)); + } + return $attribute; + } + } diff --git a/cake/tests/cases/libs/view/helper.test.php b/cake/tests/cases/libs/view/helper.test.php index 44b38f903..125e00ac1 100644 --- a/cake/tests/cases/libs/view/helper.test.php +++ b/cake/tests/cases/libs/view/helper.test.php @@ -179,35 +179,6 @@ class TestHelper extends Helper { } } -/** - * Html5TestHelper class - * - * @package cake.tests.cases.libs.view - */ -class Html5TestHelper extends TestHelper { - -/** - * Minimized - * - * @var array - */ - protected $_minimizedAttributes = array('require', 'checked'); - -/** - * Allow compact use in HTML - * - * @var string - */ - protected $_minimizedAttributeFormat = '%s'; - -/** - * Test to attribute format - * - * @var string - */ - protected $_attributeFormat = 'data-%s="%s"'; -} - /** * HelperTest class * @@ -815,32 +786,6 @@ class HelperTest extends CakeTestCase { Configure::write('App.www_root', $webRoot); } -/** - * test parsing attributes. - * - * @return void - */ - function testParseAttributeCompact() { - $helper = new TestHelper($this->View); - $compact = array('compact', 'checked', 'declare', 'readonly', 'disabled', - 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize'); - - foreach ($compact as $attribute) { - foreach (array('true', true, 1, '1', $attribute) as $value) { - $attrs = array($attribute => $value); - $expected = ' ' . $attribute . '="' . $attribute . '"'; - $this->assertEqual($helper->parseAttributes($attrs), $expected, '%s Failed on ' . $value); - } - } - $this->assertEqual($helper->parseAttributes(array('compact')), ' compact="compact"'); - - $helper = new Html5TestHelper($this->View); - $expected = ' require'; - $this->assertEqual($helper->parseAttributes(array('require')), $expected); - $this->assertEqual($helper->parseAttributes(array('require' => true)), $expected); - $this->assertEqual($helper->parseAttributes(array('require' => false)), ''); - } - /** * test lazy loading helpers is seamless * diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index 41d0aed9b..c3e73790e 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -47,6 +47,50 @@ class TheHtmlTestController extends Controller { public $uses = null; } +class TestHtmlHelper extends HtmlHelper { +/** + * expose a method as public + * + * @param string $options + * @param string $exclude + * @param string $insertBefore + * @param string $insertAfter + * @return void + */ + function parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) { + return $this->_parseAttributes($options, $exclude, $insertBefore, $insertAfter); + } +} + +/** + * Html5TestHelper class + * + * @package cake.tests.cases.libs.view.helpers + */ +class Html5TestHelper extends TestHtmlHelper { + +/** + * Minimized + * + * @var array + */ + protected $_minimizedAttributes = array('require', 'checked'); + +/** + * Allow compact use in HTML + * + * @var string + */ + protected $_minimizedAttributeFormat = '%s'; + +/** + * Test to attribute format + * + * @var string + */ + protected $_attributeFormat = 'data-%s="%s"'; +} + /** * HtmlHelperTest class * @@ -1312,4 +1356,31 @@ class HtmlHelperTest extends CakeTestCase { ) ); } + +/** + * test parsing attributes. + * + * @return void + */ + function testParseAttributeCompact() { + $helper = new TestHtmlHelper($this->View); + $compact = array('compact', 'checked', 'declare', 'readonly', 'disabled', + 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize'); + + foreach ($compact as $attribute) { + foreach (array('true', true, 1, '1', $attribute) as $value) { + $attrs = array($attribute => $value); + $expected = ' ' . $attribute . '="' . $attribute . '"'; + $this->assertEqual($helper->parseAttributes($attrs), $expected, '%s Failed on ' . $value); + } + } + $this->assertEqual($helper->parseAttributes(array('compact')), ' compact="compact"'); + + $helper = new Html5TestHelper($this->View); + $expected = ' require'; + $this->assertEqual($helper->parseAttributes(array('require')), $expected); + $this->assertEqual($helper->parseAttributes(array('require' => true)), $expected); + $this->assertEqual($helper->parseAttributes(array('require' => false)), ''); + } + } From b1f4c6a0c9bd932e25bf1090cf0287594653f321 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 12:38:36 -0200 Subject: [PATCH 05/15] Changed tags attributes to protected. --- cake/libs/view/helpers/html.php | 47 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index d4af24612..21746f60a 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -29,9 +29,8 @@ class HtmlHelper extends AppHelper { * html tags used by this helper. * * @var array - * @access public */ - public $tags = array( + protected $_tags = array( 'meta' => '', 'metalink' => '', 'link' => '%s', @@ -246,14 +245,14 @@ class HtmlHelper extends AppHelper { if (isset($options['link'])) { if (isset($options['rel']) && $options['rel'] === 'icon') { - $out = sprintf($this->tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); + $out = sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); $options['rel'] = 'shortcut icon'; } else { $options['link'] = $this->url($options['link'], true); } - $out .= sprintf($this->tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); + $out .= sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); } else { - $out = sprintf($this->tags['meta'], $this->_parseAttributes($options, array('type'), ' ', ' ')); + $out = sprintf($this->_tags['meta'], $this->_parseAttributes($options, array('type'), ' ', ' ')); } if ($inline) { @@ -276,7 +275,7 @@ class HtmlHelper extends AppHelper { if (empty($charset)) { $charset = strtolower(Configure::read('App.encoding')); } - return sprintf($this->tags['charset'], (!empty($charset) ? $charset : 'utf-8')); + return sprintf($this->_tags['charset'], (!empty($charset) ? $charset : 'utf-8')); } /** @@ -336,7 +335,7 @@ class HtmlHelper extends AppHelper { } unset($options['default']); } - return sprintf($this->tags['link'], $url, $this->_parseAttributes($options), $title); + return sprintf($this->_tags['link'], $url, $this->_parseAttributes($options), $title); } /** @@ -391,12 +390,12 @@ class HtmlHelper extends AppHelper { } if ($rel == 'import') { - $out = sprintf($this->tags['style'], $this->_parseAttributes($options, array('inline'), '', ' '), '@import url(' . $url . ');'); + $out = sprintf($this->_tags['style'], $this->_parseAttributes($options, array('inline'), '', ' '), '@import url(' . $url . ');'); } else { if ($rel == null) { $rel = 'stylesheet'; } - $out = sprintf($this->tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline'), '', ' ')); + $out = sprintf($this->_tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline'), '', ' ')); } if ($options['inline']) { @@ -462,7 +461,7 @@ class HtmlHelper extends AppHelper { } } $attributes = $this->_parseAttributes($options, array('inline', 'once'), ' '); - $out = sprintf($this->tags['javascriptlink'], $url, $attributes); + $out = sprintf($this->_tags['javascriptlink'], $url, $attributes); if ($options['inline']) { return $out; @@ -494,9 +493,9 @@ class HtmlHelper extends AppHelper { unset($options['inline'], $options['safe']); $attributes = $this->_parseAttributes($options, ' ', ' '); if ($inline) { - return sprintf($this->tags['javascriptblock'], $attributes, $script); + return sprintf($this->_tags['javascriptblock'], $attributes, $script); } else { - $this->_View->addScript(sprintf($this->tags['javascriptblock'], $attributes, $script)); + $this->_View->addScript(sprintf($this->_tags['javascriptblock'], $attributes, $script)); return null; } } @@ -675,10 +674,10 @@ class HtmlHelper extends AppHelper { unset($options['url']); } - $image = sprintf($this->tags['image'], $path, $this->_parseAttributes($options, null, '', ' ')); + $image = sprintf($this->_tags['image'], $path, $this->_parseAttributes($options, null, '', ' ')); if ($url) { - return sprintf($this->tags['link'], $this->url($url), null, $image); + return sprintf($this->_tags['link'], $this->url($url), null, $image); } return $image; } @@ -696,9 +695,9 @@ class HtmlHelper extends AppHelper { public function tableHeaders($names, $trOptions = null, $thOptions = null) { $out = array(); foreach ($names as $arg) { - $out[] = sprintf($this->tags['tableheader'], $this->_parseAttributes($thOptions), $arg); + $out[] = sprintf($this->_tags['tableheader'], $this->_parseAttributes($thOptions), $arg); } - return sprintf($this->tags['tablerow'], $this->_parseAttributes($trOptions), join(' ', $out)); + return sprintf($this->_tags['tablerow'], $this->_parseAttributes($trOptions), join(' ', $out)); } /** @@ -748,10 +747,10 @@ class HtmlHelper extends AppHelper { } elseif ($useCount) { $cellOptions['class'] = 'column-' . ++$i; } - $cellsOut[] = sprintf($this->tags['tablecell'], $this->_parseAttributes($cellOptions), $cell); + $cellsOut[] = sprintf($this->_tags['tablecell'], $this->_parseAttributes($cellOptions), $cell); } $options = $this->_parseAttributes($count % 2 ? $oddTrOptions : $evenTrOptions); - $out[] = sprintf($this->tags['tablerow'], $options, implode(' ', $cellsOut)); + $out[] = sprintf($this->_tags['tablerow'], $options, implode(' ', $cellsOut)); } return implode("\n", $out); } @@ -784,7 +783,7 @@ class HtmlHelper extends AppHelper { } else { $tag = 'tag'; } - return sprintf($this->tags[$tag], $name, $this->_parseAttributes($options, null, ' ', ''), $text, $name); + return sprintf($this->_tags[$tag], $name, $this->_parseAttributes($options, null, ' ', ''), $text, $name); } /** @@ -794,7 +793,7 @@ class HtmlHelper extends AppHelper { * @return string Formatted block */ public function useTag($tag) { - if (!isset($this->tags[$tag])) { + if (!isset($this->_tags[$tag])) { return ''; } $args = func_get_args(); @@ -804,7 +803,7 @@ class HtmlHelper extends AppHelper { $arg = $this->_parseAttributes($arg, null, ' ', ''); } } - return vsprintf($this->tags[$tag], $args); + return vsprintf($this->_tags[$tag], $args); } /** @@ -855,7 +854,7 @@ class HtmlHelper extends AppHelper { } else { $tag = 'para'; } - return sprintf($this->tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $text); + return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $text); } /** @@ -873,7 +872,7 @@ class HtmlHelper extends AppHelper { $options = array(); } $items = $this->__nestedListItem($list, $options, $itemOptions, $tag); - return sprintf($this->tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $items); + return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $items); } /** @@ -900,7 +899,7 @@ class HtmlHelper extends AppHelper { } else if (isset($itemOptions['odd']) && $index % 2 != 0) { $itemOptions['class'] = $itemOptions['odd']; } - $out .= sprintf($this->tags['li'], $this->_parseAttributes($itemOptions, array('even', 'odd'), ' ', ''), $item); + $out .= sprintf($this->_tags['li'], $this->_parseAttributes($itemOptions, array('even', 'odd'), ' ', ''), $item); $index++; } return $out; From 7df97820207fd600bffa2fd484b8be667fe46a4d Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 16:21:17 -0200 Subject: [PATCH 06/15] Moving loadConfig to Html helper. --- cake/libs/view/helper.php | 16 ---------------- cake/libs/view/helpers/html.php | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cake/libs/view/helper.php b/cake/libs/view/helper.php index 88588f808..0337b5088 100644 --- a/cake/libs/view/helper.php +++ b/cake/libs/view/helper.php @@ -174,22 +174,6 @@ class Helper extends Object { return $this->{$name} = $value; } -/** - * Parses tag templates into $this->tags. - * - * @param $name file name inside app/config to load. - * @return array merged tags from config/$name.php - */ - public function loadConfig($name = 'tags') { - if (file_exists(CONFIGS . $name .'.php')) { - require(CONFIGS . $name .'.php'); - if (isset($tags)) { - $this->tags = array_merge($this->tags, $tags); - } - } - return $this->tags; - } - /** * Finds URL for specified action. * diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index 21746f60a..d784c6f66 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -905,6 +905,22 @@ class HtmlHelper extends AppHelper { return $out; } +/** + * Parses tag templates into $this->tags. + * + * @param $name file name inside app/config to load. + * @return array merged tags from config/$name.php + */ + public function loadConfig($name = 'tags') { + if (file_exists(CONFIGS . $name .'.php')) { + require(CONFIGS . $name .'.php'); + if (isset($tags)) { + $this->_tags = array_merge($this->_tags, $tags); + } + } + return $this->_tags; + } + /** * Returns a space-delimited string with items of the $options array. If a * key of $options array happens to be one of: From 1a90bf7292930af87859c2b7d4e7a7322c07bdd6 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 19:26:13 -0200 Subject: [PATCH 07/15] Support to read ini files without section in IniReader. --- cake/libs/config/ini_reader.php | 7 ++++++- cake/tests/cases/libs/config/ini_reader.test.php | 16 ++++++++++++++++ cake/tests/test_app/config/no_section.ini | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 cake/tests/test_app/config/no_section.ini diff --git a/cake/libs/config/ini_reader.php b/cake/libs/config/ini_reader.php index 915bf9498..e20f8dcfb 100644 --- a/cake/libs/config/ini_reader.php +++ b/cake/libs/config/ini_reader.php @@ -77,7 +77,12 @@ class IniReader implements ConfigReaderInterface { } else { $values = array(); foreach ($contents as $section => $attribs) { - $values[$section] = $this->_parseNestedValues($attribs); + if (is_array($attribs)) { + $values[$section] = $this->_parseNestedValues($attribs); + } else { + $parse = $this->_parseNestedValues(array($attribs)); + $values[$section] = array_shift($parse); + } } } return $values; diff --git a/cake/tests/cases/libs/config/ini_reader.test.php b/cake/tests/cases/libs/config/ini_reader.test.php index 2fb8eb2dd..3db8bb942 100644 --- a/cake/tests/cases/libs/config/ini_reader.test.php +++ b/cake/tests/cases/libs/config/ini_reader.test.php @@ -64,6 +64,22 @@ class IniReaderTest extends CakeTestCase { $this->assertEquals('administrators', $config['groups']); } +/** + * test without section + * + * @return void + */ + public function testReadingWithoutSection() { + $reader = new IniReader($this->path); + $config = $reader->read('no_section.ini'); + + $expected = array( + 'some_key' => 'some_value', + 'bool_key' => true + ); + $this->assertEquals($config, $expected); + } + /** * test that names with .'s get exploded into arrays. * diff --git a/cake/tests/test_app/config/no_section.ini b/cake/tests/test_app/config/no_section.ini new file mode 100644 index 000000000..6e6fbb7a0 --- /dev/null +++ b/cake/tests/test_app/config/no_section.ini @@ -0,0 +1,2 @@ +some_key = some_value +bool_key = 1 From 175e00830830328e104a7669dffba36c5b6d89d8 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 19:27:50 -0200 Subject: [PATCH 08/15] Reading configuration using reader classes. You can pass the key configFile in Html settings to load in constructor. --- cake/libs/view/helpers/html.php | 66 ++++++++++++++++--- .../cases/libs/view/helpers/html.test.php | 54 ++++++++++++++- .../test_app/config/htmlhelper_minimized.ini | 2 + .../tests/test_app/config/htmlhelper_tags.php | 8 +++ 4 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 cake/tests/test_app/config/htmlhelper_minimized.ini create mode 100644 cake/tests/test_app/config/htmlhelper_tags.php diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index d784c6f66..21543f311 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -152,6 +152,19 @@ class HtmlHelper extends AppHelper { 'xhtml11' => '' ); +/** + * Default Constructor + * + * @param View $View The View this helper is being attached to. + * @param array $settings Configuration settings for the helper. + */ + public function __construct(View $View, $settings = array()) { + parent::__construct($View, $settings); + if (!empty($settings['configFile'])) { + $this->loadConfig($settings['configFile']); + } + } + /** * Adds a link to the breadcrumbs array. * @@ -906,19 +919,54 @@ class HtmlHelper extends AppHelper { } /** - * Parses tag templates into $this->tags. + * Load Html configs * - * @param $name file name inside app/config to load. - * @return array merged tags from config/$name.php + * @param mixed $configFile String with the config file (load using PhpReader) or an array with file and reader name + * @param string $path Path with config file + * @return mixed False to error or loaded configs */ - public function loadConfig($name = 'tags') { - if (file_exists(CONFIGS . $name .'.php')) { - require(CONFIGS . $name .'.php'); - if (isset($tags)) { - $this->_tags = array_merge($this->_tags, $tags); + public function loadConfig($configFile, $path = CONFIGS) { + $file = null; + $reader = 'php'; + + if (!is_array($configFile)) { + $file = $configFile; + } elseif (isset($configFile[0])) { + $file = $configFile[0]; + if (isset($configFile[1])) { + $reader = $configFile[1]; } + } else { + return trigger_error(__('Cannot load the configuration file. Wrong "configFile" configuration.'), E_USER_NOTICE); } - return $this->_tags; + + $readerClass = Inflector::camelize($reader) . 'Reader'; + if (!App::import('Lib', 'config/' . $readerClass)) { + return trigger_error(__('Cannot load the configuration file. Unknown reader.'), E_USER_NOTICE); + } + + try { + $readerObj = new $readerClass($path); + $configs = $readerObj->read($file); + if (isset($configs['tags']) && is_array($configs['tags'])) { + $this->_tags = array_merge($this->_tags, $configs['tags']); + } + if (isset($configs['minimizedAttributes']) && is_array($configs['minimizedAttributes'])) { + $this->_minimizedAttributes = array_merge($this->_minimizedAttributes, $configs['minimizedAttributes']); + } + if (isset($configs['docTypes']) && is_array($configs['docTypes'])) { + $this->__docTypes = array_merge($this->__docTypes, $configs['docTypes']); + } + if (isset($configs['attributeFormat'])) { + $this->_attributeFormat = $configs['attributeFormat']; + } + if (isset($configs['minimizedAttributeFormat'])) { + $this->_minimizedAttributeFormat = $configs['minimizedAttributeFormat']; + } + } catch (Exception $e) { + return trigger_error(__('Cannot load the configuration file. Failed to load the file.'), E_USER_NOTICE); + } + return $configs; } /** diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index c3e73790e..a7a4cfbec 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -60,6 +60,20 @@ class TestHtmlHelper extends HtmlHelper { function parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) { return $this->_parseAttributes($options, $exclude, $insertBefore, $insertAfter); } + +/** + * Get a protected attribute value + * + * @param string $attribute + * @return mixed + */ + public function getAttribute($attribute) { + if (!isset($this->{$attribute})) { + return null; + } + return $this->{$attribute}; + } + } /** @@ -128,7 +142,7 @@ class HtmlHelperTest extends CakeTestCase { function setUp() { parent::setUp(); $this->View = $this->getMock('View', array('addScript'), array(new TheHtmlTestController())); - $this->Html = new HtmlHelper($this->View); + $this->Html = new TestHtmlHelper($this->View); $this->Html->request = new CakeRequest(null, false); $this->Html->request->webroot = ''; @@ -1357,6 +1371,44 @@ class HtmlHelperTest extends CakeTestCase { ); } +/** + * testLoadConfig method + * + * @return void + */ + + public function testLoadConfig() { + $path = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS; + + $result = $this->Html->loadConfig('htmlhelper_tags', $path); + $expected = array( + 'tags' => array( + 'form' => 'start form', + 'formend' => 'finish form' + ) + ); + $this->assertEqual($result, $expected); + $tags = $this->Html->getAttribute('_tags'); + $this->assertEqual($tags['form'], 'start form'); + $this->assertEqual($tags['formend'], 'finish form'); + $this->assertEqual($tags['selectend'], ''); + + $result = $this->Html->loadConfig(array('htmlhelper_minimized.ini', 'ini'), $path); + $expected = array( + 'minimizedAttributeFormat' => 'format' + ); + $this->assertEqual($result, $expected); + $this->assertEqual($this->Html->getAttribute('_minimizedAttributeFormat'), 'format'); + + $this->expectError(); + $result = $this->Html->loadConfig('wrong_file'); + $this->assertFalse($result); + + $this->expectError(); + $result = $this->Html->loadConfig(array('htmlhelper_tags', 'wrong_reader'), $path); + $this->assertFalse($result); + } + /** * test parsing attributes. * diff --git a/cake/tests/test_app/config/htmlhelper_minimized.ini b/cake/tests/test_app/config/htmlhelper_minimized.ini new file mode 100644 index 000000000..e6a722d67 --- /dev/null +++ b/cake/tests/test_app/config/htmlhelper_minimized.ini @@ -0,0 +1,2 @@ +minimizedAttributeFormat = "format" + diff --git a/cake/tests/test_app/config/htmlhelper_tags.php b/cake/tests/test_app/config/htmlhelper_tags.php new file mode 100644 index 000000000..abff9cdf5 --- /dev/null +++ b/cake/tests/test_app/config/htmlhelper_tags.php @@ -0,0 +1,8 @@ + array( + 'form' => 'start form', + 'formend' => 'finish form' + ) +); \ No newline at end of file From 55c557d5a154e1880a0191c1a8305697fe51713e Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 19:26:13 -0200 Subject: [PATCH 09/15] Support to read ini files without section in IniReader. --- cake/libs/config/ini_reader.php | 7 ++++++- cake/tests/cases/libs/config/ini_reader.test.php | 16 ++++++++++++++++ cake/tests/test_app/config/no_section.ini | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 cake/tests/test_app/config/no_section.ini diff --git a/cake/libs/config/ini_reader.php b/cake/libs/config/ini_reader.php index 915bf9498..e20f8dcfb 100644 --- a/cake/libs/config/ini_reader.php +++ b/cake/libs/config/ini_reader.php @@ -77,7 +77,12 @@ class IniReader implements ConfigReaderInterface { } else { $values = array(); foreach ($contents as $section => $attribs) { - $values[$section] = $this->_parseNestedValues($attribs); + if (is_array($attribs)) { + $values[$section] = $this->_parseNestedValues($attribs); + } else { + $parse = $this->_parseNestedValues(array($attribs)); + $values[$section] = array_shift($parse); + } } } return $values; diff --git a/cake/tests/cases/libs/config/ini_reader.test.php b/cake/tests/cases/libs/config/ini_reader.test.php index 2fb8eb2dd..3db8bb942 100644 --- a/cake/tests/cases/libs/config/ini_reader.test.php +++ b/cake/tests/cases/libs/config/ini_reader.test.php @@ -64,6 +64,22 @@ class IniReaderTest extends CakeTestCase { $this->assertEquals('administrators', $config['groups']); } +/** + * test without section + * + * @return void + */ + public function testReadingWithoutSection() { + $reader = new IniReader($this->path); + $config = $reader->read('no_section.ini'); + + $expected = array( + 'some_key' => 'some_value', + 'bool_key' => true + ); + $this->assertEquals($config, $expected); + } + /** * test that names with .'s get exploded into arrays. * diff --git a/cake/tests/test_app/config/no_section.ini b/cake/tests/test_app/config/no_section.ini new file mode 100644 index 000000000..6e6fbb7a0 --- /dev/null +++ b/cake/tests/test_app/config/no_section.ini @@ -0,0 +1,2 @@ +some_key = some_value +bool_key = 1 From 5b8f680d43874e98ac3be2ba40045c61777b05b2 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 20:00:06 -0200 Subject: [PATCH 10/15] Throwing exception instead notice in loadConfig. --- cake/libs/view/helpers/html.php | 40 +++++++++---------- .../cases/libs/view/helpers/html.test.php | 4 +- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index 21543f311..436941a81 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -937,34 +937,30 @@ class HtmlHelper extends AppHelper { $reader = $configFile[1]; } } else { - return trigger_error(__('Cannot load the configuration file. Wrong "configFile" configuration.'), E_USER_NOTICE); + throw new ConfigureException(__('Cannot load the configuration file. Wrong "configFile" configuration.')); } $readerClass = Inflector::camelize($reader) . 'Reader'; if (!App::import('Lib', 'config/' . $readerClass)) { - return trigger_error(__('Cannot load the configuration file. Unknown reader.'), E_USER_NOTICE); + throw new ConfigureException(__('Cannot load the configuration file. Unknown reader.')); } - try { - $readerObj = new $readerClass($path); - $configs = $readerObj->read($file); - if (isset($configs['tags']) && is_array($configs['tags'])) { - $this->_tags = array_merge($this->_tags, $configs['tags']); - } - if (isset($configs['minimizedAttributes']) && is_array($configs['minimizedAttributes'])) { - $this->_minimizedAttributes = array_merge($this->_minimizedAttributes, $configs['minimizedAttributes']); - } - if (isset($configs['docTypes']) && is_array($configs['docTypes'])) { - $this->__docTypes = array_merge($this->__docTypes, $configs['docTypes']); - } - if (isset($configs['attributeFormat'])) { - $this->_attributeFormat = $configs['attributeFormat']; - } - if (isset($configs['minimizedAttributeFormat'])) { - $this->_minimizedAttributeFormat = $configs['minimizedAttributeFormat']; - } - } catch (Exception $e) { - return trigger_error(__('Cannot load the configuration file. Failed to load the file.'), E_USER_NOTICE); + $readerObj = new $readerClass($path); + $configs = $readerObj->read($file); + if (isset($configs['tags']) && is_array($configs['tags'])) { + $this->_tags = array_merge($this->_tags, $configs['tags']); + } + if (isset($configs['minimizedAttributes']) && is_array($configs['minimizedAttributes'])) { + $this->_minimizedAttributes = array_merge($this->_minimizedAttributes, $configs['minimizedAttributes']); + } + if (isset($configs['docTypes']) && is_array($configs['docTypes'])) { + $this->__docTypes = array_merge($this->__docTypes, $configs['docTypes']); + } + if (isset($configs['attributeFormat'])) { + $this->_attributeFormat = $configs['attributeFormat']; + } + if (isset($configs['minimizedAttributeFormat'])) { + $this->_minimizedAttributeFormat = $configs['minimizedAttributeFormat']; } return $configs; } diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index a7a4cfbec..c2226acac 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -1400,11 +1400,11 @@ class HtmlHelperTest extends CakeTestCase { $this->assertEqual($result, $expected); $this->assertEqual($this->Html->getAttribute('_minimizedAttributeFormat'), 'format'); - $this->expectError(); + $this->expectException('ConfigureException'); $result = $this->Html->loadConfig('wrong_file'); $this->assertFalse($result); - $this->expectError(); + $this->expectException('ConfigureException'); $result = $this->Html->loadConfig(array('htmlhelper_tags', 'wrong_reader'), $path); $this->assertFalse($result); } From be98491413a217518b9741cb70d644b328276081 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 20:27:46 -0200 Subject: [PATCH 11/15] Ini/Php readers now read files with/without extension. --- cake/libs/config/ini_reader.php | 6 ++++++ cake/libs/config/php_reader.php | 12 +++++++++--- cake/tests/cases/libs/config/ini_reader.test.php | 11 +++++++++++ cake/tests/cases/libs/config/php_reader.test.php | 5 +++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/cake/libs/config/ini_reader.php b/cake/libs/config/ini_reader.php index e20f8dcfb..7ab9694ce 100644 --- a/cake/libs/config/ini_reader.php +++ b/cake/libs/config/ini_reader.php @@ -71,6 +71,12 @@ class IniReader implements ConfigReaderInterface { */ public function read($file) { $filename = $this->_path . $file; + if (!file_exists($filename)) { + $filename .= '.ini'; + if (!file_exists($filename)) { + throw new ConfigureException(__('Could not load configuration files: %s or %s', substr($filename, 0, -4), $filename)); + } + } $contents = parse_ini_file($filename, true); if (!empty($this->_section) && isset($contents[$this->_section])) { $values = $this->_parseNestedValues($contents[$this->_section]); diff --git a/cake/libs/config/php_reader.php b/cake/libs/config/php_reader.php index c122f0808..acd0f94df 100644 --- a/cake/libs/config/php_reader.php +++ b/cake/libs/config/php_reader.php @@ -57,15 +57,21 @@ class PhpReader implements ConfigReaderInterface { if (strpos($key, '..') !== false) { throw new ConfigureException(__('Cannot load configuration files with ../ in them.')); } + if (substr($key, -4) === '.php') { + $key = substr($key, 0, -4); + } list($plugin, $key) = pluginSplit($key); if ($plugin) { - $file = App::pluginPath($plugin) . 'config' . DS . $key . '.php'; + $file = App::pluginPath($plugin) . 'config' . DS . $key; } else { - $file = $this->_path . $key . '.php'; + $file = $this->_path . $key; } if (!file_exists($file)) { - throw new ConfigureException(__('Could not load configuration file: ') . $file); + $file .= '.php'; + if (!file_exists($file)) { + throw new ConfigureException(__('Could not load configuration files: %s or %s', substr($file, 0, -4), $file)); + } } include $file; if (!isset($config)) { diff --git a/cake/tests/cases/libs/config/ini_reader.test.php b/cake/tests/cases/libs/config/ini_reader.test.php index 3db8bb942..4f077873a 100644 --- a/cake/tests/cases/libs/config/ini_reader.test.php +++ b/cake/tests/cases/libs/config/ini_reader.test.php @@ -114,4 +114,15 @@ class IniReaderTest extends CakeTestCase { $this->assertFalse($config['bools']['test_null']); } + +/** + * test read file without extension + * + * @return void + */ + public function testReadingWithoutExtension() { + $reader = new IniReader($this->path); + $config = $reader->read('nested'); + $this->assertTrue($config['bools']['test_on']); + } } \ No newline at end of file diff --git a/cake/tests/cases/libs/config/php_reader.test.php b/cake/tests/cases/libs/config/php_reader.test.php index 63957ea62..a1d3034fc 100644 --- a/cake/tests/cases/libs/config/php_reader.test.php +++ b/cake/tests/cases/libs/config/php_reader.test.php @@ -38,6 +38,9 @@ class PhpReaderTest extends CakeTestCase { $values = $reader->read('var_test'); $this->assertEquals('value', $values['Read']); $this->assertEquals('buried', $values['Deep']['Deeper']['Deepest']); + + $values = $reader->read('var_test.php'); + $this->assertEquals('value', $values['Read']); } /** @@ -84,7 +87,9 @@ class PhpReaderTest extends CakeTestCase { ), true); $reader = new PhpReader($this->path); $result = $reader->read('TestPlugin.load'); + $this->assertTrue(isset($result['plugin_load'])); + $result = $reader->read('TestPlugin.load.php'); $this->assertTrue(isset($result['plugin_load'])); } } From d933d6bd73bf650c8cccf8bbc4ac2f3e532b537b Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Sun, 23 Jan 2011 20:51:56 -0200 Subject: [PATCH 12/15] Assigning the helper object in view class, avoiding to use __get magic for each call. --- cake/libs/view/view.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cake/libs/view/view.php b/cake/libs/view/view.php index 7ff7ed9fa..35a886fbc 100644 --- a/cake/libs/view/view.php +++ b/cake/libs/view/view.php @@ -624,7 +624,8 @@ class View extends Object { public function loadHelpers() { $helpers = HelperCollection::normalizeObjectArray($this->helpers); foreach ($helpers as $name => $properties) { - $this->Helpers->load($properties['class'], $properties['settings']); + list($plugin, $class) = pluginSplit($properties['class']); + $this->{$class} = $this->Helpers->load($properties['class'], $properties['settings']); } $this->_helpersLoaded = true; } From 95713fbf3b082d094bd7a87c371b3d0029d14eb7 Mon Sep 17 00:00:00 2001 From: Juan Basso Date: Tue, 25 Jan 2011 01:18:39 -0200 Subject: [PATCH 13/15] Separated the tests for HtmlHelper::loadConfig() with exception in different methods. --- .../cases/libs/view/helpers/html.test.php | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index c2226acac..4da61890d 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -1399,14 +1399,27 @@ class HtmlHelperTest extends CakeTestCase { ); $this->assertEqual($result, $expected); $this->assertEqual($this->Html->getAttribute('_minimizedAttributeFormat'), 'format'); + } - $this->expectException('ConfigureException'); +/** + * testLoadConfigWrongFile method + * + * @return void + * @expectedException ConfigureException + */ + public function testLoadConfigWrongFile() { $result = $this->Html->loadConfig('wrong_file'); - $this->assertFalse($result); + } - $this->expectException('ConfigureException'); +/** + * testLoadConfigWrongReader method + * + * @return void + * @expectedException ConfigureException + */ + public function testLoadConfigWrongReader() { + $path = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'config'. DS; $result = $this->Html->loadConfig(array('htmlhelper_tags', 'wrong_reader'), $path); - $this->assertFalse($result); } /** From 161d3ea5fb64a24d50cdf9d0843a364be35c0450 Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 26 Jan 2011 19:33:06 +0530 Subject: [PATCH 14/15] Removed from comments references to DBOs which are no longer available. Closes #1479 --- app/config/database.php.default | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/config/database.php.default b/app/config/database.php.default index 2078240ea..9fb8e9e98 100644 --- a/app/config/database.php.default +++ b/app/config/database.php.default @@ -29,7 +29,6 @@ * * driver => The name of a supported driver; valid options are as follows: * mysql - MySQL 4 & 5, - * mysqli - MySQL 4 & 5 Improved Interface (PHP5 only), * sqlite - SQLite (PHP5 only), * postgres - PostgreSQL 7 and higher, * mssql - Microsoft SQL Server 2000 and higher, @@ -43,19 +42,18 @@ * Determines whether or not the database should use a persistent connection * * host => - * the host you connect to the database. To add a socket or port number, use 'port' => # + * the host you connect to the database. To add a socket or port number, use 'port' => # * * prefix => * Uses the given prefix for all the tables in this database. This setting can be overridden * on a per-table basis with the Model::$tablePrefix property. * * schema => - * For Postgresspecifies which schema you would like to use the tables in. Postgres defaults to - * 'public', DB2 defaults to empty. + * For Postgres specifies which schema you would like to use the tables in. Postgres defaults to 'public'. * * encoding => - * For MySQL, MySQLi, Postgres specifies the character encoding to use when connecting to the - * database. Uses database default. + * For MySQL, Postgres specifies the character encoding to use when connecting to the + * database. Uses database default not specified. * */ class DATABASE_CONFIG { From e99f090ee0fb7ec531c40848bcfe43a6a1b1a1f5 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 27 Jan 2011 18:32:51 -0800 Subject: [PATCH 15/15] Fixed issue where ClassRegistry alias was incorrectly set --- .../cases/libs/controller_test_case.test.php | 32 ++++++++++++++++++- cake/tests/lib/controller_test_case.php | 4 +-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cake/tests/cases/libs/controller_test_case.test.php b/cake/tests/cases/libs/controller_test_case.test.php index 6d4812937..1ffb518c6 100644 --- a/cake/tests/cases/libs/controller_test_case.test.php +++ b/cake/tests/cases/libs/controller_test_case.test.php @@ -76,6 +76,20 @@ if (!class_exists('PostsController')) { } } +/** + * ControllerTestCaseTest controller + */ +class ControllerTestCaseTestController extends AppController { + +/** + * Uses array + * + * @param array + */ + public $uses = array('TestPlugin.TestPluginComment'); + +} + /** * ControllerTestCaseTest @@ -90,7 +104,7 @@ class ControllerTestCaseTest extends CakeTestCase { * @var array * @access public */ - public $fixtures = array('core.post', 'core.author'); + public $fixtures = array('core.post', 'core.author', 'core.test_plugin_comment'); /** * reset environment. @@ -201,6 +215,22 @@ class ControllerTestCaseTest extends CakeTestCase { $result = ClassRegistry::init('TestPlugin.TestPluginComment'); $this->assertInstanceOf('TestPluginComment', $result); + + $Tests = $this->Case->generate('ControllerTestCaseTest', array( + 'models' => array( + 'TestPlugin.TestPluginComment' => array('save') + ) + )); + $this->assertInstanceOf('TestPluginComment', $Tests->TestPluginComment); + $Tests->TestPluginComment->expects($this->at(0)) + ->method('save') + ->will($this->returnValue(true)); + $Tests->TestPluginComment->expects($this->at(1)) + ->method('save') + ->will($this->returnValue(false)); + $this->assertTrue($Tests->TestPluginComment->save(array())); + $this->assertFalse($Tests->TestPluginComment->save(array())); + } /** diff --git a/cake/tests/lib/controller_test_case.php b/cake/tests/lib/controller_test_case.php index 217463ecf..150bf12a5 100644 --- a/cake/tests/lib/controller_test_case.php +++ b/cake/tests/lib/controller_test_case.php @@ -280,8 +280,8 @@ class ControllerTestCase extends CakeTestCase { list($plugin, $name) = pluginSplit($model); $config = array_merge((array)$config, array('name' => $model)); $_model = $this->getMock($name, $methods, array($config)); - ClassRegistry::removeObject($model); - ClassRegistry::addObject($model, $_model); + ClassRegistry::removeObject($name); + ClassRegistry::addObject($name, $_model); } foreach ($mocks['components'] as $component => $methods) {