【Drupal】DIを使用してサービスを呼び出す

こちらのサイトではDRUPAL10に関連する記事を掲載しています。

この記事はこちらのサイトを日本語訳しています。

Access to this page has been denied.

Drupal サービスまたはカスタム サービスを必要とするフォームは、依存性注入を使用してサービスにアクセスする必要があります。

current_userサービスを呼び出す

サンプル フォーム ( Drupal 8 のフォーム APIで使用されるフォームと同様) では、’current_user’ サービスを使用して現在のユーザーの uid を取得します。 のファイル内容 /modules/example/src/Form/ExampleForm.phpモジュールが入っている場合 /modules/example:

<?php

namespace Drupal\example\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Implements an example form.
 */
class ExampleForm extends FormBase {

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

  /**
   * @param \Drupal\Core\Session\AccountInterface $account
   */
  public function __construct(AccountInterface $account) {
    $this->account = $account;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    // Instantiates this form class.
    return new static(
      // Load the service required to construct this class.
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}.
   */
  public function getFormId() {
    return 'example_form';
  }

  /**
   * {@inheritdoc}.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    // Get current user data.
    $uid = $this->account->id();
    
    // ...
  }
  
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // ...
  }
}

createメソッドは、の新しいインスタンスを返すファクトリ メソッドです。 ExampleForm物体。 の ExampleForm::create1 つ以上のサービスをロードします。 これは、で定義されている任意のコア サービスにすることができます core.services.ymlまたは任意 *.services.ymlファイル。

ExampleForm::__constructによってロードされるサービスを使用します ExampleForm::createクラスのプロパティに保存します。 サービスが読み込まれる順序 ExampleForm::createのパラメータの順序と等しくなければなりません ExampleForm::__construct方法。

createメソッドは Drupal\Core\DependencyInjection\ContainerInjectionInterfaceこれにより、コントローラーをサービスでインスタンス化できます。 Drupal\Core\Form\FormBaseはすでにこのインターフェースを実装しています。 拡張する任意のフォーム Drupal\Core\Form\FormBaseConfigFormBase や ConfirmFormBase などは、この依存性注入の機能を備えています。

<?php

namespace Drupal\example\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Session\AccountProxyInterface;

/**
 * Implements an example configuration form.
 */
class ExampleConfigForm extends ConfigFormBase {

  /**
   * Drupal\Core\Session\AccountProxyInterface definition.
   *
   * @var AccountProxyInterface $currentUser
   */
  protected $currentUser;

  /**
   * Class constructor.
   */
  public function __construct(ConfigFactoryInterface $config_factory, AccountProxyInterface $current_user) {
    parent::__construct($config_factory);
    $this->currentUser = $current_user;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('config.factory'),
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'example.config_form',
    ];
  }

  /**
   * {@inheritdoc}.
   */
  public function getFormId() {
    return 'example_config_form';
  }

  /**
   * {@inheritdoc}.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    // Get current user data.
    $uid = $this->currentUser->id();
    drupal_set_message($uid);

    // ...

    $config = $this->config('example.config_form');
    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->config('example.config_form')->save();
    parent::submitForm($form, $form_state);
  }
}

上記のコンストラクタ プロパティ プロモーションを使用した例 (PHP 8.0):

…
class ExampleConfigForm extends ConfigFormBase {

  /**
   * Class constructor.
   */
  public function __construct(
    ConfigFactoryInterface $config_factory, 
    protected AccountProxyInterface $currentUser
  ) {
    parent::__construct($config_factory);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('config.factory'),
      $container->get('current_user')
    );
  }
…

@todo 同じクラス インターフェイスでパラメーターを定義するだけで、FormController が $route 情報を buildForm() メソッドに自動的に挿入する方法を示します。

buildForm(array $form, FormStateInterface $form_state, Request $request = NULL) 

ブロック内の依存性注入 (プラグイン)

カスタム ブロック プラグイン内にカスタム/コア サービスを挿入して、使用する必要があります。

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;

という名前のカスタム ブロックがあるとします 「drupalise」カスタム サービス 「drupalise」を挿入します。。次のように、カスタム ブロック コード内に

<?php

namespace Drupal\drupalise\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\drupalise\Services\DrupaliseMe;

/**
 * Provides a 'Drupalise' block.
 *
 * @Block(
 * id = "drupalise",
 * admin_label = @Translation("Drupalise"),
 * )
 */
class Drupalise extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * @var $drupalise \Drupal\drupalise\Services\DrupaliseMe
   */
  protected $drupalise;

