web-dev-qa-db-fra.com

Comment utiliser l'injection de dépendances pour les plugins / blocs [\ Drupal :: formbuilder () et \ Drupal :: config ()]?

Je n'arrive pas à comprendre cette théorie de l'injection de dépendance. Comment sommes-nous censés aligner les méthodes ci-dessous avec l'injection de dépendance?

\Drupal::routeMatch()->getParameter('node');
\Drupal::request();
\Drupal::formBuilder()->getForm('Drupal\enquirycart\Form\EnquiryForm');
\Drupal::config()

Voici une classe dont j'ai besoin pour corriger ce message d'avertissement lorsqu'il est affiché dans https://pareview.sh/

"\ Les appels Drupal doivent être évités dans les classes, utilisez plutôt l'injection de dépendances"

    class EnquirycartBlock extends BlockBase implements BlockPluginInterface {

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    $default_config = \Drupal::config('enquirycart.settings');

    return [
      'label_display' => FALSE,
      'enquiry_email' => $default_config->get('enquirycart.email'),
    ];

  }

  /**
   * {@inheritdoc}
   */
  public function build() {

    $builtForm = \Drupal::formBuilder()->getForm('Drupal\enquirycart\Form\EnquirycartButtonForm');
    $renderArray['form'] = $builtForm;

    return $renderArray;

  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form_new = parent::blockForm($form, $form_state);

    return $form_new;

  }
5
danuddara

Pour référence future, à partir du lien de @Kevin:

La clé pour que les plugins utilisent l'injection de dépendance est d'implémenter ContainerFactoryPluginInterface . Lorsque des plugins sont créés, le code vérifie d'abord si le plugin implémente cette interface. Si c'est le cas, il utilise les modèles create () et __construct (), sinon, il utilise uniquement le modèle __construct (). - Extrait de la leçon 11.4 d'Acquia - Injection de dépendances et plugins

L'exemple de code ci-dessous est écrit par Mart Matsoo de Chromatic . Veuillez consulter l'article complet ici: https://chromatichq.com/blog/dependency-injection-drupal-8-plugins . Comme @Kevin l'a déjà mentionné dans les commentaires, c'est un excellent article sur l'injection de dépendance dans les plugins.

Exemple d'injection de dépendance dans un bloc

Notez l'injection du service 'current_user' via $container->get('current_user') dans la méthode create(). Vous pouvez y passer des services supplémentaires.

<?php

namespace Drupal\heytaco\Plugin\Block;

use Drupal\Core\Session\AccountProxy;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a Hey Taco Results Block
 *
 * @Block(
 *   id = "heytaco_block",
 *   admin_label = @Translation("HeyTaco! Leaderboard"),
 * )
 */
class HeyTacoBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * @var $account \Drupal\Core\Session\AccountProxyInterface
   */
  protected $account;

  /**
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   * @param array $configuration
   * @param string $plugin_id
   * @param mixed $plugin_definition
   *
   * @return static
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('current_user')
    );
  }

  /**
   * @param array $configuration
   * @param string $plugin_id
   * @param mixed $plugin_definition
   * @param \Drupal\Core\Session\AccountProxyInterface $account
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, AccountProxyInterface $account) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->account = $account;
  }

Exemple d'injection de dépendance dans un contrôleur

Le même concept s'applique ici, passez des services supplémentaires via $container->get() dans la méthode create().

<?php

namespace Drupal\heytaco\Controller;

use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Controller\ControllerBase;

/**
 * Controller routines for HeyTaco! block.
 */
class HeyTacoController extends ControllerBase {

  protected $account;

  public function __construct(AccountInterface $account) {
    $this->account = $account;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('current_user')
    );
  }
12
mvdgun

Grâce à @kevin, j'ai réussi à faire fonctionner cette DI comme je le voulais. Si quelqu'un veut vérifier les services de base, suivez le lien ci-dessous.

Tous les services sont répertoriés dans l'API de base https://api.drupal.org/api/drupal/core%21core.services.yml/8.3.x

Je viens de poster un exemple de classe où il a utilisé tous les services\Drupal que j'ai mentionnés dans la question. voici comment procéder.

namespace Drupal\enquirycart\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Routing\CurrentRouteMatch;

class EnquirycartBlock extends BlockBase implements BlockPluginInterface, ContainerFactoryPluginInterface {


    /**
     * @var  \Drupal\Core\Form\FormBuilderInterface $formbuilder
     */
    protected $formbuilder;

    protected $configfactory;

    protected $routematch;

    protected $requestmatch;

    /**
    * @param array $configuration
    * @param string $plugin_id
    * @param mixed $plugin_definition
    * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
    */
    public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $form_builder, ConfigFactoryInterface $config_factory, CurrentRouteMatch $route_match, RequestStack $requestdi) {
        parent::__construct($configuration, $plugin_id, $plugin_definition);

        $this->formbuilder = $form_builder;
        $this->configfactory = $config_factory;
        $this->routematch = $route_match;
        $this->requestmatch = $requestdi;
       /*  dpm($this->configfactory->get('enquirycart.settings'));     
         dpm($this->routematch->getParameter('node')->getTitle()); 
         dpm($this->requestmatch->getCurrentRequest()->getSession()->get('enquire'));*/
    }

   /**
   * {@inheritdoc}
   */
    public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
       return new static(
            $configuration,
            $plugin_id,
            $plugin_definition,
            $container->get('form_builder'),
            $container->get('config.factory'),
            $container->get('current_route_match'),
            $container->get('request_stack')   
          );
    }


}
1
danuddara