[Form] Made data mappers completely responsible for dealing with empty values. Removed duplication of code.
This commit is contained in:
parent
9bf6e8ba59
commit
5fe3f39ebc
@ -23,22 +23,24 @@ class PropertyPathMapper implements DataMapperInterface
|
|||||||
*/
|
*/
|
||||||
public function mapDataToForms($data, array $forms)
|
public function mapDataToForms($data, array $forms)
|
||||||
{
|
{
|
||||||
if (!empty($data) && !is_array($data) && !is_object($data)) {
|
if (null === $data || array() === $data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($data) && !is_object($data)) {
|
||||||
throw new UnexpectedTypeException($data, 'object, array or empty');
|
throw new UnexpectedTypeException($data, 'object, array or empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($data)) {
|
$iterator = new VirtualFormAwareIterator($forms);
|
||||||
$iterator = new VirtualFormAwareIterator($forms);
|
$iterator = new \RecursiveIteratorIterator($iterator);
|
||||||
$iterator = new \RecursiveIteratorIterator($iterator);
|
|
||||||
|
|
||||||
foreach ($iterator as $form) {
|
foreach ($iterator as $form) {
|
||||||
/* @var FormInterface $form */
|
/* @var FormInterface $form */
|
||||||
$propertyPath = $form->getPropertyPath();
|
$propertyPath = $form->getPropertyPath();
|
||||||
$config = $form->getConfig();
|
$config = $form->getConfig();
|
||||||
|
|
||||||
if (null !== $propertyPath && $config->getMapped()) {
|
if (null !== $propertyPath && $config->getMapped()) {
|
||||||
$form->setData($propertyPath->getValue($data));
|
$form->setData($propertyPath->getValue($data));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,6 +50,14 @@ class PropertyPathMapper implements DataMapperInterface
|
|||||||
*/
|
*/
|
||||||
public function mapFormsToData(array $forms, &$data)
|
public function mapFormsToData(array $forms, &$data)
|
||||||
{
|
{
|
||||||
|
if (null === $data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($data) && !is_object($data)) {
|
||||||
|
throw new UnexpectedTypeException($data, 'object, array or empty');
|
||||||
|
}
|
||||||
|
|
||||||
$iterator = new VirtualFormAwareIterator($forms);
|
$iterator = new VirtualFormAwareIterator($forms);
|
||||||
$iterator = new \RecursiveIteratorIterator($iterator);
|
$iterator = new \RecursiveIteratorIterator($iterator);
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ use Symfony\Component\Form\Exception\FormException;
|
|||||||
use Symfony\Component\Form\Exception\AlreadyBoundException;
|
use Symfony\Component\Form\Exception\AlreadyBoundException;
|
||||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
|
use Symfony\Component\Form\Util\FormUtil;
|
||||||
use Symfony\Component\Form\Util\PropertyPath;
|
use Symfony\Component\Form\Util\PropertyPath;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
@ -352,7 +353,7 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
$viewData = $this->normToView($normData);
|
$viewData = $this->normToView($normData);
|
||||||
|
|
||||||
// Validate if view data matches data class (unless empty)
|
// Validate if view data matches data class (unless empty)
|
||||||
if ('' !== $viewData && null !== $viewData) {
|
if (!FormUtil::isEmpty($viewData)) {
|
||||||
$dataClass = $this->config->getDataClass();
|
$dataClass = $this->config->getDataClass();
|
||||||
|
|
||||||
$actualType = is_object($viewData) ? 'an instance of class ' . get_class($viewData) : ' a(n) ' . gettype($viewData);
|
$actualType = is_object($viewData) ? 'an instance of class ' . get_class($viewData) : ' a(n) ' . gettype($viewData);
|
||||||
@ -492,12 +493,12 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
// since forms without children may also be compound.
|
// since forms without children may also be compound.
|
||||||
// (think of empty collection forms)
|
// (think of empty collection forms)
|
||||||
if ($this->config->getCompound()) {
|
if ($this->config->getCompound()) {
|
||||||
if (null === $submittedData || '' === $submittedData) {
|
|
||||||
$submittedData = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_array($submittedData)) {
|
if (!is_array($submittedData)) {
|
||||||
throw new UnexpectedTypeException($submittedData, 'array');
|
if (!FormUtil::isEmpty($submittedData)) {
|
||||||
|
throw new UnexpectedTypeException($submittedData, 'array');
|
||||||
|
}
|
||||||
|
|
||||||
|
$submittedData = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->children as $name => $child) {
|
foreach ($this->children as $name => $child) {
|
||||||
@ -520,7 +521,7 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
$viewData = $this->getViewData();
|
$viewData = $this->getViewData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $viewData || '' === $viewData) {
|
if (FormUtil::isEmpty($viewData)) {
|
||||||
$emptyData = $this->config->getEmptyData();
|
$emptyData = $this->config->getEmptyData();
|
||||||
|
|
||||||
if ($emptyData instanceof \Closure) {
|
if ($emptyData instanceof \Closure) {
|
||||||
@ -532,7 +533,7 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Merge form data from children into existing view data
|
// Merge form data from children into existing view data
|
||||||
if ($this->config->getCompound() && null !== $viewData) {
|
if ($this->config->getCompound()) {
|
||||||
$this->config->getDataMapper()->mapFormsToData($this->children, $viewData);
|
$this->config->getDataMapper()->mapFormsToData($this->children, $viewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,7 +702,7 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array() === $this->modelData || null === $this->modelData || '' === $this->modelData;
|
return FormUtil::isEmpty($this->modelData) || array() === $this->modelData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1048,9 +1049,12 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
*/
|
*/
|
||||||
private function normToView($value)
|
private function normToView($value)
|
||||||
{
|
{
|
||||||
if (!$this->config->getViewTransformers()) {
|
// Scalar values should be converted to strings to
|
||||||
// Scalar values should always be converted to strings to
|
// facilitate differentiation between empty ("") and zero (0).
|
||||||
// facilitate differentiation between empty ("") and zero (0).
|
// Only do this for simple forms, as the resulting value in
|
||||||
|
// compound forms is passed to the data mapper and thus should
|
||||||
|
// not be converted to a string before.
|
||||||
|
if (!$this->config->getViewTransformers() && !$this->config->getCompound()) {
|
||||||
return null === $value || is_scalar($value) ? (string) $value : $value;
|
return null === $value || is_scalar($value) ? (string) $value : $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,4 +219,23 @@ abstract class FormUtil
|
|||||||
|
|
||||||
return $choice === $value;
|
return $choice === $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given data is empty.
|
||||||
|
*
|
||||||
|
* This logic is reused multiple times throughout the processing of
|
||||||
|
* a form and needs to be consistent. PHP's keyword `empty` cannot
|
||||||
|
* be used as it also considers 0 and "0" to be empty.
|
||||||
|
*
|
||||||
|
* @param mixed $data
|
||||||
|
*
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
static public function isEmpty($data)
|
||||||
|
{
|
||||||
|
// Should not do a check for array() === $data!!!
|
||||||
|
// This method is used in occurrences where arrays are
|
||||||
|
// not considered to be empty, ever.
|
||||||
|
return null === $data || '' === $data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user