Skip to content

Instantly share code, notes, and snippets.

@assada
Last active May 22, 2019 08:42
Show Gist options
  • Save assada/83d350fe4b3ce9154e00232265964bb6 to your computer and use it in GitHub Desktop.
Save assada/83d350fe4b3ce9154e00232265964bb6 to your computer and use it in GitHub Desktop.
Symfony 3 Form errors Normalizer
<?php
namespace Tire\DealerApiBundle\Serialize;
use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationPath;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
/**
* Class FormErrorsSerializer
*
* @package Tire\DealerApiBundle\Serialize
*
* @author Aleksey Ilyenko <oleksii@tireconnect.ca>
* Tireconnect LLC
*/
class FormErrorsSerializer
{
/**
* @param \Symfony\Component\Form\FormInterface $data
*
* @return \ArrayObject
*/
public function serializeFormErrors(FormInterface $data)
{
$form = new \ArrayObject();
$errors = [];
foreach ($data->getErrors() as $error) {
$cause = $error->getCause();
$field = null;
$code = null;
if ($cause instanceof ConstraintViolationInterface) {
$path = new ViolationPath($cause->getPropertyPath());
$field = $path->getElements();
}
$tempArray = [];
$temp = &$tempArray;
foreach ((array)$field as $key) {
$temp = &$temp[$key];
}
$temp[] = $error->getMessage();
$errors[implode('.', $field)][] = $error->getMessage();
unset($temp, $tempArray);
}
foreach ($data->all() as $child) {
if ($child instanceof FormInterface) {
$formattedChild = $this->serializeFormErrors($child);
if (null !== $formattedChild) {
foreach ($formattedChild as $key => $value) {
$errors[$key] = $value;
}
}
}
}
if ($errors) {
$form = $errors;
}
return $form;
}
/**
* @param array|\ArrayObject $collection
*
* @return array
*/
public function arrayUnflatten($collection)
{
$collection = (array)$collection;
$output = [];
foreach ($collection as $key => $value) {
$this->arraySet($output, $key, $value);
if (is_array($value) && !strpos($key, '.')) {
$nested = $this->arrayUnflatten($value);
$output[$key] = $nested;
}
}
return $output;
}
/**
* Set an array item to a given value using "dot" notation.
*
* @param array|\ArrayObject $array
* @param string $key
* @param mixed $value
*
* @return array|mixed
*/
public function arraySet(&$array, $key, $value)
{
if (null === $key) {
return $array = $value;
}
$keys = explode('.', $key);
while (count($keys) > 1) {
$key = array_shift($keys);
if (!isset($array[$key]) || !is_array($array[$key])) {
$array[$key] = [];
}
$array =& $array[$key];
}
$array[array_shift($keys)] = $value;
return $array;
}
}
@assada
Copy link
Author

assada commented Nov 3, 2017

Usage:

Flatt:

$serializer = $this->get('serializer.form_errors');
$flatt = $serializer->serializeFormErrors($data); //$data<FormInterface> Your form

var_dump($flatt);

Result:

array (size=4)
  'price.range.0.value' => 
    array (size=2)
      0 => string 'This value should not be null.' (length=30)
      1 => string 'This value should not be blank.' (length=31)
  'price.range.0.from' => 
    array (size=2)
      0 => string 'This value should not be null.' (length=30)
      1 => string 'This value should not be blank.' (length=31)
  'price.range.1.value' => 
    array (size=2)
      0 => string 'This value should not be null.' (length=30)
      1 => string 'This value should not be blank.' (length=31)
  'price.range.1.from' => 
    array (size=2)
      0 => string 'This value should not be null.' (length=30)
      1 => string 'This value should not be blank.' (length=31)

Unflatt:

$unflatten = $serializer->arrayUnflatten($flatt);

var_dump($unflatten);

Result:

array (size=1)
  'price' => 
    array (size=1)
      'range' => 
        array (size=2)
          0 => 
            array (size=2)
              'value' => 
                array (size=2)
                  0 => string 'This value should not be null.' (length=30)
                  1 => string 'This value should not be blank.' (length=31)
              'from' => 
                array (size=2)
                  0 => string 'This value should not be null.' (length=30)
                  1 => string 'This value should not be blank.' (length=31)
          1 => 
            array (size=2)
              'value' => 
                array (size=2)
                  0 => string 'This value should not be null.' (length=30)
                  1 => string 'This value should not be blank.' (length=31)
              'from' => 
                array (size=2)
                  0 => string 'This value should not be null.' (length=30)
                  1 => string 'This value should not be blank.' (length=31)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment