I need to validate user profile form when loading page (without post) and display errors.
It turned out to be quite a challenge.
Requirements
- errors must be displayed in same manner as after post would be.
- required fields must have
field is empty
error message.
Universal and almost working solution: error messages are displayed, that's fine. However they are not highlighted because form element does not receive has-error
style class because form field is marked as valid because valid
is checking for submitted
and submitted is false because is was not submitted.
$errors = $this->get('validator')->validate($form);
if (count($errors)) {
/** @var ConstraintViolation $error */
foreach ($errors as $error) {
// data.firstname
if (preg_match('/^data\.(.*)/', $error->getPropertyPath(), $matches)) {
$path = $matches[1];
} // children[schoolGrades].data
elseif (preg_match('/^children\[(.*?)\]\.data/', $error->getPropertyPath(), $matches)) {
$path = $matches[1];
} else {
throw new \Exception(sprintf('Cannot parse field path from "%s"', $error->getPropertyPath()));
}
$formElement = $form->get($path);
$formElement->addError(new FormError($error->getMessage()));
}
}
$form->handleRequest($request);
Question
Is there a way set valid
to false or submitted
to true? Maybe there is entirely different solution? I find it hard to believe that I am the first to implement this as I found it hard to believe that I cannot retrieve data as array from form I built and set data with $form->setData($user);
.
Other information
Found solutions that does not work for me:
$form->submit([], false);
as in here. Not good - if required field is empty error will not be displayed.- Using
ViolationMapper();
as in here. Simply does not work for me... :/
Implemented working solution with drawbacks: create user data as array with data set from user entity. Problem: have to maintain function when changing form and/or User entity.
public static function handleRequest(User $user, FormInterface $form, Request $request)
{
if ($request->get(UserWizardModel::URL_GET_PARAM_LAST_STEP) && !$request->get($form->getName())) {
$schoolGradeIdArray = [];
foreach ($user->getSchoolGrades() as $schoolGrade) {
$schoolGradeIdArray[] = $schoolGrade->getId();
}
$userAsArray = [
'firstname' => $user->getFirstname(),
'lastname' => $user->getLastname(),
'profileType' => '',
'phone' => $user->getPhone(),
'schoolGrades' => $schoolGradeIdArray,
'profileSchool' => $user->getProfileSchool()->getId(),
];
$form->submit($userAsArray);
} else {
$form->handleRequest($request);
}
}