Skip to content

Instantly share code, notes, and snippets.

@linxlad
Last active February 23, 2016 14:23
Show Gist options
  • Save linxlad/e3c0121838e9f198f355 to your computer and use it in GitHub Desktop.
Save linxlad/e3c0121838e9f198f355 to your computer and use it in GitHub Desktop.
Symfony 3 PHP 7 Serialize all form errors before storing to cache and retrieve them again.
<?php
namespace OpenObjects\Bundle\CoreBundle\Util;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormError;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Validator\ConstraintViolation;
/**
* The FormUtil class is responsible for preparing form errors for caching.
*
* Class FormUtil
* @package OpenObjects\Bundle\CoreBundle\Util
*/
class FormUtil
{
/**
* List all errors of a given bound form.
*
* @param Form $form
*
* @return array
*/
public static function getFormErrorsToSerialized(Form $form)
{
$errors = array();
// Global
foreach ($form->getErrors() as $error) {
$errors['global'] = (string) $error->getMessage();
}
// Fields
foreach ($form as $child /** @var Form $child */) {
foreach ($child as $element) {
if (!$element->isValid()) {
foreach ($element->getErrors() as $error) {
$errors[$child->getName()]['message'] = $error->getMessage();
$errors[$child->getName()]['messageTemplate'] = $error->getMessageTemplate();
$errors[$child->getName()]['messagePluralization'] = $error->getMessagePluralization();
$errors[$child->getName()]['messageParameters'] = $error->getMessageParameters();
$errors[$child->getName()]['cause'] = $errors[$child->getName()];
$errorCause = $error->getCause();
$errors[$child->getName()]['cause']['plural'] = $errorCause->getPlural();
$errors[$child->getName()]['cause']['propertyPath'] = $errorCause->getPropertyPath();
$errors[$child->getName()]['cause']['invalidValue'] = $errorCause->getInvalidValue();
$errors[$child->getName()]['cause']['constraint'] = serialize($errorCause->getConstraint());
$errors[$child->getName()]['cause']['code'] = $errorCause->getCode();
$errors[$child->getName()]['cause']['cause'] = $errorCause->getCause();
}
}
}
if (!$child->isValid()) {
foreach ($child->getErrors() as $error) {
$errors[$child->getName()]['message'] = $error->getMessage();
$errors[$child->getName()]['messageTemplate'] = $error->getMessageTemplate();
$errors[$child->getName()]['messagePluralization'] = $error->getMessagePluralization();
$errors[$child->getName()]['messageParameters'] = $error->getMessageParameters();
$errors[$child->getName()]['cause'] = $errors[$child->getName()];
if ($errorCause = $error->getCause()) {
$errors[$child->getName()]['cause']['plural'] = $errorCause->getPlural();
$errors[$child->getName()]['cause']['propertyPath'] = $errorCause->getPropertyPath();
$errors[$child->getName()]['cause']['invalidValue'] = $errorCause->getInvalidValue();
$errors[$child->getName()]['cause']['constraint'] = serialize($errorCause->getConstraint());
$errors[$child->getName()]['cause']['code'] = $errorCause->getCode();
$errors[$child->getName()]['cause']['cause'] = $errorCause->getCause();
}
}
}
}
$serializer = new Serializer(
[new GetSetMethodNormalizer()],
['json' => new JsonEncoder()]
);
return $serializer->serialize($errors, 'json');
}
/**
* Apply an array of errors to form elements.
*
* @param Form $form
* @param array $formErrors
* @return Form
*/
public static function applyErrorsToForm(Form &$form, array $formErrors)
{
foreach ($formErrors as $field => $errors) {
if ($field == 'global') {
$errorObject = new FormError($errors);
$form->addError($errorObject);
} else {
if (isset($errors['cause']['cause'])) {
$errors['cause']['propertyPath'] = $errors['cause']['cause']['propertyPath'] ?? 'children[' . $field . '].data';
$errors['cause']['invalidValue'] = $errors['cause']['cause']['invalidValue'] ?? null;
$errors['cause']['plural'] = $errors['cause']['cause']['plural'] ?? null;
$errors['cause']['code'] = $errors['cause']['cause']['code'] ?? null;
$errors['cause']['constraint'] = $errors['cause']['cause']['constraint'];
}
$constraint = null;
if (isset($errors['cause']['constraint'])) {
$constraint = unserialize($errors['cause']['constraint']);
}
// Unravel cause
$constraintViolation = new ConstraintViolation(
$errors['cause']['message'],
$errors['cause']['messageTemplate'],
$errors['cause']['messageParameters'],
$form,
$errors['cause']['propertyPath'] ?? $field . '.data',
$errors['cause']['invalidValue'] ?? '',
$errors['cause']['plural'] ?? null,
$errors['cause']['code'] ?? null,
$constraint,
$errors['cause']['cause'] ?? null
);
$errorObject = new FormError(
$errors['message'],
$errors['messageTemplate'] ?? null,
$errors['messageParameters'] ?? [],
$errors['messagePluralization'] ?? null,
$constraintViolation
);
$form->get($field)->addError($errorObject);
}
}
return $form;
}
/**
* Apply an array of values to a form.
*
* @param Form $form
* @param array $formValues
* @return Form
*/
public static function applyValuesToForm(Form &$form, array $formValues)
{
foreach ($formValues as $field => $value) {
if ($form->has($field)) {
$form->get($field)->setData($value);
}
}
return $form;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment