Symfony2:使用 Sonata 文件字段上传 CSV 文件并将其内容存储在 Doctrine json_array 类型中
Symfony2: Using Sonata file field to upload a CSV file and store its content in a Doctrine json_array type
在 Symfony 项目中,我需要在实体上存储一些 table 数据,这些数据应该作为 CSV 文档上传到 Sonata admin 中。我的第一个想法是使用 Doctrine2 json_array
数据类型来存储数据,但我惊讶地发现这并不是一件容易的事。
经过一些研究,我发现 Symfony\Component\Form\DataTransformerInterface 似乎是将 CSV 文件转换为数组的正确选择。问题是 transform($value)
方法没有在 $value
参数中接收上传的文件,所以我坚持这个。
在实体管理员中 class 我有:
$formMapper
[...]
->add($formMapper->create('discounts', 'file', array(
'required' => false,
'data_class' => null
))
->addViewTransformer(new CSVToArrayTransformer()))
其中 CSVToArrayTransformer
看起来像这样:
class CSVToArrayTransformer implements DataTransformerInterface
{
public function transform($csvFile){
// here should take place the csv to array transformation, but $csvFile is null
}
}
有没有更好的获取方法?
如Sonata documentation (Uploading and serving documents)所述,您应该在提交相应的表单后使用prePersist
和preUpdate
钩子来处理上传的文件。
使用这样的东西:
// 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())
}
//...
在您的实体中:
// 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);
}
//...
希望这对您有所帮助。
在 Symfony 项目中,我需要在实体上存储一些 table 数据,这些数据应该作为 CSV 文档上传到 Sonata admin 中。我的第一个想法是使用 Doctrine2 json_array
数据类型来存储数据,但我惊讶地发现这并不是一件容易的事。
经过一些研究,我发现 Symfony\Component\Form\DataTransformerInterface 似乎是将 CSV 文件转换为数组的正确选择。问题是 transform($value)
方法没有在 $value
参数中接收上传的文件,所以我坚持这个。
在实体管理员中 class 我有:
$formMapper
[...]
->add($formMapper->create('discounts', 'file', array(
'required' => false,
'data_class' => null
))
->addViewTransformer(new CSVToArrayTransformer()))
其中 CSVToArrayTransformer
看起来像这样:
class CSVToArrayTransformer implements DataTransformerInterface
{
public function transform($csvFile){
// here should take place the csv to array transformation, but $csvFile is null
}
}
有没有更好的获取方法?
如Sonata documentation (Uploading and serving documents)所述,您应该在提交相应的表单后使用prePersist
和preUpdate
钩子来处理上传的文件。
使用这样的东西:
// 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())
}
//...
在您的实体中:
// 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);
}
//...
希望这对您有所帮助。