Как получить доступ к сервисам или конфигурации изнутри формы

Как получить доступ к сервисам или конфигурации изнутри формы

Иногда вам может понадобиться получить доступ к сервису или другой конфигурации изнутри вашего класса формы. Чтобы сделать это, у вас есть 2 варианта:

1) Передать опции в вашу форму

Наиболее простой способ передать сервисы или конфигурацию в вашу форму - через опции форм. Представьте, что вам нужно получить доступ к менеджеру сущностей Doctrine, чтобы вы могли сделать запрос. Для начала, позвольте (на самом деле, потребуйте), чтобы новая опция entity_manager была передана в вашу форму:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Form/TaskType.php
// ...

class TaskType extends AbstractType
{
    // ...

    public function configureOptions(OptionsResolver $resolver)
    {
        // ...

        $resolver->setRequired('entity_manager');
    }
}

Теперь, когда вы сделала это, вы должны передать опцию entity_manager при создании вашей формы:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/Controller/DefaultController.php
use App\Form\TaskType;

// ...
public function new()
{
    $em = $this->getDoctrine()->getManager();

    $task = ...;
    $form = $this->createForm(TaskType::class, $task, array(
        'entity_manager' => $em,
    ));

    // ...
}

Наконец, опция entity_manager доступна в аргументе $options вашего метода buildForm():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Form/TaskType.php
// ...

class TaskType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        /** @var \Doctrine\ORM\EntityManager $em */
        $em = $options['entity_manager'];
        // ...
    }

    // ...
}

Используйте этот метод, чтобы передать что угодно в вашу форму.

2) Определить вашу форму, как сервис

В качестве альтернативы, вы можете определить ваш класс формы, как сервис. Это хорошая идея, если вы хотите использовать форму повторно в нескольких местах - регистрация формы в качестве сервиса облегчает это.

Представьте, что вам нужно получить доступ к объекту EntityManager, чтобы вы могли сделать запрос. Для начала, добавьте это в качестве аргумента к вашему классу формы:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/Form/TaskType.php

use Doctrine\ORM\EntityManagerInterface;
// ...

class TaskType extends AbstractType
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    // ...
}

Если вы используете автомонтирование и автоконфигурацию, то вам больше ничего не нужно делать. Symfony автоматически передаст правильный объект EntityManager в ваш метод __construct().

Если вы не используете автомонтирование и автоконфигурацию, зарегистрируйте вашу форму, как сервис, вручную и тегируйте с помощью form.type:

  • YAML
  • XML
  • PHP
1
2
3
4
5
# config/services.yaml
services:
    App\Form\TaskType:
        arguments: ['@doctrine.orm.entity_manager']
        tags: [form.type]

Вот и всё! Ваш контроллер - где вы создали форму - не требует никаких изменений: Symfony достаточно умна, чтобы загружать TaskType из контейнера.

Смотрите Как создать пользовательский тип поля формы, чтобы получить больше информации.