【问题标题】:Symfony2 Asset GreaterThan didn't workSymfony2 Asset GreaterThan 没有工作
【发布时间】:2014-04-24 14:39:27
【问题描述】:

其实我有一个问题。 Inventory 实体中的“Quantity”属性不应为负数。

所以我尝试在我的实体声明中使用 GreaterThan 或 GreaterThanOrEqual 断言。

事实上,我可以验证负数。 我不明白。

实体:

/* src/Clicproxy/***Bundle/Entity/Inventory.php */
<?php

namespace Clicproxy\***Bundle\Entity;

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


/**
 * Inventory
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Clicproxy\***Bundle\Entity\InventoryRepository")
 * @UniqueEntity(fields="audit, name", message="entity.inventory.unique")
 */
class Inventory
{
    /* [...] */

    /**
     * @var integer
     *
     * @ORM\Column(name="quantity", type="integer", nullable=true)
     * @Assert\GreaterThan(value = 1)
     */
    private $quantity;

[...]

表单类型:

/* src/Clicproxy/***Bundle/Form/InventoryCollabType.php */
<?php

namespace Clicproxy\***Bundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class InventoryCollabType extends AbstractType
{
        /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('quantity', null, array('label' => 'entity.inventory.quantity'))
            ->add('pageCostBlack', null, array('label' => 'entity.inventory.pagecostblack'))
            ->add('pageCostColor', null, array('label' => 'entity.inventory.pagecostcolor'))
            ->add('avMonthPagesBlack', null, array('label' => 'entity.inventory.avmonthpagesblack'))
            ->add('avMonthPagesColor', null, array('label' => 'entity.inventory.avmonthpagescolor'))
        ;
    }

    /* [...] */
}

控制器:

public function configAction (Request $request, $slug)
{
    $em = $this->getDoctrine()->getManager();
    $audit = $em->getRepository('Clicproxy***Bundle:Audit')->findOneBy(array('slug' => $slug));

    if (!$audit instanceof Audit) {
        throw $this->createNotFoundException('wizard.config.notfound');
    }

    $audit->addInventoriesFromEquipments($em->getRepository('Clicproxy***Bundle:Equipment')->findBy(array(), array('optimized' => 'ASC', 'name'=> 'ASC')));

    $form = $this->createCreateConfigForm($audit);

    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($audit);
        foreach ($audit->getInventories() as $inventory) {
            $inventory->setAudit($audit);
            $em->persist($inventory);
        }
        $em->flush();

        /* [...] */

        return $this->redirect($this->generateUrl('wizard_result', array('slug' => $audit->getSlug())));
    }

    /* [...] */

    return array(
        'audit' => $audit,
        'form'   => $form->createView(),
        'tabactive' => 2,
    );
}

有人知道我的上下文吗?

感谢您的支持, 大卫。

编辑: 最后我在下面写了这段代码,你的意见?

public function configAction (Request $request, $slug)
{
    $em = $this->getDoctrine()->getManager();
    $audit = $em->getRepository('Clicproxy***Bundle:Audit')->findOneBy(array('slug' => $slug));

    if (!$audit instanceof Audit) {
        throw $this->createNotFoundException('wizard.config.notfound');
    }

    $audit->addInventoriesFromEquipments($em->getRepository('Clicproxy***Bundle:Equipment')->findBy(array(), array('optimized' => 'ASC', 'name'=> 'ASC')));

    $form = $this->createCreateConfigForm($audit);

    $form->handleRequest($request);

    if ($form->isValid()) {
        $validator = $this->get('validator');
        $errors_messages = array();
        foreach ($audit->getInventories() as $inventory)
        {
            $violations = $validator->validate($inventory);
            if (0 < $violations->count()) 
            {
                $error_message = substr($violations, strpos($violations, ':')+2);
                if (! in_array($error_message, $errors_messages, true)) {
                    $errors_messages[] = $error_message;
                    $this->get('session')->getFlashBag()->add('error', $error_message);
                }

            }
        }
        if (! $this->get('session')->getFlashBag()->has('error'))
        {
            $em = $this->getDoctrine()->getManager();
            $em->persist($audit);
            foreach ($audit->getInventories() as $inventory) {
                $inventory->setAudit($audit);
                $em->persist($inventory);
            }
            $em->flush();

            /* [...] */

            return $this->redirect($this->generateUrl('wizard_result', array('slug' => $audit->getSlug())));
        }
    }


    return array(
        'audit' => $audit,
        'form'   => $form->createView(),
        'tabactive' => 2,
    );
}

感谢您的支持。

【问题讨论】:

  • 你能展示你用来处理表单提交的逻辑吗?
  • 我刚刚添加了逻辑。

标签: forms validation symfony doctrine


【解决方案1】:

您不是在验证您的实体,而是在验证您的表单。

当您调用 $form-&gt;isValid() 时假设您的 Doctrine 实体正在被验证,这是一个常见的错误,但事实并非如此。

您需要显式调用验证器服务并将其与表单验证分开处理。

看起来像这样:

$validator = $this->get('validator');
$errors = $validator->validate($inventory);

if (count($errors) > 0) {
    // Handle errors here
}

如需了解更多信息,请查看validation documentation

【讨论】:

  • 我只是把我刚刚写的代码加进去,你能给我意见吗?
  • 您应该在 if 语句中返回一个错误,在该语句中检查是否存在违规行为。那和0 &lt; $violations-&gt;count() 真的很尴尬。写$violations-&gt;count() &gt; 0 更易读。除此之外,它看起来不错
  • 我已经添加了$form-&gt;get('XXX')-&gt;addError(new FormError('Message'));来处理模板中的错误信息。
猜你喜欢
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 2016-02-19
相关资源
最近更新 更多