Reputation: 1388
In a Symfony project I need to store some table data on an entity, data which is supposed to be uploaded as a CSV document in Sonata admin. My first thought was to use the Doctrine2 json_array
data type to store the data, but I was surprised to find out that it's not such a easy task.
After some research I found the Symfony\Component\Form\DataTransformerInterface which seemed to be the right choice to transform the CSV file into an array. The problem is that the transform($value)
method is not receiving the uploaded file in $value
parameter, so I'm stuck with this.
In the entity admin class I have:
$formMapper
[...]
->add($formMapper->create('discounts', 'file', array(
'required' => false,
'data_class' => null
))
->addViewTransformer(new CSVToArrayTransformer()))
where CSVToArrayTransformer
looks like this:
class CSVToArrayTransformer implements DataTransformerInterface
{
public function transform($csvFile){
// here should take place the csv to array transformation, but $csvFile is null
}
}
Is there a better method to obtain this?
Upvotes: 2
Views: 2196
Reputation: 13167
As stated by Sonata documentation (Uploading and serving documents), you should use the prePersist
and preUpdate
hooks to deal with the uploaded file after submitting the corresponding form.
Use something like this :
// Admin class
//...
protected function configureFormFields(FormMapper $formMapper)
$formMapper
//...
->add('file', 'file', array(
'required' => false,
'data_class' => null,
))
//...
;
}
// Called on submit create form.
public function prePersist($entity)
{
$this->manageFileUpload($entity);
return $entity;
}
// Called on submit edit form.
public function preUpdate($entity)
{
$this->manageFileUpload($entity);
return $entity;
}
protected function manageFileUpload($entity)
{
$entity->convertUploadedCsvToArray($entity->getFile())
}
//...
And in your entity :
// Entity
//...
// Unmapped property used for file upload
protected $file;
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile()
{
return $this->file;
}
/**
* Upload attachment file
*/
public function convertUploadedCsvToArray()
{
if (null === $this->getFile()) {
return;
}
$this->getFile()->move('youruploadpath', $this->getFile()->getClientOriginalName());
// Do your logic with the csv file here
$transformer = new CsvDataTransformer();
$discounts = $transformer->transform($this->getFile());
// Set the field using result of parsing.
$this->setDiscounts($discounts);
// Empty the
$this->setFile(null);
}
//...
Hope this helps.
Upvotes: 2