2016-01-11 1 views
2

В проекте Symfony мне нужно сохранить некоторые данные таблицы в сущности, данные, которые должны быть загружены как CSV-документ в Администратор сонаты. Моя первая мысль заключалась в том, чтобы использовать тип данных Doctrine2 json_array для хранения данных, но я был удивлен, обнаружив, что это не такая простая задача.Symfony2: использование поля файла Sonata для загрузки CSV-файла и сохранения его содержимого в Doctrine json_array type

После некоторого исследования я нашел 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

Как указано 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); 
} 

//... 

Надеется, что это помогает.

+0

Я читал, что рецепт кулинарной книги, но я не думаю, что это помогает. Методы 'prePersist' и' preUpdate' не могут изменить объект '$ entity', полученный в качестве параметра. Они могут использовать только содержащиеся в нем данные через 'getSomething()' для выполнения дополнительных задач, но не 'setSomething()'. В этом рецепте вы используете данные изображения для сохранения изображения, которое является другим объектом. В моем конкретном случае у меня нет объекта, связанного с CSV-файлом, мне просто нужны данные, чтобы сохранить его с тем же объектом, который контролируется этим классом администратора. Я нашел решение, опубликую его в ближайшее время. Благодаря! –

+0

Пример в документе использует другой объект, но prePersist может использоваться для установки полей текущего объекта. Я сделал загрузку файла, добавив не-сопоставленный файл $, вызвав мой метод загрузки и установив поле entity с информацией uploadedFile, и все сделано с помощью prePersist hook. – chalasr

+0

Ну что-то должно быть иначе. Я проверил это с другим свойством, и никаких изменений не было. –