craue / CraueFormFlowBundle

Multi-step forms for your Symfony project.
MIT License
736 stars 118 forks source link

List all flow instances from the current session #116

Open rvanlaak opened 10 years ago

rvanlaak commented 10 years ago

I've been busy with the session storage in order to store extra data aside of the $formData. How easy will it be to make a list of all started flows, in order to continue them? Can they be directly extracted from the storage handler?

New features could be

  1. list of active flows (could be template like buttons.html.twig)
  2. function to set a flow, based on earlier serialized session data
craue commented 10 years ago

Currently, having started and aborted two flows of the demo results in session data like this:

array(
    'flow_createLocation_data_26xz98wx38' => array(
        // step 1
        array(
            'country' => 'US',
            '_token' => '81jaZU6lQD_oCV-BmTZSxAN3rORRQgAVEu4iZbsACRE',
        ),
        // step 2
        array(
            'region' => 'US-TX',
            '_token' => 'ytCzDJAGrpo7ToVKqU89IOIQ0sDW2LDeve_5X0x6Sy0',
        ),
    ),
    'flow_createVehicle_data_3a03y1o9at' => array(
        // step 1
        array(
            'vehicle' => array(
                'numberOfWheels' => '2',
            ),
            '_token' => 'sGcKUDmMmeaLedFQhoDt2ULi_39hErh4ZqZN1qZDCjc',
        ),
    ),
    // and some unrelated stuff
)

Only the submitted form data is stored, so the only way to determine the flow it belongs to would be by extracting its name from the key. But in order to continue a flow, you'd have to know at which step.

There's no easy way to get a list of all flows. This would require restructuring the data, i.e. to have exactly one root element and maybe some metadata. At least I am not absolutely opposed to it. :smirk:

What do you mean by point 2?

rvanlaak commented 10 years ago

My usecase were the customers that had to be possible to continue their order. After every submit I serialize the data of the current flow into a json-file. That works fine now, but I had to make it possible to put the json-data back into the session. I've got this working with the following snippet in my own AbstractFlow.

class AbstractFlow extends FormFlow
{ 

function setData($file) 
{
        // 2nd parameter true to get formData as array instead of object
        $formData = json_decode(file_get_contents($file->getAbsolutePath()), true);

        // Manually set the data for the flow in order to continue
        $this->setInstanceId($this->determineInstanceId());
        $dataId = $this->getId() . '_data_' . $this->getInstanceId();
        $this->setStepDataKey($dataId);

        $this->storage->set($dataId, $formData);

        // Always continue at step 3 (after user page)
        $this->currentStepNumber = 3;

        // Return an array with parameters needed for the redirect
        return array(
            'instance' => $this->getInstanceId(),
            'step'     => $this->currentStepNumber,
        );
}

}

The return array is used in the congroller as parameter for $this->redirect($this->generateUrl('flow_index', $parameters))

Maybe the setter features for the flow could make it possible to set the data in the session, by generating a new instanceId. The setter then could return the array with parameters the controller has to redirect to.

craue commented 10 years ago

148 should serve as a first step to achieve this.