2

I have the current situation in a Symfony2 website:

  • login functionality performed by loginAction in SecurityController. When visiting its route, the action uses parameters ( p1, p2, p3) while rendering the view. (same as FOSUserBundle)

  • register functionnality registerAction in RegistrationController is returning a view using other parameters p3,p4,p5. (same as FOSUserBundle)

Parameters are used to hold error messages when form is invalid.

I need to display a homepage that show both functionalities(a form for login and a form for registration), but that can also handle errors due to invalid data.

I can successfuly display the home page(MembersManagementBundle::index.html.twig):

{{ render(controller('MembersManagementBundle:Security:login')) }}

{{ render(controller('MembersManagementBundle:Registration:register')) }}

Controller:

class IndexController extends Controller
{

     public function indexAction()
    {
        return $this->render('MembersManagementBundle::index.html.twig');
    }
}

If good values are entered (whether in login or register form), redirection is performed to the correct target page after form submit.

But,

If bad data is entered to one of the forms, there is a redirection to its specific view with the specific errors( It is normal since submitting form calls the url specified in action attribute which call the corresponding action in corresponding controller).

Questions:

Is is possible to have the two actions in one template with the sum of all parameters? Should I develop indexAction so that it contains the logic of both actions? Or there is another way that can keep the two actions separate but merge the result into indexAction? My goal at the end is to be able to generate index page with the needed errors(p1,p2,p3 or p4,p5,p6).

Thank you. Your help is much appreciated.

Adib Aroui
  • 4,981
  • 5
  • 42
  • 94
  • Could you please provide the logic of the login and registration action? – KhorneHoly Feb 16 '15 at 12:40
  • @KhorneHoly. Thank you for your feedback, please to look at the links I provided in edit (From FOSUserBundle github) – Adib Aroui Feb 16 '15 at 12:44
  • do your actions contain also this render at the end? `return $this->render('FOSUserBundle:Registration:register.html.twig', array( 'form' => $form->createView(), ));` If yes, you need to edit your render actions to the index! – KhorneHoly Feb 16 '15 at 12:46
  • @KhorneHoly, am I not going to fall in an infinite loop doing so (rendering nested index pages)? – Adib Aroui Feb 16 '15 at 12:49
  • No, since your action only will be called when the form will be submitted. So it would be like this -> User goes to the index -> index renders the 2 forms -> 1 of the 2 forms will be submitted -> action will be fired -> action renders the index -> index will render the two controllers which gives out the forms, but since the forms won't be submitted automatically there can't be a infinity loop. The only think you must think of is a way that the the form action remembers the errors from the first call in the second call. Hope this is somewhat understandable. – KhorneHoly Feb 16 '15 at 12:53
  • Well, I tested rendering the index page in the two actions but as I told you, it created a loop. I kinda understand your approach but what creates the problem is `{{ render(controller('MembersManagementBundle:Security:login')) }}`, this line calls the `loginAction` which renders index inside of index for tens of times. – Adib Aroui Feb 16 '15 at 13:03

1 Answers1

0

This is what your process looks like right now:

  1. The User goes to the index page.
  2. The Index Page includes 2 forms due calling the render function in twig.
  3. The User submits one of the 2 forms.
  4. The forms submits and runs through the action that lies behind the form.
  5. The form renders only the twig template since that's what the action does in the end.

Now you need to edit it to the following:

  1. 1-4 are the same.
  2. The form renders the index controller again which will render the 2 forms again. There cannot be a infinity loop since the forms won't be submitted again from the program logic.
  3. Now is one point left over: Since the form will action will be run through 2 times, how will the errors be shown? Because they will be set in the first run, but not in the second.

That how you do it:

You add a variable in the loginAction:

$loginErrorsArray = array();

Wherever you'd add a error to the form you add it to the array instead.

//instead of $form->addError(...);
$loginErrorsArray['formField'] = $errorMessage;

Before you're rendering out the form you're saving it into the session.

$this->get('session')->set('loginErrors', $loginErrorsArray);

Now in the same action at the beginning of the code you're getting the session variable and run through it, creating formErrors foreach entry. After that you save a empty array in the session.

$loginErrorsArray = $this->get('session')->get('loginErrors');
foreach($loginErrorsArray as $error){
    $form->addError(...);
}
$this->get('session')->set('loginErrors', array());

Now this will do the following in the action:

  1. It gets the array with the errors.
  2. Creates errors foreach error found. (since in the first run through there are no errors set there will no be created).
  3. Then it will add all errors found to the array.
  4. In the second run it will add all errors in the array to the form, but will not create any new to the array.

Hope this is helpfull.

KhorneHoly
  • 4,666
  • 6
  • 43
  • 75
  • Thank you for this help, I really appreciate the time you gave to this question. I am reading it and after full understanding it I will come to give a feedback. thanks again – Adib Aroui Feb 16 '15 at 13:15
  • No sir. When I change `loginAction` and `registerAction` so that they render `index.html.twig`, there is infinite loop (at the first run before submitting any form). I hope you correct me if I am wrong. For the second part about errors handling, I see what you mean and I will be using the approach, but after resolving the main issue. thanks again – Adib Aroui Feb 16 '15 at 13:23
  • Are you convinced? anyways, for sharing purposes, try to read this it allowed me have more insights about the issues: http://stackoverflow.com/questions/26959973/symfony2-fos-login-register-and-forgot-password-in-one-view?rq=1 . Wish happpy day and thanks – Adib Aroui Feb 17 '15 at 10:32