Как сделать выбор из массива в Symfony Entity - PullRequest
2 голосов
/ 04 марта 2020

Я новичок в symfony и все еще учусь, мой вопрос в том, как мне заполнить выпадающий список в форме массивом stati c вариантов выбора. Скажем, у меня есть класс с именем Cake, я хотел бы иметь возможность заполнить раскрывающийся список для status из Cake из массива statuses, созданного в том же CakeEntity:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\CakeRepository")
 */
class Cake
{
    /**
     * @ORM\Column(type="string", length=50)
     */

    private $status;

    private $statuses = array(
        'not_ready' => 'Not Ready',
        'almost_ready' => 'Almost Ready',
        'ready'=>'Ready',
        'too_late'=>'Too late'
    );
    public function getStatus(): ?string
    {
        return $this->status;
    }

    public function setStatus(string $status): self
    {
        $this->status = $status;
        return $this;
    }

    public function getStatuses()
    {
       return $this->statuses;
    }
}

Мой контроллер выглядит так:

namespace App\Controller;

use App\Entity\Cake;
use App\Form\CakeType;
use App\Repository\CakeRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;


/**
 * @Route("/cake")
 */
class CakeController extends AbstractController
{
    /**
     * @Route("/new", name="cake_new", methods={"GET","POST"})
     */
    public function new(Request $request): Response
    {
        $cake = new Cake();
        $form = $this->createForm(CakeType::class, $cake);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $cake->setCreatedAt(\DateTime::createFromFormat('d-m-Y', date('d-m-Y')));
            $cake->setCreatedBy(1);
            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($cake);
            $entityManager->flush();

            return $this->redirectToRoute('cake_index');
        }

        return $this->render('cake/new.html.twig', [
            'cake' => $cake,
            'form' => $form->createView(),
        ]);
    }

My CakeEntity:

<?php

namespace App\Form;

use App\Entity\cake;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;

class CakeType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        ->add('status', ChoiceType::class,
            [
                'choices'=>function(?Cake $cake) {
                    return $cake->getStatuses();
                }
            ]);
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Cake::class,
        ]);
    }
}

При попытке просмотреть /cake/new я получаю сообщение об ошибке:

Ошибка произошло разрешение параметров формы "Symfony \ Component \ Form \ Extension \ Core \ Type \ ChoiceType": ожидается, что параметр "выборы" со значением Closure будет иметь тип "null" или "array" или "\ Traversable" , но имеет тип "Закрытие".

1 Ответ

2 голосов
/ 04 марта 2020

Вы можете объявить getStatuses на Cake как static или использовать константы publi c. Например:

class Cake
{
    // with static variables

    private static $statuses = [
        'not_ready'    => 'Not Ready',
        'almost_ready' => 'Almost Ready',
        'ready'        => 'Ready',
        'too_late'     => 'Too late',
    ];

    public static function getStatuses()
    {
        return self::$statuses;
    }

    // or with public const

    public const STATUSES = [
        'not_ready'    => 'Not Ready',
        'almost_ready' => 'Almost Ready',
        'ready'        => 'Ready',
        'too_late'     => 'Too late',
    ];
}

Это кажется разумным, поскольку возвращаемое значение является не экземпляром, а спецификацией класса c.


Затем можно использовать:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('status', ChoiceType::class, [
        'choices'=> Cake::getStatuses(),
    ]);

    // or

    $builder->add('status', ChoiceType::class, [
        'choices'=> Cake::STATUSES,
    ]);
}

Если выбор действительно зависит от данного экземпляра Cake, вы можете передать его через массив параметров или использовать события формы .

...