如何在Symfony 2表单字段中设置默认值?

时间:2012-06-29 15:20:41

标签: forms symfony validation

我一直在尝试使用Symfony 2设置表单。

所以我跟着the tutorial,我创建了一个特殊的类来创建表单并在控制器外部处理验证过程(如文档中所示)

但是现在我需要自动填写一个字段,我听说我必须在ProductType.php中创建它,在那里创建表单(对于我的产品)。

但我不知道怎么做,这是我在ProductType.php中的buildForm函数:

class QuotesType extends AbstractType
{
    private $id;

    public function __construct($id){
        $this->product_id = $id;
    }

    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('user_name',              'text')
            ->add('user_lastname',          'text')
            ->add('user_email',             'email')
            ->add('user_comments',          'textarea')
            ->add('user_product_id',        'hidden', array(
                'data' => $this->product_id,
            ));
        ;
    }

它显然无法工作,因为我收到一条SQL错误,说我的字段为空。

如何将默认值添加到user_product_id?我应该直接对象吗?

编辑:

以下是我的实体代码的一部分:

namespace QN\MainBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * QN\MainBundle\Entity\Quotes
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="QN\MainBundle\Entity\QuotesRepository")
 */
class Quotes
{

    public function __construct($p_id)
    {
        $this->date = new \Datetime('today');
    }
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var integer $user_product_id
     *
     * @ORM\Column(name="user_product_id", type="integer")
     */
    private $user_product_id = "1";

    /**
     * @var datetime $date
     *
     * @ORM\Column(name="date", type="datetime")
     */
    private $date;

我的控制员:

public function requestAction($id)
    {
        $repository = $this->getDoctrine()
                           ->getEntityManager()
                           ->getRepository('QNMainBundle:Categories');
    $categories = $repository->findAll();

    $quote = new Quotes($id);
    $form = $this->createForm(new QuotesType(), $quote);

    $formHandler = new QuotesHandler($form, $this->get('request'), $this->getDoctrine()->getEntityManager());

    if( $formHandler->process() )
    {
        return $this->redirect( $this->generateUrl('QNMain_Product', array('id' => $id)) );
    }

    return $this->render('QNMainBundle:Main:requestaform.html.twig', array(
        'categories' => $categories,
        'id' => $id,
        'form' => $form->createView(),
    ));

}

我的处理程序:

namespace QN\MainBundle\Form;

use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManager;
use QN\MainBundle\Entity\Quotes;

class QuotesHandler
{
    protected $form;
    protected $request;
    protected $em;

    public function __construct(Form $form, Request $request, EntityManager $em)
    {
        $this->form    = $form;
        $this->request = $request;
        $this->em      = $em;
    }

    public function process()
    {
        if( $this->request->getMethod() == 'POST' )
        {
            $this->form->bindRequest($this->request);

            if( $this->form->isValid() )
            {
                $this->onSuccess($this->form->getData());

                return true;
            }
        }

        return false;
    }

    public function onSuccess(Quotes $quote)
    {
        $this->em->persist($quote);
        $this->em->flush();
    }

}

我也在这里放置Date我尝试在实体中设置,我可能在这两种情况下做错了,因为我不能使它既不工作..Date不在{{ 1}}功能,我不知道是否应该......

2 个答案:

答案 0 :(得分:2)

你在这里要做的是创建一个安全漏洞:任何人都可以在user_product_id字段中注入任何ID并欺骗你的应用程序。没有提到渲染一个字段并且没有显示它是没用的。

您可以在实体中将默认值设置为user_product_id

/**
 * @ORM\Annotations...
 */
private $user_product_id = 9000;

答案 1 :(得分:2)

对我来说,最好的方法是创建Form Type Extension

class Comit < ActiveRecord::Base
  belongs_to :user
  mount_uploader :file_url, ComitUploader, mount_on: :file_url
  validates :filename, :file_url, presence: true
  validates_format_of :file_url, with: /.xls/, message: "Wrong file format"
  before_save :validate_excel

  def validate_excel
    sheet = Roo::Excel.new(:file_url)
    errors = []

    header = sheet.row(1)
    num_of_columns = sheet.last_column

    errors << 'Need headers' unless
    errors << 'Need more columns' if num_of_columns < 21

    errors
  end
end

注册课程:

namespace AppBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;

class DefaultValueTypeExtension extends AbstractTypeExtension
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if (null !== $options['default']) {
            $default = $options['default'];

            $builder->addEventListener(
                FormEvents::PRE_SET_DATA,
                function (FormEvent $event) use ($default) {
                    if (null === $event->getData()) {
                        $event->setData($default);
                    }
                }
            );
        }
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array('default' => null));
    }

    /**
     * {@inheritdoc}
     */
    public function getExtendedType()
    {
        return 'Symfony\Component\Form\Extension\Core\Type\FormType';

        // before 2.8:
        // return 'form';
    }
}

现在任何可能的值都可以在字段表单上作为默认值传递:

services:
    # forms
    app.form.extension:
        class: AppBundle\Form\Extension\DefaultValueTypeExtension
        tags:
            - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }

            # before 2.8: 
            #- { name: form.type_extension, alias: form }