в приложении symfony2 сообщение «Сущность» имеет отношение «один ко многим» к документам. Документы представляют пользовательские загрузки. Я создал форму. Я понял две формы: MessageForm и DocumentForm. DocumentForm живет внутри коллекции FormField в MessageForm. Загрузка и обработка файлов действительно работает.
Но если я хочу отредактировать сообщение «Сущность», Form содержит столько пустых файлов, сколько есть «Документы». желаемое поведение:
Это должно обрабатываться внутри формы. Изменения должны быть сделаны при отправке формы.
Как это можно реализовать?
Решение состоит в том, чтобы написать расширение пользовательского типа. как описано в http://symfony.com/doc/2.1/cookbook/form/create_form_type_extension.html .
<?php use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\Util\PropertyPath; use Symfony\Component\OptionsResolver\OptionsResolverInterface; /** * Class FileTypeExtension * * @see http://symfony.com/doc/2.1/cookbook/form/create_form_type_extension.html */ class FileTypeExtension extends AbstractTypeExtension { /** * Returns the name of the type being extended. * * @return string The name of the type being extended */ public function getExtendedType() { return 'file'; } /** * Add the image_path option * * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setOptional(array('file_path', 'file_name')); } /** * Pass the image url to the view * * @param FormView $view * @param FormInterface $form * @param array $options */ public function buildView(FormView $view, FormInterface $form, array $options) { if (array_key_exists('file_path', $options)) { $parentData = $form->getParent()->getData(); if (null !== $parentData) { $propertyPath = new PropertyPath($options['file_path']); $fileUrl = $propertyPath->getValue($parentData); } else { $fileUrl = null; } $view->set('file_url', $fileUrl); } if (array_key_exists('file_name', $options)) { $parentData = $form->getParent()->getData(); if (null !== $parentData) { $propertyPath = new PropertyPath($options['file_name']); $fileName = $propertyPath->getValue($parentData); } else { $fileName = null; } $view->set('file_name', $fileName); } } }
{% block file_widget %} {% spaceless %} {% if file_url is not null %} <div><a href="{{ file_url }}">{{ file_name }}</a></div> <div style="display:none">{{ block('form_widget') }}</div> {% else %} {{ block('form_widget') }} {% endif %} {% endspaceless %} {% endblock %}
parameters: foobar.file_type_extension.class: Foobar\Form\Extension\FileTypeExtension services: foobar.file_type_extension: class: %replacethis.file_type_extension.class% tags: - { name: form.type_extension, alias: file }
$builder->add('file','file', array( "label" => "Datei", "required" => true, "attr" => array(), "file_path" => "webPath", "file_name" => "name" ));
это оно 😉
В дополнение к вышеуказанным ответам, которые позволят вам создать файл, который может быть отображен как ссылка (если у него есть URL) или поле (если это не так) – вы можете взглянуть на
http://symfony.com/doc/2.0/cookbook/form/form_collections.html
В сочетании с некоторыми jQuery вы сможете добавлять поля в пользовательский интерфейс.