3

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:

  1. $form->submit([], false); as in here. Not good - if required field is empty error will not be displayed.
  2. 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);
    }
}
Community
  • 1
  • 1
Aurelijus Rozenas
  • 2,176
  • 2
  • 28
  • 40
  • I had to do the same - I ended up using your implemented solution. Although I checked this with a form factory and put the error there: ($form->get('field')->addError(new FormError('error message'));) The other way would be to just parse the form and validate the given data on the front-end with Javascript. – yogee Feb 05 '16 at 13:31
  • you could also put that stuff in a session object (or a request Response) and check in the twig template for any of these errors. – yogee Feb 05 '16 at 13:39
  • 1
    Yes, yours are valid suggestions but for me the goal is to have universal solution so I don't have change code in multiple places if I changes constraints, entity fields or template. – Aurelijus Rozenas Feb 07 '16 at 16:35

0 Answers0