Open sidebar
<?php namespace OpenObjects\Bundle\CoreBundle\Service; use OpenObjects\Bundle\StyleGuideBundle\Form\FieldType\FieldsetComponentType; use Symfony\Component\Form\Form; use Symfony\Component\Form\FormError; use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyPath; use Symfony\Component\Validator\ConstraintViolation; /** * Class FormErrorsSerializer * @package OpenObjects\Bundle\CoreBundle\Service */ class FormErrorsSerializer { /** * @var bool */ private $breakErrorLoop = false; /** * @var array */ private $originalFormErrors = []; /** * @param Form $form * @param bool $flatArray * @param bool $addFormName * @param string $glueKeys * * @return array */ public function serializeFormErrors(Form $form, $flatArray = false, $addFormName = false, $glueKeys = '_') { $errors = []; $errors['global'] = []; $errors['fields'] = []; foreach ($form->getErrors() as $error) { $errors['global'][] = $error->getMessage(); } $errors['fields'] = $this->serialize($form); if ($flatArray) { $errors['fields'] = $this->arrayFlatten( $errors['fields'], $glueKeys, (($addFormName) ? $form->getName() : '') ); } return $errors; } /** * @param Form $form * * @return array */ private function serialize(Form $form) : array { $localErrors = []; if ($form->getErrors()->count() > 0) { foreach ($form->getErrors() as $error) { $localErrors = $this->buildErrorArray($error); } } else { foreach ($form->getIterator() as $key => $child) { foreach ($child->getErrors() as $error) { if (!empty($this->serialize($child))) { $localErrors[$key] = $this->buildErrorArray($error); } } if (count($child->getIterator()) > 0 && ($child instanceof Form)) { if (!empty($this->serialize($child))) { $localErrors[$key] = $this->serialize($child); } } } } return $localErrors; } /** * @param Form $form * @param array $errors */ public function unserialize(Form &$form, array $errors) { foreach ($errors as $field => $error) { if ($this->breakErrorLoop) { break; } if (count($errors) > 0 && !isset($error['message'])) { if ($this->isFieldset($form, $field) && !empty($error)) { $form->get($field)->addError( new FormError( ucfirst(str_replace('_', ' ', $field)) . ' is invalid.' ) ); } $this->unserialize($form, $error); } else { $this->searchForm($form, $field, $error); } } } /** * @param Form $form * @param $field * * @return bool */ private function isFieldset(Form $form, $field) : bool { if ($form->has($field)) { return $form->get($field) ->getConfig() ->getType() ->getInnerType() instanceof FieldsetComponentType; } return false; } /** * @param Form $form * @param $needle * @param $error * * @return void */ private function searchForm(Form &$form, string $needle, array $error) { $searchKey = $form->getName(); // If this is the root form then set the search key as the needle. if (!$form->getParent()) { $searchKey = $needle; } if ($form->has($needle) && $this->keyExists($this->originalFormErrors['fields'], $searchKey)) { $addError = true; foreach ($form->get($needle)->getErrors() as $item) { if ($item->getMessage() == $error['message']) { $addError = false; } } if ($addError) { $formError = $this->createNewFormError($form, $error, $needle); $form->get($needle)->addError($formError); } } else { $originalFormErrors = $this->originalFormErrors; foreach ($form->getIterator() as $key => $child) { if (isset($this->originalFormErrors['fields'][$key])) { $originalFormErrors = $this->originalFormErrors['fields'][$key]; } if (!$child instanceof Form) { continue; } $childIterator = $child->getIterator(); $numItems = $childIterator->count(); $counter = 0; foreach ($childIterator as $name => $field) { if ($this->isTimestamp($name)) { foreach ($originalFormErrors as $fieldName => $fieldValue) { // PHP datetime needs to be divided by 1000 to match the unix time indexed field. $epochName = str_replace('.', '', ($fieldName/1000)); if ($name == $epochName) { if ($child->get($name)->getErrors()->count() === 0) { $formError = $this->createNewFormError($field, $error, $needle); if ($child->get($name)->has($needle)) { $child->get($name)->get($needle)->addError($formError); } } } } if (++$counter === $numItems) { $this->breakErrorLoop = true; break 2; } } } if ($form->get($key)->has($needle) && isset($originalFormErrors[$key])) { $formError = $this->createNewFormError($child, $error, $needle); $form->get($key)->get($needle)->addError($formError); // Remove from original errors array. unset($this->originalFormErrors['fields'][$key][$needle]); break; } if (count($child->getIterator()) > 0 && ($child instanceof Form)) { $this->searchForm($child, $needle, $error); } } } } /** * @param $timestamp * * @return bool */ private function isTimestamp($timestamp) : bool { $check = (is_int($timestamp) OR is_float($timestamp)) ? $timestamp : (string) (int) $timestamp; return ($check === $timestamp) && ( (int) $timestamp <= PHP_INT_MAX) && ( (int) $timestamp >= ~PHP_INT_MAX) && $check != 0; } /** * @param $errorIn * * @return array */ private function buildErrorArray(FormError $errorIn) : array { $errorOut = []; $errorOut['message'] = $errorIn->getMessage(); $errorOut['messageTemplate'] = $errorIn->getMessageTemplate(); $errorOut['messagePluralization'] = $errorIn->getMessagePluralization(); $errorOut['messageParameters'] = $errorIn->getMessageParameters(); if ($errorCause = $errorIn->getCause()) { $errorOut['cause']['message'] = $errorCause->getMessage(); $errorOut['cause']['messageTemplate'] = $errorCause->getMessageTemplate(); $errorOut['cause']['parameters'] = $errorCause->getParameters(); $errorOut['cause']['plural'] = $errorCause->getPlural(); $errorOut['cause']['propertyPath'] = $errorCause->getPropertyPath(); $errorOut['cause']['invalidValue'] = $errorCause->getInvalidValue(); $errorOut['cause']['constraint'] = serialize($errorCause->getConstraint()); $errorOut['cause']['code'] = $errorCause->getCode(); $errorOut['cause']['cause'] = $errorCause->getCause(); } return $errorOut; } /** * @param Form $form * @param $error * @param $field * * @return FormError */ private function createNewFormError(Form $form, $error, $field) : FormError { if (isset($error['cause']['cause'])) { $error['cause']['propertyPath'] = $error['cause']['cause']['propertyPath'] ?? 'children[' . $field . '].data'; $error['cause']['invalidValue'] = $error['cause']['cause']['invalidValue'] ?? null; $error['cause']['plural'] = $error['cause']['cause']['plural'] ?? null; $error['cause']['code'] = $error['cause']['cause']['code'] ?? null; $error['cause']['constraint'] = $error['cause']['cause']['constraint'] ?? null; } $constraint = null; if (isset($error['cause']['constraint'])) { $constraint = unserialize($error['cause']['constraint']); } return new FormError( $error['message'], $error['messageTemplate'] ?? null, $error['messageParameters'] ?? [], $error['messagePluralization'] ?? null, new ConstraintViolation( $error['cause']['message'], $error['cause']['messageTemplate'], $error['cause']['parameters'], $form, $error['cause']['propertyPath'] ?? $field . '.data', $error['cause']['invalidValue'] ?? '', $error['cause']['plural'] ?? null, $error['cause']['code'] ?? null, $constraint, $error['cause']['cause'] ?? null ) ); } /** * @param $array * @param string $separator * @param string $flattenedKey * * @return array */ private function arrayFlatten(array $array, string $separator = '_', string $flattenedKey = '') : array { $flattenedArray = []; foreach ($array as $key => $value) { if (is_array($value)) { $flattenedArray = array_merge( $flattenedArray, $this->arrayFlatten( $value, $separator, ( strlen($flattenedKey) > 0 ? $flattenedKey . $separator : "" ) . $key ) ); } else { $flattenedArray[(strlen($flattenedKey) > 0 ? $flattenedKey . $separator : "") . $key] = $value; } } return $flattenedArray; } /** * @param $array * @param $keySearch * * @return bool */ protected function keyExists($array, $keySearch) { foreach ($array as $key => $item) { if ( $key == $keySearch || (is_array($item) && $this->keyExists($item, $keySearch)) ) { return true; } } return false; } /** * @param array $errors * * @return FormErrorsSerializer */ public function setOriginalFormErrors(array $errors) : FormErrorsSerializer { $this->originalFormErrors = $errors; return $this; } /** * @return array */ public function getOriginalFormErrors() : array { return $this->originalFormErrors; } }
Close sidebar
Back
Please note that all pasted data is publicly available.
Twitter
GitHub
Use setting
Back
Please note that all pasted data is publicly available.
Twitter
GitHub
Use setting