Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll
10/03/2021, by Ivan

В прошлой статье мы рассмотрели что такое Dependencies Injection:

12.15. Services и Dependency Injection.

В этой статье приведен пример кода с Dependency Injection в контроллере.

/modules/custom/drupalbook/src/Controller/ModalFormContactController.php:

<?php

namespace Drupal\drupalbook\Controller;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormBuilder;

/**
 * ModalFormContactController class.
 */
class ModalFormContactController extends ControllerBase {

  /**
   * The form builder.
   *
   * @var \Drupal\Core\Form\FormBuilder
   */
  protected $formBuilder;

  /**
   * ModalFormContactController constructor.
   *
   * @param \Drupal\Core\Form\FormBuilder $form_builder
   *   The form builder.
   */
  public function __construct(FormBuilder $form_builder) {
    $this->formBuilder = $form_builder;
  }

  /**
   * {@inheritdoc}
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The Drupal service container.
   *
   * @return static
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('form_builder')
    );
  }

  /**
   * Callback for modal form.
   */
  public function openModalForm() {
    $response = new AjaxResponse();
    $modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
    $enquiry_title = $this->t("Send an enquiry to @business_name", ['@business_name' => $modal_form['business_name']['#value']]);
    $response->addCommand(new OpenModalDialogCommand($enquiry_title, $modal_form));

    return $response;
  }

}

Давайте разберем части кода для DI (Dependency Injection). 

namespace Drupal\drupalbook\Controller;

Сначала мы указываем namespace (пространство имен), место в котором этот файл лежит, где drupalbook это машинное имя вашего модуля.

use Symfony\Component\DependencyInjection\ContainerInterface;

Подключаем класс ContainerInterface, позже мы будем использовать для получения объектов из Service Container.

  /**
   * The form builder.
   *
   * @var \Drupal\Core\Form\FormBuilder
   */
  protected $formBuilder;

Объявляем свойство в котором мы будем хранить объект из Service Container. Комментарий @var \Namespace помогает вашей IDE понять какие методы объекта показывать в автокомплите.

  /**
   * ModalFormContactController constructor.
   *
   * @param \Drupal\Core\Form\FormBuilder $form_builder
   *   The form builder.
   */
  public function __construct(FormBuilder $form_builder) {
    $this->formBuilder = $form_builder;
  }

Дальше в конструкторе нужно получить в параметре объект из Service container, этот объект мы будем создавать в следующем методе create(), а здесь мы получаем объект и сохраняем в свойство, объявленное выше $formBuilder. Если вы подключаете новый сервис, то его нужно добавлять параметр за параметром в __construct(). Так что если вы собрались подключить 10 сервисов, то у вас будет 10 параметров.

  /**
   * {@inheritdoc}
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The Drupal service container.
   *
   * @return static
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('form_builder')
    );
  }

В методе create мы получаем объект Service container и возвращаем объект $form_builder, которые в коде выше в конструкторе мы сохраняем в свойства для объектов (formBuilder). Обратите внимание на регистр переменных для объектов из Service container мы используем lowercase ($form_builder), а для свойств в классе, куда мы эти объекты сохраняем, мы используем camelCase с маленькой буквы (formBuilder).

И теперь мы можем использовать объект из Service Container в методах нашего класса:

  /**
   * Callback for modal form.
   */
  public function openModalForm() {
    ...
    $modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
    ...
  }