Expanding Helper an View functionaility to accept deep nested entitities.

This allows the form helper to render inputs with arbitrary number of dot separated parts
This commit is contained in:
José Lorenzo Rodríguez 2009-10-21 16:39:16 -04:30 committed by mark_story
parent 50ec80ff50
commit ce743c00e8
4 changed files with 121 additions and 80 deletions

View file

@ -541,31 +541,10 @@ class Helper extends Overloadable {
*/ */
function tagIsInvalid($model = null, $field = null, $modelID = null) { function tagIsInvalid($model = null, $field = null, $modelID = null) {
$view =& ClassRegistry::getObject('view'); $view =& ClassRegistry::getObject('view');
foreach (array('model', 'field', 'modelID') as $key) {
if (empty(${$key})) {
${$key} = $this->{$key}();
}
}
$errors = $this->validationErrors; $errors = $this->validationErrors;
$entity = $view->entity();
if (!empty($view->entityPath)) { if (!empty($entity)) {
$check = $view->entityPath; return Set::extract($errors,join('.',$entity));
$path = explode('.',$check);
if (count($path) == 1 || is_numeric($path[0])) {
$check = $model . '.' . $check;
}
return Set::extract($errors,$check);
}
if ($view->model !== $model && isset($errors[$view->model][$model])) {
$errors = $errors[$view->model];
}
if (!isset($modelID)) {
return empty($errors[$model][$field]) ? 0 : $errors[$model][$field];
} else {
return empty($errors[$model][$modelID][$field]) ? 0 : $errors[$model][$modelID][$field];
} }
} }
@ -586,8 +565,10 @@ class Helper extends Overloadable {
$this->setEntity($options); $this->setEntity($options);
return $this->domId(); return $this->domId();
} }
$dom = $this->model() . $this->modelID() . Inflector::camelize($view->field) . Inflector::camelize($view->fieldSuffix); $entity = $view->entity();
$model = array_shift($entity);
$dom = $model . join('',array_map(array('Inflector','camelize'),$entity));
if (is_array($options) && !array_key_exists($id, $options)) { if (is_array($options) && !array_key_exists($id, $options)) {
$options[$id] = $dom; $options[$id] = $dom;
@ -626,18 +607,7 @@ class Helper extends Overloadable {
$name = $field; $name = $field;
break; break;
default: default:
$entity = $view->entity(); $name = 'data[' . join('][', $view->entity()) . ']';
if (!empty($view->entityPath)) {
$check = $view->entityPath;
$path = explode('.',$check);
$model = $this->model();
if ((count($path) == 1 && $model != $this->field()) || is_numeric($path[0])) {
debug($model); debug($this->field());
array_unshift($path,$model);
}
$entity = $path;
}
$name = 'data[' . join('][', $path) . ']';
break; break;
} }
@ -676,35 +646,9 @@ class Helper extends Overloadable {
$view =& ClassRegistry::getObject('view'); $view =& ClassRegistry::getObject('view');
$result = null; $result = null;
$modelName = $this->model(); $entity = $view->entity();
$fieldName = $this->field(); if (!empty($this->data) && !empty($entity)) {
$modelID = $this->modelID(); $result = Set::extract($this->data,join('.',$entity));
if (!empty($this->data) && !empty($view->entityPath)) {
$check = $view->entityPath;
$path = explode('.',$check);
if ((count($path) == 1 && $this->model() != $this->field()) || is_numeric($path[0])) {
$field = $this->model() . '.' . $check;
}
$result = Set::extract($this->data,$check);
}
if (is_null($fieldName)) {
$fieldName = $modelName;
$modelName = null;
}
if (isset($this->data[$fieldName]) && $modelName === null) {
$result = $this->data[$fieldName];
} elseif (isset($this->data[$modelName][$fieldName])) {
$result = $this->data[$modelName][$fieldName];
} elseif (isset($this->data[$fieldName]) && is_array($this->data[$fieldName])) {
if (ClassRegistry::isKeySet($fieldName)) {
$model =& ClassRegistry::getObject($fieldName);
$result = $this->__selectedArray($this->data[$fieldName], $model->primaryKey);
}
} elseif (isset($this->data[$modelName][$modelID][$fieldName])) {
$result = $this->data[$modelName][$modelID][$fieldName];
} }
if (is_array($result)) { if (is_array($result)) {

View file

@ -609,6 +609,19 @@ class View extends Object {
*/ */
function entity() { function entity() {
$assoc = ($this->association) ? $this->association : $this->model; $assoc = ($this->association) ? $this->association : $this->model;
if (!empty($this->entityPath)) {
$path = explode('.',$this->entityPath);
$count = count($path);
if (
($count == 1 && !empty($this->association)) ||
($count == 1 && $this->model != $this->entityPath) ||
($count == 2 && !empty($this->fieldSuffix)) ||
is_numeric($path[0])
) {
array_unshift($path,$assoc);
}
return Set::filter($path);
}
return array_values(Set::filter( return array_values(Set::filter(
array($assoc, $this->modelId, $this->field, $this->fieldSuffix) array($assoc, $this->modelId, $this->field, $this->fieldSuffix)
)); ));

View file

@ -645,6 +645,10 @@ class HelperTest extends CakeTestCase {
$this->Helper->data['HelperTestPost']['title'] = 'My Title'; $this->Helper->data['HelperTestPost']['title'] = 'My Title';
$result = $this->Helper->value('title'); $result = $this->Helper->value('title');
$this->assertEqual($result,'My Title'); $this->assertEqual($result,'My Title');
$this->Helper->data['My']['title'] = 'My Title';
$result = $this->Helper->value('My.title');
$this->assertEqual($result,'My Title');
} }

View file

@ -574,7 +574,7 @@ class ValidateItem extends CakeTestModel {
*/ */
var $_schema = array( var $_schema = array(
'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'), 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
'profile_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'), '' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
'name' => array('type' => 'text', 'null' => '', 'default' => '', 'length' => '255'), 'name' => array('type' => 'text', 'null' => '', 'default' => '', 'length' => '255'),
'description' => array( 'description' => array(
'type' => 'string', 'null' => '', 'default' => '', 'length' => '255' 'type' => 'string', 'null' => '', 'default' => '', 'length' => '255'
@ -709,6 +709,8 @@ class FormHelperTest extends CakeTestCase {
unset($this->Form->Html, $this->Form, $this->Controller, $this->View); unset($this->Form->Html, $this->Form, $this->Controller, $this->View);
Configure::write('Security.salt', $this->oldSalt); Configure::write('Security.salt', $this->oldSalt);
} }
/** /**
* testFormCreateWithSecurity method * testFormCreateWithSecurity method
@ -1602,7 +1604,7 @@ class FormHelperTest extends CakeTestCase {
'/option', '/option',
'/select', '/select',
'/div' '/div'
); debug($result,true); );
$this->assertTags($result, $expected); $this->assertTags($result, $expected);
$result = $this->Form->input('email', array( $result = $this->Form->input('email', array(
@ -5477,17 +5479,95 @@ class FormHelperTest extends CakeTestCase {
} }
function testMultiRecordForm() { function testMultiRecordForm() {
$this->Form->create('ValidateProfile'); $this->Form->create('ValidateProfile');
$this->Form->validationErrors['ValidateProfile'][2]['ValidateItem'][1]['name'] = 'Error in field name'; $this->Form->data['ValidateProfile'][1]['ValidateItem'][2]['name'] = 'Value';
$result = $this->Form->error('ValidateProfile.2.ValidateItem.1.name'); $result = $this->Form->input('ValidateProfile.1.ValidateItem.2.name');
$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field name', '/div')); $expected = array(
'div' => array('class' => 'input textarea'),
$this->Form->validationErrors['ValidateProfile'][2]['city'] = 'Error in field city'; 'label' => array('for' => 'ValidateProfile1ValidateItem2Name'),
$result = $this->Form->error('ValidateProfile.2.city'); 'Name',
$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div')); '/label',
'textarea' => array(
$result = $this->Form->error('2.city'); 'id' => 'ValidateProfile1ValidateItem2Name',
$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div')); 'name' => 'data[ValidateProfile][1][ValidateItem][2][name]',
'cols' => 30,
'rows' => 6
),
'Value',
'/textarea',
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('ValidateProfile.1.ValidateItem.2.created',array('empty' => true));
$expected = array(
'div' => array('class' => 'input date'),
'label' => array('for' => 'ValidateProfile1ValidateItem2CreatedMonth'),
'Created',
'/label',
array('select' => array(
'name' => 'data[ValidateProfile][1][ValidateItem][2][created][month]',
'id' => 'ValidateProfile1ValidateItem2CreatedMonth'
)
),
array('option' => array('value' => '')), '', '/option',
$this->dateRegex['monthsRegex'],
'/select', '-',
array('select' => array(
'name' => 'data[ValidateProfile][1][ValidateItem][2][created][day]',
'id' => 'ValidateProfile1ValidateItem2CreatedDay'
)
),
array('option' => array('value' => '')), '', '/option',
$this->dateRegex['daysRegex'],
'/select', '-',
array('select' => array(
'name' => 'data[ValidateProfile][1][ValidateItem][2][created][year]',
'id' => 'ValidateProfile1ValidateItem2CreatedYear'
)
),
array('option' => array('value' => '')), '', '/option',
$this->dateRegex['yearsRegex'],
'/select',
'/div'
);
$this->assertTags($result, $expected);
$this->Form->validationErrors['ValidateProfile'][1]['ValidateItem'][2]['profile_id'] = 'Error';
$this->Form->data['ValidateProfile'][1]['ValidateItem'][2]['profile_id'] = '1';
$result = $this->Form->input('ValidateProfile.1.ValidateItem.2.profile_id');
$expected = array(
'div' => array('class' => 'input text error'),
'label' => array('for' => 'ValidateProfile1ValidateItem2ProfileId'),
'Profile',
'/label',
'input' => array(
'name' => 'data[ValidateProfile][1][ValidateItem][2][profile_id]', 'type' => 'text',
'value' => '1',
'id' => 'ValidateProfile1ValidateItem2ProfileId',
'maxlength' => 8,
'class' => 'form-error'
),
array('div' => array('class' => 'error-message')),
'Error',
'/div',
'/div'
);
$this->assertTags($result, $expected,true);
}
function testMultiRecordFormValidationErrors() {
$this->Form->create('ValidateProfile');
$this->Form->validationErrors['ValidateProfile'][2]['ValidateItem'][1]['name'] = 'Error in field name';
$result = $this->Form->error('ValidateProfile.2.ValidateItem.1.name');
$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field name', '/div'));
$this->Form->validationErrors['ValidateProfile'][2]['city'] = 'Error in field city';
$result = $this->Form->error('ValidateProfile.2.city');
$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div'));
$result = $this->Form->error('2.city');
$this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div'));
} }
} }
?> ?>