[Form] Added capability to process "." rules in "error_mapping"

This commit is contained in:
Bernhard Schussek 2012-05-21 11:35:42 +02:00
parent c9c4900663
commit 215b687b7b
4 changed files with 42 additions and 2 deletions

View File

@ -73,6 +73,8 @@ CHANGELOG
* added option "mapped" which should be used instead of setting "property_path" to false
* "data_class" now *must* be set if a form maps to an object and should be left empty otherwise
* improved error mapping on forms
* dot (".") rules are now allowed to map errors assigned to a form to
one of its children
* errors are not mapped to unsynchronized forms anymore
* changed Form constructor to accept a single `FormConfigInterface` object
* changed argument order in the FormBuilder constructor

View File

@ -90,7 +90,7 @@ class MappingRule
*
* @throws ErrorMappingException
*/
private function getTarget()
public function getTarget()
{
$childNames = explode('.', $this->targetPath);
$target = $this->origin;

View File

@ -91,6 +91,15 @@ class ViolationMapper
}
}
// Follow dot rules until we have the final target
$mapping = $this->scope->getAttribute('error_mapping');
while (isset($mapping['.'])) {
$dotRule = new MappingRule($this->scope, '.', $mapping['.']);
$this->scope = $dotRule->getTarget();
$mapping = $this->scope->getAttribute('error_mapping');
}
// Only add the error if the form is synchronized
// If the form is not synchronized, it already contains an
// error about being invalid. Further errors could be a result
@ -260,7 +269,10 @@ class ViolationMapper
new VirtualFormAwareIterator($form->getChildren())
);
foreach ($form->getAttribute('error_mapping') as $propertyPath => $targetPath) {
$this->rules[] = new MappingRule($form, $propertyPath, $targetPath);
// Dot rules are considered at the very end
if ('.' !== $propertyPath) {
$this->rules[] = new MappingRule($form, $propertyPath, $targetPath);
}
}
}
}

View File

@ -1354,4 +1354,30 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($parent->hasErrors(), $parent->getName() . ' should not have an error, but has one');
$this->assertFalse($child->hasErrors(), $child->getName() . ' should not have an error, but has one');
}
public function testFollowDotRules()
{
$violation = $this->getConstraintViolation('data.foo');
$parent = $this->getForm('parent', null, null, array(
'foo' => 'address',
));
$child = $this->getForm('address', null, null, array(
'.' => 'street',
));
$grandChild = $this->getForm('street', null, null, array(
'.' => 'name',
));
$grandGrandChild = $this->getForm('name');
$parent->add($child);
$child->add($grandChild);
$grandChild->add($grandGrandChild);
$this->mapper->mapViolation($violation, $parent);
$this->assertFalse($parent->hasErrors(), $parent->getName() . ' should not have an error, but has one');
$this->assertFalse($child->hasErrors(), $child->getName() . ' should not have an error, but has one');
$this->assertFalse($grandChild->hasErrors(), $grandChild->getName() . ' should not have an error, but has one');
$this->assertEquals(array($this->getFormError()), $grandGrandChild->getErrors(), $grandGrandChild->getName() . ' should have an error, but has none');
}
}