Skip to content

Commit

Permalink
[Form] Added capability to process "." rules in "error_mapping"
Browse files Browse the repository at this point in the history
  • Loading branch information
webmozart committed May 22, 2012
1 parent c9c4900 commit 215b687
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function isPrefix($propertyPath)
*
* @throws ErrorMappingException
*/
private function getTarget()
public function getTarget()
{
$childNames = explode('.', $this->targetPath);
$target = $this->origin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ public function mapViolation(ConstraintViolation $violation, FormInterface $form
}
}

// 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
Expand Down Expand Up @@ -260,7 +269,10 @@ private function setScope(FormInterface $form)
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);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1354,4 +1354,30 @@ public function testDontMapToUnsynchronizedForms()
$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');
}
}

0 comments on commit 215b687

Please sign in to comment.