Intereting Posts
Каждый раз, когда моя почта переходит к спаму в phpmailer PHP: как отсортировать значения массива в алфавитном порядке? Устранение неполадок "preg_replace (): Неизвестный модификатор" представить успех, но не загружать в комбинированную форму Проверка того, содержит ли строка целое число Ввод SQL-запроса в функцию PHP приемлемо ли перерабатывать или повторно использовать переменные? Заменить контент для переменной PHP (сохранены теги HTML) Проверка почтового индекса Соединенного Королевства (GB) без регулярного выражения Magento Search возвращает все продукты как я могу установить данные из базы данных в поле с помощью формы в zend framework 1.11 Я хочу, чтобы поле ввода имело уникальное значение Могу ли я показать список контактов в категории, на странице «Список всех категорий контактов» в Joomla? Скрыть или зашифровать URL-файлы файлов? Как создать пользовательскую страницу администратора в opencart?

Получить услугу запроса из класса DataTransformer

Короткий рассказ:
Мне нужно получить сервис Request из класса, который не наследуется от класса Controller (это DataTransformer, который, как правило, реализует DataTransformerInterface).

Длинная история:
У меня встроенная форма с полем электронной почты. Если пользователь вводит электронное письмо, которое не существует в моей таблице базы данных пользователей, я хочу создать нового пользователя с этим электронным письмом.
Для этого мне нужно установить свой IP-адрес, поэтому я следил за учебником встроенных форм и рецептом трансформатора данных , но, наконец, я понятия не имею, где я могу вставить экземпляр запроса в свой конструктор DataTransformer или что-то еще.

Если бы я был в классе, расширяющем форму Контроллера, это было бы так же просто, как:
$this->container->get('request')->getClientIp()

Вы можете сделать это с помощью «Реферирование (инжекция)» . В вашем случае вы хотите ввести запрос, который является сервисом из более узкой области .

Если вы используете трансформаторы, вы, вероятно, уже используете пользовательский тип формы и создаете экземпляр Data Transformer в вашем методе формы формы FormForm , см. Здесь для получения дополнительной информации.

Вы хотите ввести объект Request в пользовательский тип формы, затем он может передаваться в Data Transformer в качестве параметра конструктора.

Для этого измените файл services.yml в своем пакете и добавьте конструктор к типу пользовательской формы и настраиваемому преобразователю данных следующим образом:

 // src/Acme/HelloBundle/Resources/config/services.yml parameters: // ... services: acme.type.custom_type: class: Acme\HelloBundle\Form\Type\CustomType scope: request arguments: ["@doctrine.odm.mongodb.document_manager", "@request"] tags: - { name: form.type, alias: custom_type } 

Обновите класс CustomType следующим образом:

 <?php // src/Acme/HelloBundle/Form/Type/CustomType.php namespace Acme\HelloBundle\Form\Type; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Doctrine\ODM\MongoDB\DocumentManager; use Acme\HelloBundle\Form\DataTransformer\CustomDataTransformer; class CustomType extends AbstractType { private $request; private $dm; public function __construct(DocumentManager $dm, Request $request) { $this->dm = $dm; $this->request = $request; } public function buildForm(FormBuilderInterface $builder, array $options) { // Create a new Data Transformer that will be able to use the Request Object! $transformer = new CustomDataTransformer($this->dm, $this->request); $builder->addModelTransformer($transformer); } // ... } 

и, наконец, добавить конструктор в трансформатор, аналогичный тому, который был добавлен в Тип формы:

 <?php // src/Acme/HelloBundle/Form/DataTransformer/CustomDataTransformer.php namespace Acme\HelloBundle\Form\DataTransformer; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Form\DataTransformerInterface; use Doctrine\ODM\MongoDB\DocumentManager; class CustomDataTransformer implements DataTransformerInterface { private $request; private $dm; public function __construct(DocumentManager $dm, Request $request) { $this->dm = $dm; $this->request = $request; } // ... } 

Обратите внимание, что вместе с запросом я ввел MongoDB DocumentManager, это означает, что можно вводить несколько объектов.

Хорошо, это просто: в моем вопросе я предполагал, что DataTransformer будет вызван «магически», но он создается при создании формы, поэтому, если это кому-то помогает, вот оно:

  1. В классе DataTransformer (реализация DataTransformerInterface):

    1. Определите новые атрибуты класса, чтобы удерживать инъекцию зависимостей:

       /** * @var EntityManager */ private $entityManager; /** * @var \Symfony\Component\DependencyInjection\Container */ private $container; 
    2. Определите конструктор как:

       public function __construct( EntityManager $entityManager, Container $container ) { $this->entityManager = $entityManager; $this->container = $container; } 
  2. В вашем классе формы (реализация AbstractType)

    1. Добавьте следующие методы метода setDefaultOptions :

       $resolver->setRequired( array( 'em', 'container' ) ); $resolver->setAllowedTypes( array( 'em' => 'Doctrine\Common\Persistence\ObjectManager', 'container' => 'appDevDebugProjectContainer', ) ); 
    2. В методе buildForm примените трансформатор, как определено в рецепте трансформатора, но введите его как:

       $entityManager = $options['em']; $container = $options['container']; $transformer = new FantasticTransformer( $entityManager, $container ); 
  3. В вашем контроллере, когда вы вызываете метод createForm , можно ли вводить экземпляры EntityManager и Container, просто добавляя их следующим образом:

      $form = $this->createForm( 'your_form', $lookup, array( 'action' => $this->generateUrl( 'your_action_url' ), 'em' => $this->getDoctrine()->getManager(), 'container' => $this->container ) ); 
  4. Теперь вы можете, наконец, получить IP-адрес клиента из службы запросов, вызывающего контейнер, определенный в конструкторе вашего класса DataTransformer:

     $ip = $this->container->get('request')->getClientIp(); 

Обратите внимание, что мы вводим контейнер вместо экземпляра запроса, это связано с областями Symfony .