SonataMediaBundle - Как использовать пользовательский ввод файлов

У меня есть своего рода проект поиска мусора, в котором я использую AngularJS для управления различными вопросами, которые он может содержать. Эти вопросы бывают разных типов. Поэтому некоторые могут включать ввод файла, а некоторые нет. В этом проекте я также использую Symfony и SonataMediaBundle для управления своими файлами и изображениями.

Поскольку моя html-модель (в основном мои формы) может меняться в зависимости от действий пользователя, я не могу использовать встроенный инструмент Symfony для создания форм. Поэтому все мои формы изготавливаются на заказ. Это вызывает у меня проблему с SonataMediaBundle, когда я хочу загрузить некоторые файлы. Если пользователь выбирает файл, этот файл будет отправлен через POST методу в контроллере при отправке формы. Поэтому я хочу отправить этот полученный файл в SonataMediaBundle, чтобы он мог им управлять, но я нигде не нашел в документации, как это сделать.

Теоретически это действительно просто. В моем контроллере, когда я получаю ввод файла, я хочу, чтобы SonataMedia управляла загрузкой (то есть копированием в нужное место и т. Д.), И я понятия не имею, как мне это сделать.


person Etienne Noël    schedule 27.02.2014    source источник
comment
Возможно, вам стоит взглянуть на: gist.github.com/romaricdrigon/6291435. Это позволяет вам использовать способ создания форм Symfony в сочетании с AngularJS. Вы можете создать форму любым удобным для вас способом и вернуть ее из серверной части в свой SPA.   -  person Bart Van Remortele    schedule 06.03.2014


Ответы (2)


Используя symfony2 и не используя его преимущества, вы совершаете большую ошибку, вы должны правильно создать свое приложение, но что касается вашего вопроса, ничто не ограничено symfony, но вы сами можете его использовать. Вы можете получить сервис медиа-менеджера сонаты. из контейнера, и вам нужно вручную установить все необходимые сеттеры для медиа-менеджера, и вам нужно вручную работать над проверками, такими как размер файла, тип файла и т. д. Ниже приведена демонстрация того, как вы можете сохранить файл в пакете мультимедиа сонаты.

/* Before class use these*/
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Application\Sonata\MediaBundle\Entity\Media;

public function uploadAction()
{

$file = $this->get('request')->files->get('filefieldname');

    if (!$file instanceof UploadedFile || !$file->isValid()) {
        return new Response(json_encode(array(
            'event' => 'uploader:error',
            'data'  => array(
                'message' => 'Missing file.',
            ),
        )));
    }

/* validate max min size for the file */
/* validate mime type for the file */
/* Get sonata media manager service from container    */ 
$mediaManager = $this->container->get('sonata.media.manager.media');
/* create new instance of sonata media class in my case entity is located at 
* Application\Sonata\MediaBundle\Entity\Media 
*/
$media = new Media();
$media->setBinaryContent($file);
$media->setContext('default'); 
$ImagemimeTypes = array('image/jpeg', 'image/png');
$FilemimeTypes = array('application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/msword', 'application/pdf', 'application/x-pdf');
if (in_array($file->getMimeType(), $FilemimeTypes)) {
    $media->setProviderName('sonata.media.provider.file');
}
if (in_array($file->getMimeType(), $ImagemimeTypes)) {
    $media->setProviderName('sonata.media.provider.image');
}
 /*If you have other providers in your app like vimeo /dailymotion etc
 then do set here i have shown you the demo for adding image/file in sonata media */
/*other setters if you want to set like enabled/disable etc*/
 $mediaManager->save($media);
// end function
}

Но опять же, вам придется сделать много доработок, которые Symfony уже предоставляет вам с легкостью.

person M Khalid Junaid    schedule 07.03.2014

Bundle призван закрыть именно этот разрыв между Symfony и SonataMedia. SonataMedia создана для исходного PHP, тогда как SonataMediaBundle подключает интерфейсы Symfony к SonataMedia; вы переписываете большую часть функциональности Bundle. Чтобы получить хороший пример того, как это делается правильно, посмотрите код Bundle ;)

Извините, если следующее предложение вы тщательно обдумали, я просто не могу быть уверенным из-за ограниченной информации в вопросе. Формы Symfony очень гибкие и предоставляют множество важных функций, которые вам не следует пытаться реализовать самостоятельно (например, CSRF-токены). Большинство проблем имеет хорошее решение с помощью системы форм. Если форма метаморфична (имеет множество полей, основанных на взаимодействии с пользовательским интерфейсом) и не может обрабатываться несколькими типами форм, у вас все еще есть варианты. Если вы можете установить параметр GET, указывающий, какой тип формы отправляется в данный момент, вы можете передать его в FormBuilder. Вы даже можете создать одну большую форму для всего приложения, содержащую все поля, которые вы когда-либо использовали — это немного пустая трата времени, но все же лучше, чем пытаться связать публикацию + сонату вместе. Самое обидное, что делает первая версия, это лишние байты и пустое поле. Наименьший вред, который вы можете сделать, — это создать серьезные утечки безопасности.

person Levente Pánczél    schedule 03.03.2014
comment
Я мог бы сделать то, о чем вы говорите, если бы не это. У меня может быть до 20 вопросов, и каждый вопрос может быть разных типов (у меня 10 разных типов вопросов). Поэтому мне пришлось бы перейти на свою страницу, 200 разных форм, чтобы я мог управлять всеми различными возможностями, и это кажется не очень хорошим вариантом... - person Etienne Noël; 03.03.2014
comment
Если вы говорите, что у вас есть 10 типов, я понимаю, что у вас есть 10 вариантов полей. Если каждый вопрос может иметь форму любого типа, то я вижу два шага. 1) Создайте один класс FormType, который создает столько полей, что может содержать любой из 10 типов (например, если есть текст и радио для типа 1 и текст и 3 флажка для типа 2, тогда вы создаете форму с текстом, радио и 3 флажка). 2) Получите конструктор форм и для каждого вопроса $builder->add() один экземпляр этого FormType (параметры его конструктора могут заботиться об отдельных списках «выборов» и о том, какие поля действительно нужно добавить. - person Levente Pánczél; 04.03.2014
comment
Если вы по-прежнему не считаете, что это легко решит проблему, отредактируйте вопрос так, чтобы мы видели по крайней мере 2-3 из 10 типов вопросов и 2-3 из 20 вопросов, желательно в какой-либо комбинации, чтобы мы может понять, почему это представляет собой гораздо более сложную задачу, чем следовало бы. - person Levente Pánczél; 04.03.2014