1

stack: symfony2/doctrine2/php/mysql

a multipage form constist of two steps. each step is realized in a controller action.

in step1, the form is displayed. form-input is validated in the same action. if the form is valid the user should be redirected to the second step/action. in the second step the user has to confirm his input. after confirmation the data should be stored in the db.

thus form-entities/form-data are/is needed in the second step/action. however i do not want to store it in the db before confirmation.

do i really need to serialize all objects? to the session? is there a better approach?

any suggestions?

Martin Abraham
  • 752
  • 7
  • 24
  • i think you should create hidden field and in submit Action file validate the hidden object – Ammar Hayder Khan Jun 26 '13 at 12:00
  • 2
    Serializing your entity objects to the session would be the way that I would do it. If you're not sure how to do that, it's answered pretty well on http://stackoverflow.com/questions/9384836/symfony2-serialize-entity-object-to-session. – james_tookey Jun 26 '13 at 12:01
  • well tried to use serialization, but entities are quite complexe with "many" association. thus serialization is too slow. even after detaching. – Martin Abraham Jun 26 '13 at 19:15

2 Answers2

1

First of all, I would recommend validating the input via JavaScript before posting and not in the controller action on the server.

If you don't want to serialize the data to the session you can simply pass it on to the next page when you receive it in the first action and then post it to the second action, I'm imagining something like this:

firstAction() {
  $exampleData = $_POST['exampleData'];
  // Do whatever you need, then pass the data on to the next page
  return $this->render('SomeBundle:Views:secondPage.html.php',
                       array('exampleData' => $exampleData));

On the second page you then just have to access $exampleData with JavaScript and best put it in some hidden input field inside the form.

<!-- secondPage.html.php -->
<script type="text/javascript">
    var exampleData = <?php echo $exampleData ?>;
    $('#hiddenInput').val(exampleData);
</script>

The second controller action will then receive $exampleData as well without having it serialized in the session.

Sorry if there are any syntax errors, haven't used symfony2 in a while :)

enp4yne
  • 638
  • 5
  • 21
  • this is probably what @aligarian meant, I just went in to a little more detail – enp4yne Jun 26 '13 at 12:48
  • steps are realized in separate controller actions, which correspond to different url. also js is not an option. just serializing post-data (`$postParams = $this->getRequest()->request;`) and repopulate the form (`$form->bind($postParams);`) seems to be an idea. – Martin Abraham Jun 26 '13 at 19:07
  • You should never rely on JavaScript for validation. – Adam Feb 09 '15 at 08:49
1

tried to use serialization, but entities are quite complex with "many" associations. thus serialization is too slow. even after detaching.

first solution (simplified):

store the POST variables to the session inside the first step/action.

    $postParams = $this->getRequest()->request;

    $session = $this->getRequest()->getSession();
    if (!$session) {
        $session = new Session();
    }
    $session->set($sessionKey, $postParams);

in the second step/action i used the form to repopulate my entity.

    $cancellation = $manager->initCancellationSomehow();

    $session = $this->getRequest()->getSession();
    if (!$session) {
        $session = new Session();
    }

    $parameterBag = $session->get($sessionKey);

    $cancellation = $this->getCancellation($customerId);

    $form = $this->createForm(
        new CancellationType(),
        $cancellation,
        array(
            'em' => $this->getDoctrine()->getManager())
    );

    $form->bind($parameterBag->get('form'));

    [..]

second solution:

well my first thought was to store cancellation in the db. therefore i added a state attribute (active/temp/..). unconfirmed cancellations get marked as temp. if the user confirms the state gets changed form temp to active. temp collections get deleted after on hour by a garbarge collector which runs at a low priority.

i like the second solution because the user has to confirm the final cancellation, which is already stored in the db. if the frontend does not work as expected the user will likely notice corrupted cancellations (e.g. wrong entries selected). if he confirms, only the state is changed. feels safe. in the first solution the user confirms what should be stored in the db, but isn't till now. feels unsecure.

Thomas Landauer
  • 7,857
  • 10
  • 47
  • 99
Martin Abraham
  • 752
  • 7
  • 24