Как передать данные в форму CollectionType и получить их там? - PullRequest
0 голосов
/ 24 февраля 2020

Как правильно получить данные, которые отправляются в коллекцию?

Важно:

Если я удалю из класса Create Form эту строку:

'data'=> array_values($builder->getData()->cpus), //TODO: shit code send data And add in Collection 

И добавьте в класс Form Form это:

'data_class' => Command::class, //namespace (Collection\Command)

Это работает только на этапе просмотра (ветки), но сначала я должен получить эти данные перед созданием формы сбора (view).

Как я могу это сделать?

В этот момент я нашел это решение (которое выглядит "дерьмово") :). Строки, помеченные как TODO

Коллекция \ Команда:

class Command
{
    public $id_item;
    /**
     * @var ItemInterface $interface
     */
    public $interface;
    public $id_object;

    public function __construct(string $id_item, ItemInterface $interface)
    {
        $this->id_item = $id_item;
        $this->interface = $interface;
    }

    public function getIdItem(): string
    {
        return $this->id_item;
    }

    public function getInterface(): ItemInterface
    {
        return $this->interface;
    }
}

Проблема в том, что я не могу получить данные из $ cpus хорошим способом :)

Коллекция \ Форма:

class Form extends AbstractType
{
    private $cpuModelFetcher;

    public function __construct(CpuModelFetcher $cpuModelFetcher)
    {
        $this->cpuModelFetcher = $cpuModelFetcher;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $index = (int)$builder->getName(); //TODO: shit code - use name of form as index.
        /**
         * @var Command $command
         */
        $command = $builder->getData()[$index]; //TODO: shit code get data from array

        $builder
            ->add('id_object', Type\ChoiceType::class,
                [
                    'choices' => array_flip($this->cpuModelFetcher->getSupportedCpuModelListForModelBasedDeviceBySocketType(
                        $command->getIdItem(),$command->getInterface()->getId())),
                    'placeholder' => 'not installed in '.$command->getInterface()->getName().' socket.',
                    'required' => false,
                ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults(array(
            //'data_class' => Command::class,
            'data_class' => null,
        ));
    }
}

Команда создания:

class Command
{
    /**
     * @Assert\NotBlank()
     */
    private $id;
    public $cpus;

    private function __construct(Id $id)
    {
        $this->id = $id;
    }

    public static function fromDevice(Device $device): self
    {
        $command = new self($device->getId());
        if($device->getBasedType()->isModelBasedDevice()){
            $command->cpus = $command->transformDeviceModelInterfaceCollectionToCommandArray($device->getId(),
                $device->getModelBasedDevice()->getDeviceModel()->getCpuInterfaces());
        }

        return $command;
    }

    private function transformDeviceModelInterfaceCollectionToCommandArray(Id $id_item, ArrayCollection $interfaces): array
    {
        $object_specific_interfaces = [];
        foreach ($interfaces as $one){
            /**
             * @var DeviceModelInterface $one
             */
            for($i=0; $i<$one->getAmount(); $i++){
                $object_specific_interfaces[] = new Collection\Command($id_item->getValue(), $one->getInterface());
            }
        }
        unset($one);
        return $object_specific_interfaces;
    }
}

Форма создания:

class Form extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        //dump($builder);
        $builder
            ->add('cpus', CollectionType::class, [
                'label' => false,
                'entry_type' => Collection\Form::class,
                'entry_options' => [
                    'label' => false,
                    'data'=> array_values($builder->getData()->cpus), //TODO: shit code send data
                ],
                'by_reference' => true,
                'allow_add' => false,
                'allow_delete' => false,
                'delete_empty' => true,
            ])
            ->add('save', Type\SubmitType::class, [
                'attr' => ['class' => 'btn btn-primary'],
            ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults(array(
            'data_class' => Command::class,
        ));
    }
}

Спасибо за любая помощь.

1 Ответ

0 голосов
/ 24 февраля 2020

Я нашел это решение, которое выглядит лучше, я просто получаю данные из события PRE_SET_DATA в классе Collection \ Form.

class Form extends AbstractType
{
    private $cpuModelFetcher;

    public function __construct(CpuModelFetcher $cpuModelFetcher)
    {
        $this->cpuModelFetcher = $cpuModelFetcher;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {

        $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
    }

    protected function addElements(FormInterface $form, $data): void
    {
        /**
         * @var Command $data
         */
        $form->add('id_object', Type\ChoiceType::class,
            [
                'choices' => array_flip($this->cpuModelFetcher->getSupportedCpuModelListForModelBasedDeviceBySocketType(
                    $data->getIdItem(), $data->getInterface()->getId())),
                'placeholder' => 'not installed in '.$data->getInterface()->getName().' socket.',
                'required' => false,
            ]);
        //dump($data);
        //dump($form);
    }

    function onPreSetData(FormEvent $event): void
    {
        $form = $event->getForm();
        $data = $event->getData();

        $this->addElements($form, $data);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults(array(
            'data_class' => Command::class,
        ));
    }
}

В любом случае, если кто-то знает другое решение, я буду рад услышь это.

Спасибо.

...