使用symfony Form Component重构普通请求数据解析

时间:2016-02-11 00:27:29

标签: php forms symfony symfony-forms

所以我在这里有一个带有这个动作方法的控制器:

public function addAction(Request $request)
{
    $tournamentId = $request->request->get('tournament_id');
    $externalId = $request->request->get('external_id');
    $eventDate = $request->request->get('event_date');

    if (!is_numeric($tournamentId) || !is_numeric($externalId) || empty($eventDate)) {
        throw new InvalidArgumentException('Invalid POST data');
    }

    $em = $this->getDoctrine()->getManager();
    $tournament = $em->getRepository('BakingBankCoreBundle:TournamentGame')->find($tournamentId);

    if (empty($tournament)) {
        throw new InvalidArgumentException('Invalid tournament ID');
    }

    $entity = new TournamentInstance();
    $entity->setTournament($tournament);
    $entity->setExternalId($externalId);
    $entity->setEventDate(new DateTime($eventDate));

    $em->persist($entity);
    $em->flush();

    return new JsonResponse(['id' => $entity->getId()]);
}

我的同事要我重构这个以使用表格。问题是 - TournamentInstance字段如下:

/**
 * @var TournamentGame
 *
 * @ORM\ManyToOne(targetEntity="TournamentGame")
 * @ORM\JoinColumn(name="tournament_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
 */
private $tournament;

/**
 * @var string
 *
 * @ORM\Column(name="external_id", type="string", length=64, nullable=false)
 */
private $externalId;

/**
 * @var DateTime
 *
 * @ORM\Column(name="event_date", type="date", nullable=false)
 */
private $eventDate;

POST数据不是从树枝形式发送的,而是来自JS中的AJAX请求,其中数据是从代码中的多个位置收集的。

我怎么能做到这一点,甚至值得呢?我知道他希望一切都是标准化的,但我认为他比我更理想主义(并且说了很多)。

1 个答案:

答案 0 :(得分:1)

不需要太多工作,因为您只需将实体属性映射到表单字段:

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TextType;

public function addAction(Request $request)
{
    $entity = new TournamentInstance();

    // you can set default value with $entity->setEventDate(new DateTime('tomorrow'))
    // before passing it as data to the form builder

    $form = $this->createFormBuilder($entity) // set the default value
        // you need to add a field for each property accordingly to its name
        ->add('tournament', EntityType::class) // will output a select with all tournaments
        ->add('external_id', TextType::class)
        ->add('external_date', DateTimeType::class)

    $form->handleRequest($request) // will synchronize post values to the new entity

    if ($form->isSubmitted() && $form->isValid()) { // validate the form
        $em = $this->getDoctrine()->getManager();

        $filledEntity = $form->getData();

        $em->persist($filledEntity);
        $em->flush();

        return new JsonResponse(['id' => $filledEntity->getId()]);
    }

    if (0 < count($form->getErrors)) {
        return new JsonResponse(['errors' => $form->getErrors()]);
    }

    return new JsonResponse(['errors' => ['No data matching form type']]);
}

如果您需要经过微调验证,可以在类属性中使用约束作为注释。

请参阅http://symfony.com/doc/current/book/forms.html

http://symfony.com/doc/current/book/forms.html#form-validation