Permalink
Browse files

General refactoring of the automatic input type selection

  • Loading branch information...
1 parent 8c536d1 commit ecfd4cf9f48f550331b94a500e07f67c190b148c @lorenzo lorenzo committed Feb 23, 2014
Showing with 74 additions and 91 deletions.
  1. +74 −91 src/View/Helper/FormHelper.php
@@ -68,7 +68,13 @@ class FormHelper extends Helper {
* @var array
*/
public $settings = [
- 'errorClass' => 'form-error'
+ 'errorClass' => 'form-error',
+ 'typeMap' => [
+ 'string' => 'text', 'datetime' => 'datetime', 'boolean' => 'checkbox',
+ 'timestamp' => 'datetime', 'text' => 'textarea', 'time' => 'time',
+ 'date' => 'date', 'float' => 'number', 'integer' => 'number',
+ 'decimal' => 'number', 'binary' => 'file', 'uuid' => 'string'
+ ]
];
/**
@@ -856,7 +862,7 @@ public function input($fieldName, $options = array()) {
'options' => null,
'templates' => []
];
- $options = $this->_parseOptions($options);
+ $options = $this->_parseOptions($fieldName, $options);
$label = $this->_getLabel($fieldName, $options);
if ($options['type'] !== 'radio') {
@@ -924,18 +930,12 @@ protected function _getInput($args) {
* @param array $options
* @return array Options
*/
- protected function _parseOptions($options) {
+ protected function _parseOptions($fieldName, $options) {
if (!empty($options['type'])) {
- $options = $this->_magicOptions($options);
+ $options['type'] = $this->_inputType($fieldName, $options);
}
- if (in_array($options['type'], ['radio', 'select'])) {
- $options = $this->_optionsOptions($options);
- }
-
- if (isset($options['rows']) || isset($options['cols'])) {
- $options['type'] = 'textarea';
- }
+ $options = $this->_magicOptions($fieldName, $options);
if (in_array(['datetime', 'date', 'time', 'select'], $options['type'])) {
$options += ['empty' => false];
@@ -944,18 +944,53 @@ protected function _parseOptions($options) {
return $options;
}
+ protected function _inputType($fieldName, $options) {
+ $context = $this->_getContext();
+ $primaryKey = $context->primaryKey();
+
+ if (in_array($fieldName, $primaryKey)) {
+ return 'hidden';
+ }
+
+ if (substr($fieldName, -3) === '_id') {
+ return 'select';
+ }
+
+ $internalType = $context->type($fieldName);
+ $map = $this->settings['typeMap'];
+ $type = isset($map[$internalType]) ? $map[$internalType] : 'text';
+
+ switch (true) {
+ case isset($options['checked']) :
+ return 'checkbox';
+ case isset($options['options']) :
+ return 'select';
+ case in_array($fieldName, ['passwd', 'password']) :
+ return 'password';
+ case in_array($fieldName, ['tel', 'telephone', 'phone']) :
+ return 'tel';
+ case $fieldName === 'email':
+ return 'email';
+ case isset($options['rows']) || isset($options['cols']) :
+ return 'textarea';
+ }
+
+ return $type;
+ }
+
/**
* Generates list of options for multiple select
*
* @param array $options
* @return array
*/
- protected function _optionsOptions($options) {
+ protected function _optionsOptions($fieldName, $options) {
if (isset($options['options'])) {
return $options;
}
+
$varName = Inflector::variable(
- Inflector::pluralize(preg_replace('/_id$/', '', $this->field()))
+ Inflector::pluralize(preg_replace('/_id$/', '', $fieldName))
);
$varOptions = $this->_View->get($varName);
if (!is_array($varOptions)) {
@@ -974,70 +1009,40 @@ protected function _optionsOptions($options) {
* @param array $options
* @return array
*/
- protected function _magicOptions($options) {
- $modelKey = $this->model();
- $fieldKey = $this->field();
- $options['type'] = 'text';
- if (isset($options['options'])) {
- $options['type'] = 'select';
- } elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) {
- $options['type'] = 'password';
- } elseif (in_array($fieldKey, array('tel', 'telephone', 'phone'))) {
- $options['type'] = 'tel';
- } elseif ($fieldKey === 'email') {
- $options['type'] = 'email';
- } 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', 'decimal' => 'number',
- 'binary' => 'file'
- );
-
- 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' &&
- !isset($options['step'])
- ) {
- if ($type === 'decimal') {
- $decimalPlaces = substr($fieldDef['length'], strpos($fieldDef['length'], ',') + 1);
- $options['step'] = sprintf('%.' . $decimalPlaces . 'F', pow(10, -1 * $decimalPlaces));
- } elseif ($type === 'float') {
- $options['step'] = 'any';
- }
+ protected function _magicOptions($fieldName, $options) {
+ $context = $this->_getContext();
+ $type = $context->type($fieldName);
+ $fielDef = $context->attributes($fieldName);
+
+ if ($options['type'] === 'number' && !isset($options['step'])) {
+ if ($type === 'decimal') {
+ $decimalPlaces = substr($fieldDef['length'], strpos($fieldDef['length'], ',') + 1);
+ $options['step'] = sprintf('%.' . $decimalPlaces . 'F', pow(10, -1 * $decimalPlaces));
+ } elseif ($type === 'float') {
+ $options['step'] = 'any';
}
}
- if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') {
- $options['type'] = 'select';
- }
+ // Missing HABTM
+ //...
- 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 (in_array($options['type'], ['text', 'number', 'radio', 'select'])) {
+ $options = $this->_optionsOptions($fieldName, $options);
}
+
if ($options['type'] === 'select' && array_key_exists('step', $options)) {
unset($options['step']);
}
- $options = $this->_maxLength($options);
+
+ $autoLength = !array_key_exists('maxlength', $options)
+ && !empty($fieldDef['length'])
+ && $options['type'] !== 'select';
+
+ $allowedTypes = ['text', 'email', 'tel', 'url', 'search'];
+ if ($autoLength && in_array($options['type'], $allowedTypes)) {
+ $options['maxlength'] = $fieldDef['length'];
+ }
+
return $options;
}
@@ -1065,28 +1070,6 @@ protected function _getLabel($fieldName, $options) {
}
/**
- * Calculates maxlength option
- *
- * @param array $options
- * @return array
- */
- protected function _maxLength($options) {
- $fieldDef = $this->_introspectModel($this->model(), 'fields', $this->field());
- $autoLength = (
- !array_key_exists('maxlength', $options) &&
- isset($fieldDef['length']) &&
- is_scalar($fieldDef['length']) &&
- $options['type'] !== 'select'
- );
- if ($autoLength &&
- in_array($options['type'], array('text', 'email', 'tel', 'url', 'search'))
- ) {
- $options['maxlength'] = $fieldDef['length'];
- }
- return $options;
- }
-
-/**
* Extracts a single option from an options array.
*
* @param string $name The name of the option to pull out.

0 comments on commit ecfd4cf

Please sign in to comment.