2

さて、これは少し複雑になるので、我慢してください。私はそれを明確かつ簡潔に保つように努めます。

シンプルなクラッドにSymfony2の非常に優れたフォームビルダーシステムを使用していますが、基本的なファイルアップロード要素が私のニーズを完全に満たしていないため、サムネイルプレビューなどを追加して拡張したいと思います。

これを読んで、ファイル要素をレンダリングするための独自のカスタムテンプレートブロックを作成できることがわかりました。

http://symfony.com/doc/master/cookbook/form/form_customization.html#twig

これは本当にクールで、完璧に機能しているようです。ただし、これに基づいて、ファイルアップロードのパスをエンティティの別の属性に保存しています。

http://symfony.com/doc/master/cookbook/doctrine/file_uploads.html

したがって、テンプレートがパスフィールドにアクセスするための何らかの方法が必要です。次のようなカスタムFileTypeクラスを作成しました。

<?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'],
        ));
    }
}

次に、ファイルパスを次のようにフォームビルダーに渡しました。

<?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';
    }
}

まあ、それはかなりかっこいいように見えました、しかしそれから私はフォームをロードするこのエラーを受け取ります:

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

ですから、どこかに許可されたオプションのリストがあるように見えますが、私はそれを見つけることができません。さらに、InvoiceTypeのadd()メソッドがoptions配列をFileTypeのbuildView()メソッドに渡しているかどうかは100%わかりません。これら2つの間のコードをトレースするのに問題があります。

4

1 に答える 1

2

まず、カスタムクラスを作成したら、fileタイプとして使用するように宣言(登録)する必要があります: http ://symfony.com/doc/current/reference/dic_tags.html#form-type

<?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'],
    ));
}

/**
 * {@inheritdoc}
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'path' => null,
    ));
}

/**
 * {@inheritdoc}
 * 
 * POTENTIALLY declare it as child of file type.
 */
public function getParent()
{
    return 'file';
}
}
于 2013-01-10T09:55:04.820 に答える