Reputation: 883
I'm trying to show a link to download an existing file in Symfony but I have the error which is in the Title.
I have a nursery that uploads her documents and after that I want to show them. I've made this part of the documentation : http://symfony.com/doc/current/form/create_form_type_extension.html. But it doesn't work for me ...
So, This is my Extension where we add 2 options to the form :
<?php
namespace VS\CrmBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\PropertyAccess\PropertyAccess;
class DocumentTypeExtension extends AbstractTypeExtension
{
/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return FileType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined(array('doc_path', 'doc_name'));
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
if(isset($options['doc_path']))
{
$parentData = $form->getParent()->getData();
$documentUrl = null;
if(null !== $parentData)
{
$accessor = PropertyAccess::createPropertyAccessor();
$documentUrl = $accessor->getValue($parentData, $options['doc_path']);
}
$view->vars['doc_path']-> $documentUrl;
}
if(isset($options['doc_name']))
{
$parentData = $form->getParent()->getData();
$documentName = null;
if(null !== $parentData)
{
$accessor = PropertyAccess::createPropertyAccessor();
$documentName = $accessor->getValue($parentData, $options['doc_name']);
}
$view->vars['doc_name']-> $documentName;
}
}
}
Service Definition :
vs_crm.document_type_extension:
class: VS\CrmBundle\Form\Extension\DocumentTypeExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FileType }
View extension :
{% extends 'form_div_layout.html.twig' %}
{% block file_widget %}
{% spaceless %}
{% if (doc_path is not null) and (doc_name is not null) %}
<a href="{{ asset(doc_path) }}">{{ doc_name }}</a>
{% endif %}
{% endspaceless %}
{% endblock %}
My Form :
<?php
namespace VS\CrmBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class NurseryDocumentsType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('docUrl', FileType::class, array(
'label' => 'Choose a PDF file',
'doc_path' => 'nurseryDocumentsPath',
'doc_name' => 'docUrl'
))
->add('isMandatory')
->add('docType');
}
And I've tried to call the form_widget several ways but unsuccessful...
what I don't realy understood from the documentation is : ok, the doc_name in the builForm is going to take my doc_url (whitch is the name of the file saved in the db) but what about the doc_path ? So I dit this (don't be rude :p) :
// NurseryDocuments entity
/**
* @return string|null
*/
public function getNurseryDocumentPath()
{
return __DIR__.'/../../../web/static/documents/NurseryDocuments'.$this->docUrl;
}
Little precisions : 1) I'm trying to show this documents in a step of a multi step form made with CraueFormBundle so I can't pass arguments from the controlle to my flow. 2) I've tried to make an action like :
public function showNurseryDocumentAction($document)
{
$path = $this->get('kernel')->getRootDir().'/../web/static/documents/NurseryDocuments/';
$content = file_get_contents($path.$document);
$response = new Response();
$response->headers->set('Content-Type', 'mime/type');
$response->headers->set('Content-Disposition', 'attachment;filename="'.$document);
$response->setContent($content);
return $response;
}
This works in another context but here I have error ...
Complete error :
The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.
Thanks !
Upvotes: 0
Views: 2984
Reputation: 883
Ok, I have made another form like :
<?php
namespace VS\CrmBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class NurseryDocumentsShowType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('docUrl', TextType::class);
}
public function getParent()
{
return NurseryDocumentsType::class;
}
}
That I use with the download method as you can see higher showNurseryDocumentAction($document)
. So I need one formType for the upload of documents and another to show/download them. Hope it can help someone.
Upvotes: 0
Reputation: 2358
Please Try after adding 'data_class' => null
with docUrl
in FormType
.
NurseryDocumentsType.php
->add('docUrl', FileType::class, array(
'label' => 'Choose a PDF file',
'doc_path' => 'nurseryDocumentsPath',
'doc_name' => 'docUrl',
'data_class' => null
))
Upvotes: 3