  /**
   * @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('drupalise')
    );
  }

  /**
   * @param array $configuration
   * @param string $plugin_id
   * @param mixed $plugin_definition
   * @param \Drupal\drupalise\Services\DrupaliseMe $drupalise_me
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, DrupaliseMe $drupalise_me) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->drupalise = $drupalise_me;
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $slogan= $this->drupalise->Drupalise(); // Function from your service file will return 'Drop Drop Drupal !!!'
    $build = [];
    $build['drupalise']['#markup'] = 'Drupalise is best' . $slogan;
    return $build;
  }

}

シリアル化に関する考慮事項

サービス オブジェクトが drupal によってシリアル化されると、プライベート プロパティが失われます。

でください。 ないプライベートな可視性を持つようにフォーム クラスのサービス プロパティを設定し

たとえば、フォームが ajax を介して再構築された場合、 #ajaxフォーム要素への定義、フォーム クラスがシリアル化される
クラスのプライベート プロパティに割り当てられている ajax リクエストとサービスは失われます。 これにより、ajax が実行されて正常に処理され、後続の ajax リクエストで null プロパティ値が原因でエラーが生成されるフォームが生成されます。

定義済みの要素がある場合 #ajax以下のようなハンドラーでは、サービスがフォーム クラスに挿入されていることを確認する必要があります。
プライベートではありません。

      '#ajax' => [
        'callback' => '::myAjaxCallback', 'event' => 'change', 'wrapper' => 'my-ajax-wrapper', 'progress' => [
          'type' => 'throbber', 'message' => $this->t('Verifying entry...'),
        ],
      ]

例:

class MyEntityForm extends EntityForm 

  /**
   * Drupal routeBuilder object, for rebuilding routes on form save.
   *
   * This is an injected service and must not be declared private or
   * it will be lost on serialisation of this form object.
   *
   * @var \Drupal\Core\Routing\RouteBuilder
   */
  protected $routeBuilder

  /**
   * MyEntityForm constructor.
   *
   * The injected service properties, eg $this->routeBuilder must
   * be not be declared private as this form is reloaded with ajax and
   * cached, private properties aren't serialisable.
   *
   * @param \Drupal\Core\Routing\RouteBuilderInterface $routeBuilder
   */
  public function __construct(RouteBuilderInterface $routeBuilder) {
    $this->routeBuilder = $routeBuilder
  }

}

DRUPAL10のアカウントユーザ関連API

function Drupal::currentUser | Drupal API

アカウントユーザ関連API関数

class AccountProxy | Drupal API

NameModifiersTypeDescriptionOverrides
AccountProxy::$accountprotectedpropertyThe instantiated account.
AccountProxy::$eventDispatcherprotectedpropertyEvent dispatcher.
AccountProxy::$idprotectedpropertyAccount id.
AccountProxy::getAccountpublicfunction
AccountProxy::getAccountNamepublicfunction
AccountProxy::getDisplayNamepublicfunction
AccountProxy::getEmailpublicfunction
AccountProxy::getLastAccessedTimepublicfunction
AccountProxy::getPreferredAdminLangcodepublicfunction
AccountProxy::getPreferredLangcodepublicfunction
AccountProxy::getRolespublicfunction
AccountProxy::getTimeZonepublicfunction
AccountProxy::hasPermissionpublicfunction
AccountProxy::hasRolepublicfunctionWhether a user has a certain role.
AccountProxy::idpublicfunction
AccountProxy::isAnonymouspublicfunction
AccountProxy::isAuthenticatedpublicfunction
AccountProxy::loadUserEntityprotectedfunctionLoad a user entity.
AccountProxy::setAccountpublicfunction
AccountProxy::setInitialAccountIdpublicfunction
AccountProxy::__constructpublicfunctionAccountProxy constructor.
DependencySerializationTrait::$_entityStoragesprotectedproperty
DependencySerializationTrait::$_serviceIdsprotectedproperty
DependencySerializationTrait::__sleeppublicfunction2
DependencySerializationTrait::__wakeuppublicfunction2
このサイトに関するご意見・ご質問はこちらまで

この記事またはDrupalに関するご質問がございましたら、お気軽にお問い合わせください。

タイトルとURLをコピーしました