From a15481bbe9aae5796e695655e7331e7c25e0c20e Mon Sep 17 00:00:00 2001 From: Ceeram Date: Fri, 28 Sep 2012 14:50:32 +0200 Subject: [PATCH 1/2] starting refactor Form->input --- .../Test/Case/View/Helper/FormHelperTest.php | 2 +- lib/Cake/View/Helper/FormHelper.php | 483 ++++++++++-------- 2 files changed, 280 insertions(+), 205 deletions(-) diff --git a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php index 6008fc414..e8de415d1 100644 --- a/lib/Cake/Test/Case/View/Helper/FormHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/FormHelperTest.php @@ -6117,7 +6117,7 @@ class FormHelperTest extends CakeTestCase { 'label' => 'Current Text', 'value' => "GREAT®", 'rows' => '15', 'cols' => '75' )); $expected = array( - 'div' => array('class' => 'input text'), + 'div' => array('class' => 'input textarea'), 'label' => array('for' => 'PostContent'), 'Current Text', '/label', diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index 4ec5e403b..ef45b5f2e 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -944,88 +944,275 @@ class FormHelper extends AppHelper { */ public function input($fieldName, $options = array()) { $this->setEntity($fieldName); + $options = $this->_parseOptions($fieldName, $options); + $divOptions = $this->_divOptions($options); + unset($options['div']); + + if ($options['type'] === 'radio' && isset($options['options'])) { + $radioOptions = (array)$options['options']; + unset($options['options']); + } + + $label = $this->_getLabel($fieldName, $options); + if ($options['type'] !== 'radio') { + unset($options['label']); + } + + $error = $this->_extractOption('error', $options, null); + unset($options['error']); + + $errorMessage = $this->_extractOption('errorMessage', $options, true); + unset($options['errorMessage']); + + $selected = $this->_extractOption('selected', $options, null); + unset($options['selected']); + + if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time') { + $dateFormat = $this->_extractOption('dateFormat', $options, 'MDY'); + $timeFormat = $this->_extractOption('timeFormat', $options, 12); + unset($options['dateFormat'], $options['timeFormat']); + } + + $type = $options['type']; + $out = array('before' => $options['before'], 'label' => $label, 'between' => $options['between'], 'after' => $options['after']); + $format = $this->_getFormat($options); + + unset($options['type'], $options['before'], $options['between'], $options['after'], $options['format']); + + $out['error'] = null; + if ($type != 'hidden' && $error !== false) { + $errMsg = $this->error($fieldName, $error); + if ($errMsg) { + $divOptions = $this->addClass($divOptions, 'error'); + if ($errorMessage) { + $out['error'] = $errMsg; + } + } + } + + if ($type === 'radio' && isset($out['between'])) { + $options['between'] = $out['between']; + $out['between'] = null; + } + $out['input'] = $this->_getInput(compact('type', 'fieldName', 'options', 'radioOptions', 'selected', 'dateFormat', 'timeFormat')); + + $output = ''; + foreach ($format as $element) { + $output .= $out[$element]; + } + + if (!empty($divOptions['tag'])) { + $tag = $divOptions['tag']; + unset($divOptions['tag']); + $output = $this->Html->tag($tag, $output, $divOptions); + } + return $output; + } + +/** + * + * @param type $args + * @return type + */ + protected function _getInput($args) { + extract($args); + switch ($type) { + case 'hidden': + return $this->hidden($fieldName, $options); + case 'checkbox': + return $this->checkbox($fieldName, $options); + case 'radio': + return $this->radio($fieldName, $radioOptions, $options); + case 'file': + return $this->file($fieldName, $options); + case 'select': + $options += array('options' => array(), 'value' => $selected); + $list = $options['options']; + unset($options['options']); + return $this->select($fieldName, $list, $options); + case 'time': + $options['value'] = $selected; + return $this->dateTime($fieldName, null, $timeFormat, $options); + case 'date': + $options['value'] = $selected; + return $this->dateTime($fieldName, $dateFormat, null, $options); + case 'datetime': + $options['value'] = $selected; + return $this->dateTime($fieldName, $dateFormat, $timeFormat, $options); + case 'textarea': + return $this->textarea($fieldName, $options + array('cols' => '30', 'rows' => '6')); + case 'url': + return $this->text($fieldName, array('type' => 'url') + $options); + default: + return $this->{$type}($fieldName, $options); + } + } + +/** + * + * @param type $fieldName + * @param type $options + * @return array + */ + protected function _parseOptions($fieldName, $options) { $options = array_merge( array('before' => null, 'between' => null, 'after' => null, 'format' => null), $this->_inputDefaults, $options ); + if (!isset($options['type'])) { + $options = $this->_magicOptions($options); + } + + if (in_array($options['type'], array('checkbox', 'radio', 'select'))) { + $options = $this->_optionsOptions($options); + } + + if (isset($options['rows']) || isset($options['cols'])) { + $options['type'] = 'textarea'; + } + + if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time' || $options['type'] === 'select') { + $options += array('empty' => false); + } + return $options; + } + +/** + * + * @param type $options + * @return array + */ + protected function _optionsOptions($options) { + if (isset($options['options'])) { + return $options; + } + $varName = Inflector::variable( + Inflector::pluralize(preg_replace('/_id$/', '', $this->field())) + ); + $varOptions = $this->_View->getVar($varName); + if (!is_array($varOptions)) { + return $options; + } + if ($options['type'] !== 'radio') { + $options['type'] = 'select'; + } + $options['options'] = $varOptions; + return $options; + } + +/** + * + * @param type $options + * @return array + */ + protected function _magicOptions($options) { $modelKey = $this->model(); $fieldKey = $this->field(); - - if (!isset($options['type'])) { - $magicType = true; - $options['type'] = 'text'; - if (isset($options['options'])) { - $options['type'] = 'select'; - } elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) { - $options['type'] = 'password'; - } elseif (isset($options['checked'])) { - $options['type'] = 'checkbox'; - } elseif ($fieldDef = $this->_introspectModel($modelKey, 'fields', $fieldKey)) { - $type = $fieldDef['type']; - $primaryKey = $this->fieldset[$modelKey]['key']; - } - - if (isset($type)) { - $map = array( - 'string' => 'text', 'datetime' => 'datetime', - 'boolean' => 'checkbox', 'timestamp' => 'datetime', - 'text' => 'textarea', 'time' => 'time', - 'date' => 'date', 'float' => 'number', - 'integer' => 'number' - ); - - if (isset($this->map[$type])) { - $options['type'] = $this->map[$type]; - } elseif (isset($map[$type])) { - $options['type'] = $map[$type]; - } - if ($fieldKey == $primaryKey) { - $options['type'] = 'hidden'; - } - if ( - $options['type'] === 'number' && - $type === 'float' && - !isset($options['step']) - ) { - $options['step'] = 'any'; - } - } - if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') { - $options['type'] = 'select'; - } - - if ($modelKey === $fieldKey) { - $options['type'] = 'select'; - if (!isset($options['multiple'])) { - $options['multiple'] = 'multiple'; - } - } - } - $types = array('checkbox', 'radio', 'select'); - - if ( - (!isset($options['options']) && in_array($options['type'], $types)) || - (isset($magicType) && in_array($options['type'], array('text', 'number'))) - ) { - $varName = Inflector::variable( - Inflector::pluralize(preg_replace('/_id$/', '', $fieldKey)) + $options['type'] = 'text'; + if (isset($options['options'])) { + $options['type'] = 'select'; + } elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) { + $options['type'] = 'password'; + } elseif (isset($options['checked'])) { + $options['type'] = 'checkbox'; + } elseif ($fieldDef = $this->_introspectModel($modelKey, 'fields', $fieldKey)) { + $type = $fieldDef['type']; + $primaryKey = $this->fieldset[$modelKey]['key']; + $map = array( + 'string' => 'text', 'datetime' => 'datetime', + 'boolean' => 'checkbox', 'timestamp' => 'datetime', + 'text' => 'textarea', 'time' => 'time', + 'date' => 'date', 'float' => 'number', + 'integer' => 'number' ); - $varOptions = $this->_View->getVar($varName); - if (is_array($varOptions)) { - if ($options['type'] !== 'radio') { - $options['type'] = 'select'; - } - $options['options'] = $varOptions; - } - if ($options['type'] === 'select' && array_key_exists('step', $options)) { - unset($options['step']); + if (isset($this->map[$type])) { + $options['type'] = $this->map[$type]; + } elseif (isset($map[$type])) { + $options['type'] = $map[$type]; + } + if ($fieldKey == $primaryKey) { + $options['type'] = 'hidden'; + } + if ( + $options['type'] === 'number' && + $type === 'float' && + !isset($options['step']) + ) { + $options['step'] = 'any'; } } + if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') { + $options['type'] = 'select'; + } + + if ($modelKey === $fieldKey) { + $options['type'] = 'select'; + if (!isset($options['multiple'])) { + $options['multiple'] = 'multiple'; + } + } + if (in_array($options['type'], array('text', 'number'))) { + $options = $this->_optionsOptions($options); + } + if ($options['type'] === 'select' && array_key_exists('step', $options)) { + unset($options['step']); + } + $options = $this->_maxLength($options); + return $options; + } + +/** + * + * @param type $options + * @return array + */ + protected function _getFormat($options) { + if ($options['type'] == 'hidden') { + return array('input'); + } + if (is_array($options['format']) && in_array('input', $options['format'])) { + return $options['format']; + } + if ($options['type'] == 'checkbox') { + return array('before', 'input', 'between', 'label', 'after', 'error'); + } + return array('before', 'label', 'between', 'input', 'after', 'error'); + } + +/** + * + * @param type $fieldName + * @param type $options + * @return boolean|string false or Generated label element + */ + protected function _getLabel($fieldName, $options) { + if ($options['type'] === 'radio') { + return false; + } + + $label = null; + if (isset($options['label'])) { + $label = $options['label']; + } + + if ($label === false) { + return false; + } + return $this->_inputLabel($fieldName, $label, $options); + } + +/** + * + * @param type $options + * @return array + */ + protected function _maxLength($options) { + $fieldDef = $this->_introspectModel($this->model(), 'fields', $this->field()); $autoLength = ( !array_key_exists('maxlength', $options) && isset($fieldDef['length']) && @@ -1038,150 +1225,38 @@ class FormHelper extends AppHelper { if ($autoLength && $fieldDef['type'] == 'float') { $options['maxlength'] = array_sum(explode(',', $fieldDef['length'])) + 1; } + return $options; + } - $divOptions = array(); +/** + * + * @param array $options + * @return array + */ + protected function _divOptions($options) { + if ($options['type'] === 'hidden') { + return array(); + } $div = $this->_extractOption('div', $options, true); - unset($options['div']); - - if (!empty($div)) { - $divOptions['class'] = 'input'; - $divOptions = $this->addClass($divOptions, $options['type']); - if (is_string($div)) { - $divOptions['class'] = $div; - } elseif (is_array($div)) { - $divOptions = array_merge($divOptions, $div); - } - if ($this->_introspectModel($modelKey, 'validates', $fieldKey)) { - $divOptions = $this->addClass($divOptions, 'required'); - } - if (!isset($divOptions['tag'])) { - $divOptions['tag'] = 'div'; - } + if (!$div) { + return array(); } - $label = null; - if (isset($options['label']) && $options['type'] !== 'radio') { - $label = $options['label']; - unset($options['label']); + $divOptions = array('class' => 'input'); + $divOptions = $this->addClass($divOptions, $options['type']); + if (is_string($div)) { + $divOptions['class'] = $div; + } elseif (is_array($div)) { + $divOptions = array_merge($divOptions, $div); } - if ($options['type'] === 'radio') { - $label = false; - if (isset($options['options'])) { - $radioOptions = (array)$options['options']; - unset($options['options']); - } + if ($this->_introspectModel($this->model(), 'validates', $this->field())) { + $divOptions = $this->addClass($divOptions, 'required'); } - - if ($label !== false) { - $label = $this->_inputLabel($fieldName, $label, $options); + if (!isset($divOptions['tag'])) { + $divOptions['tag'] = 'div'; } - - $error = $this->_extractOption('error', $options, null); - unset($options['error']); - - $errorMessage = $this->_extractOption('errorMessage', $options, true); - unset($options['errorMessage']); - - $selected = $this->_extractOption('selected', $options, null); - unset($options['selected']); - - if (isset($options['rows']) || isset($options['cols'])) { - $options['type'] = 'textarea'; - } - - if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time' || $options['type'] === 'select') { - $options += array('empty' => false); - } - if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time') { - $dateFormat = $this->_extractOption('dateFormat', $options, 'MDY'); - $timeFormat = $this->_extractOption('timeFormat', $options, 12); - unset($options['dateFormat'], $options['timeFormat']); - } - - $type = $options['type']; - $out = array_merge( - array('before' => null, 'label' => null, 'between' => null, 'input' => null, 'after' => null, 'error' => null), - array('before' => $options['before'], 'label' => $label, 'between' => $options['between'], 'after' => $options['after']) - ); - $format = null; - if (is_array($options['format']) && in_array('input', $options['format'])) { - $format = $options['format']; - } - unset($options['type'], $options['before'], $options['between'], $options['after'], $options['format']); - - switch ($type) { - case 'hidden': - $input = $this->hidden($fieldName, $options); - $format = array('input'); - unset($divOptions); - break; - case 'checkbox': - $input = $this->checkbox($fieldName, $options); - $format = $format ? $format : array('before', 'input', 'between', 'label', 'after', 'error'); - break; - case 'radio': - if (isset($out['between'])) { - $options['between'] = $out['between']; - $out['between'] = null; - } - $input = $this->radio($fieldName, $radioOptions, $options); - break; - case 'file': - $input = $this->file($fieldName, $options); - break; - case 'select': - $options += array('options' => array(), 'value' => $selected); - $list = $options['options']; - unset($options['options']); - $input = $this->select($fieldName, $list, $options); - break; - case 'time': - $options['value'] = $selected; - $input = $this->dateTime($fieldName, null, $timeFormat, $options); - break; - case 'date': - $options['value'] = $selected; - $input = $this->dateTime($fieldName, $dateFormat, null, $options); - break; - case 'datetime': - $options['value'] = $selected; - $input = $this->dateTime($fieldName, $dateFormat, $timeFormat, $options); - break; - case 'textarea': - $input = $this->textarea($fieldName, $options + array('cols' => '30', 'rows' => '6')); - break; - case 'url': - $input = $this->text($fieldName, array('type' => 'url') + $options); - break; - default: - $input = $this->{$type}($fieldName, $options); - } - - if ($type != 'hidden' && $error !== false) { - $errMsg = $this->error($fieldName, $error); - if ($errMsg) { - $divOptions = $this->addClass($divOptions, 'error'); - if ($errorMessage) { - $out['error'] = $errMsg; - } - } - } - - $out['input'] = $input; - $format = $format ? $format : array('before', 'label', 'between', 'input', 'after', 'error'); - $output = ''; - foreach ($format as $element) { - $output .= $out[$element]; - unset($out[$element]); - } - - if (!empty($divOptions['tag'])) { - $tag = $divOptions['tag']; - unset($divOptions['tag']); - $output = $this->Html->tag($tag, $output, $divOptions); - } - return $output; + return $divOptions; } /** From 2d908885c86de68f0e0c4cbfd88bce811d23aa54 Mon Sep 17 00:00:00 2001 From: Ceeram Date: Sat, 8 Dec 2012 18:10:36 +0100 Subject: [PATCH 2/2] adding short descriptions in docblock --- lib/Cake/View/Helper/FormHelper.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php index ef45b5f2e..a00bef997 100644 --- a/lib/Cake/View/Helper/FormHelper.php +++ b/lib/Cake/View/Helper/FormHelper.php @@ -944,7 +944,7 @@ class FormHelper extends AppHelper { */ public function input($fieldName, $options = array()) { $this->setEntity($fieldName); - $options = $this->_parseOptions($fieldName, $options); + $options = $this->_parseOptions($options); $divOptions = $this->_divOptions($options); unset($options['div']); @@ -1011,6 +1011,7 @@ class FormHelper extends AppHelper { } /** + * Generates an input element * * @param type $args * @return type @@ -1050,12 +1051,12 @@ class FormHelper extends AppHelper { } /** + * Generates input options array * - * @param type $fieldName * @param type $options - * @return array + * @return array Options */ - protected function _parseOptions($fieldName, $options) { + protected function _parseOptions($options) { $options = array_merge( array('before' => null, 'between' => null, 'after' => null, 'format' => null), $this->_inputDefaults, @@ -1081,6 +1082,7 @@ class FormHelper extends AppHelper { } /** + * Generates list of options for multiple select * * @param type $options * @return array @@ -1104,6 +1106,7 @@ class FormHelper extends AppHelper { } /** + * Magically set option type and corresponding options * * @param type $options * @return array @@ -1167,6 +1170,7 @@ class FormHelper extends AppHelper { } /** + * Generate format options * * @param type $options * @return array @@ -1185,6 +1189,7 @@ class FormHelper extends AppHelper { } /** + * Generate label for input * * @param type $fieldName * @param type $options @@ -1207,6 +1212,7 @@ class FormHelper extends AppHelper { } /** + * Calculates maxlength option * * @param type $options * @return array @@ -1229,6 +1235,7 @@ class FormHelper extends AppHelper { } /** + * Generate div options for input * * @param array $options * @return array