Okay, this gets a little convoluted, so bear with me. I'll try and keep it clear and concise.
I'm using Symfony2's very nice form builder system for simple crud, but the basic file upload element doesn't quite meet my needs, so I want to extend it by adding a thumbnail preview, and some other niceties.
Reading this, I found that I can create my own custom template block for rendering file elements:
http://symfony.com/doc/master/cookbook/form/form_customization.html#twig
Which is really cool, and seems to be working perfectly. However, I'm storing the path for my file upload in a separate attribute in the entity, based on this:
http://symfony.com/doc/master/cookbook/doctrine/file_uploads.html
So, I need some way for the template to access the path field. I created a custom FileType class like this:
<?php
namespace TechPeople\InvoiceBundle\Component\Form\Type;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\Type\FileType as SymfonyFileType;
class FileType extends SymfonyFileType {
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars = array_replace($view->vars, array(
'type' => 'file',
'value' => '',
'path' => $options['path'],
));
}
}
And then I passed the file path into the form builder like this:
<?php
namespace TechPeople\InvoiceBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class InvoiceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
echo 'test';
$builder
->add('month')
->add('year')
->add('expenses')
->add('due')
->add('paid')
->add('created')
->add('expense_amount', 'money')
->add('total_amount', 'money')
->add('attachment', 'file', array('path'=>$options['data']->getAttachmentPath()))
->add('vendor')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'TechPeople\InvoiceBundle\Entity\Invoice'
));
}
public function getName()
{
return 'techpeople_invoicebundle_invoicetype';
}
}
Well, that seemed pretty groovy, but then I get this error loading the form:
The option "path" does not exist. Known options are: "attr", "block_name", "by_reference", "cascade_validation", "compound", "constraints", "csrf_field_name", "csrf_protection", "csrf_provider", "data", "data_class", "disabled", "empty_data", "error_bubbling", "error_mapping", "extra_fields_message", "intention", "invalid_message", "invalid_message_parameters", "label", "label_attr", "mapped", "max_length", "pattern", "post_max_size_message", "property_path", "read_only", "required", "translation_domain", "trim", "validation_constraint", "validation_groups", "virtual"
500 Internal Server Error - InvalidOptionsException
So, it looks like there's a list of allowed options somewhere, but I can't find it. Additionally, I'm not 100% sure that the add() method in InvoiceType is passing the options array to the buildView() method in FileType. I'm having trouble tracing the code between these two things.