Symfony2:使用Sonata文件字段上传CSV文件并将其内容存储在Doctrine json_array类型中

时间:2016-01-11 09:53:56

标签: php symfony doctrine-orm sonata-admin

在Symfony项目中,我需要在实体上存储一些表数据,这些数据应该在Sonata admin中作为CSV文档上传。我的第一个想法是使用Doctrine2 json_array数据类型来存储数据,但我很惊讶地发现它并不是一件容易的事。

经过一番研究后,我发现Symfony\Component\Form\DataTransformerInterface似乎是将CSV文件转换为数组的正确选择。问题是transform($value)方法未在$value参数中接收上传的文件,因此我坚持这一点。

在实体管理类中,我有:

$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
   }
}

有没有更好的方法来获得这个?

1 个答案:

答案 0 :(得分:2)

正如Sonata documentation (Uploading and serving documents)所述,您应在提交相应表单后使用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);
}

//...

在您的实体中:

    $('#enable_autosave').click(function () {
        if ($(this).prop('checked')) {
            document.getElementById("autosave_information").innerHTML = "Aktiviert";
            document.getElementById("warning_information_all").style = "";
            IntervalId = setInterval(function Save_Pointer(){Save();}, 10000);
        } else {
            clearInterval(IntervalId);
            document.getElementById("autosave_information").innerHTML = "Deaktiviert";
            document.getElementById("warning_information_all").style = "visibility:hidden";
        }
    });

希望这有帮助。