Open rvanlaak opened 10 years ago
File uploads are a tough topic. What exactly do you mean by
store the id of that new Entity into the
FormFlow
by usingsaveStepData()
? If you add the id (as an attribute) to the data object used for the flow, saving the data should work properly. #49 could also be interesting in this context.
I did saw #49 indeed, and already tried to set the formData before and after validation. When I alter the value, the form isn't valid anymore with as a result an Exception. This makes it impossible to modify the data type.
Any reasons why it should not be favorable to add two extra events? I can't imagine some...
I'm not sure if the way you're trying to deal with the data is the right one, or if adding more events would serve as some kind of workaround only.
Taking a look at code I'm using in an app to handle uploads is essentially what's done by https://github.com/craue/CraueFormFlowBundle/issues/29#issue-5089782 – saving additional data (separated from the data the flow stores itself) in onPostValidate
, reading it in onPreBind
, and cleaning up by overriding reset
. It's quite old, though, and I'd rather use onPostBindSavedData
instead of onPreBind
. Would that work in your case?
Thanks for mentioning that issue, but that one is about skipping steps and resetting the form right? The thing I try to archieve is saving extra data to the session, but the problem still stays the same.
I use the following snippet in the last possible event to add extra data to the session:
/**
* Store UploadedFile to disk and persist to database
*/
public function saveFiles(PostValidateEvent $event)
{
$formData = $event->getFormData();
$dataId = $this->getId() . '_data_' . $this->getInstanceId();
$data = $this->storage->get($dataId);
// Handle all files from the flow
foreach ($formData as $fieldKey => $fieldFile) {
if ($fieldFile instanceof UploadedFile) {
$diskFile = new Document();
$diskFile->setFile($fieldFile);
$this->em->persist($diskFile);
$this->em->flush();
$data[$this->getCurrentStep()][$fieldKey] = $diskFile->getId();
}
}
$this->storage->set($dataId, $data);
}
This works great, the data of the form is overwritten by the id of the file I saved to disk. The $entityManager
is injected in the Flow by DI. But now the problem occurs; the Controller class still has to call
$flow->saveCurrentStepData($form);
In other words, saving extra data to the session works great but thereafter it gets overwritten by the regular save process of the flow. In other words; I could call the first snippet above in the controller after the saveCurrentStepData()
is called.
The Flow has no other events after that call, so if I'm right this makes it impossible to add data to the session in the Flow itself since it always will get overwritten. So, this has to be handled in the Controller.
I did get it functioning correctly now by extending saveCurrentStepData()
. The following snippet made it possible for me to save the files, and registering to the events is not needed anymore:
/**
* Override saving of data, and save files to disk
* {@inheritDoc}
*/
public function saveCurrentStepData(FormInterface $form)
{
parent::saveCurrentStepData($form);
$this->saveFiles();
}
I've used all different types of events, but with none of them it is possible to use the
FormData
from the current request, do something with that data, and save the new data to the storage.My use case is that I want to save a
UploadedFile
to the database, and store the id of that new Entity into theFormFlow
by usingsaveStepData()
.The problem is, that this data gets overwritten if the controller calls $flow->saveCurrentStepData($form);
Since no event are triggered after the above call, the data from the storage always will get overwritten by the
formData
.In other words: in what way is it possible to add extra info to the storage, after the form has been submitted and validated? Idea to dispatch two new events, called
PRE_STORAGE_DATA
andPOST_STORAGE_DATA
?