「Drupal呼び出しはクラスでは避け、代わりに依存性注入を使用する必要があります」


17

私のモジュールでは、指定されたURLのURLエイリアスを取得するための以下のコードを使用しています:

$alias = \Drupal::service('path.alias_manager')->getPathByAlias($_POST['url']);

しかし、私のモジュールで自動レビュー(http://pareview.sh/)を実行すると、次の警告が表示されます。

16 | 警告| \ Drupal呼び出しはクラスでは避け、代わりに依存性注入を使用する必要があります

依存性注入を使用して上記のコードを更新するにはどうすればよいですか?クラスコード全体を以下に示します。

<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * MyModule Class defines ajax callback function.
 */
class MyModule extends ControllerBase {
/**
 * Callback function for ajax request.
 */

  public function getUserContent() {
    $alias = \Drupal::service('path.alias_manager')->getPathByAlias($_POST['url']);
    $alias = explode('/', $alias);
    $my_module_views = views_embed_view('my_module', 'default', $alias[2]);
    $my_module= drupal_render($my_module_views);
    return array(
      '#name' => 'my_module_content',
      '#markup' => '<div class="my_module_content">' . $my_module. '</div>',
    );
  }

}


1
もう1つの質問は、OPがここで示しているエラーを回避する方法を明示的に言っていません。それはむしろ、自分の計画について確認したいユーザーからの質問です。
キアムルノ

回答:


16

BlockLibraryController例としてクラスを取り上げます。コントローラーと同じクラスを拡張します。

以下を定義します。

  • create()依存関係コンテナから値を取得し、クラスの新しいオブジェクトを作成する静的およびパブリックメソッド
  • 前のメソッドから渡された値をオブジェクトプロパティに保存するクラスコンストラクター
  • クラスコンストラクターに渡された値を保存するオブジェクトプロパティのセット

あなたの場合、コードは次のようになります。

class MyModuleController extends ControllerBase {
  /**
   * The path alias manager.
   *
   * @var \Drupal\Core\Path\AliasManagerInterface
   */
  protected aliasManager;

  /**
   * Constructs a MyModuleController object.
   *
   * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
   *   The path alias manager.
   */
  public function __construct(AliasManagerInterface $alias_manager) {
    $this->aliasManager = $alias_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('path.alias_manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getUserContent() {
    $alias = $this->aliasManager->getPathByAlias($_POST['url']);
    // Omissis.
  }

}

表示してuse \Drupal\Core\Path\AliasManagerInterface;いるコードを含むファイルの先頭に置くことを忘れないでください。

サイドノートとして、ビューをレンダリングするために使用するコードは間違っています。すでにレンダリング可能な配列を返しているdrupal_render()ため、使用する必要はありませんviews_embed_view()
返されるレンダー配列は、おそらく期待した出力を提供していません。#nameはおそらくDrupalからは使用されません。#markupは、Render APIの概要で説明されているように、渡されるマークアップをフィルタリングします

  • #markup:配列がHTMLマークアップを直接提供することを指定します。段落タグでの説明など、マークアップが非常に単純でない限り、テーマでマークアップをカスタマイズできるように、通常は#themeまたは#typeを代わりに使用することをお勧めします。値はを介して渡されることに注意してください\Drupal\Component\Utility\Xss::filterAdmin()。XSSベクトルではないHTMLタグの許容リストを許可しながら、既知のXSSベクトルを除去します。(すなわち、<script>および<style>許可されていませんが。)を参照してください\Drupal\Component\Utility\Xss::$adminTags許可されるタグのリストについて。このホワイトリストにないタグのいずれかがマークアップに必要な場合は、テーマフックとテンプレートファイルまたはアセットライブラリを実装できます。または、レンダー配列キー#allowed_tagsを使用して、フィルタリングするタグを変更できます。

  • #allowed_tags:#markupが指定されている場合、これを使用して、マークアップのフィルタリングに使用するタグを変更できます。値は、Xss::filter()受け入れるタグの配列である必要があります。#plain_textが設定されている場合、この値は無視されます。


1
これは非常に役立ちます。依存性注入は正常に機能しています。:) ありがとうございました。
-ARUN

views_embed_view()は配列のみを提供します。drupal_render()を使用せずに、htmlコンテンツとして表示するにはどうすればよいですか?
ARUN

レンダリング可能な配列を返します。これは、ページをレンダリングするコントローラーメソッドから返すことができます。
kiamlaluno

返すものをviews_embed_view()返すだけです。
キアムルノ

私のコントローラーはajax呼び出しに使用しています。返されたコンテンツはページ内で動的に更新されます。結果を返すもののviews_embed_view()、それが示すArray
ARUN

1

依存性注入を利用するには、クラスでContainerInjectionInterfaceインターフェイスを実装する必要があります。ContainerInjectionInterfaceクラスの実装にはcreate()メソッドが必要であることを義務付けています。挿入された依存関係を受け入れる追加のクラスコンストラクターで、create()methodは、定義された依存関係のインスタンスをクラスに渡すことにより、クラスのインスタンスを返します。

更新: @kiamlalunoによって正しく指摘されましたContainerInjectionInterfaceが、ControllerBaseすでに実装されているため、この場合は必要ありません。

<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Path\AliasManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * MyModule Class defines ajax callback function.
 */
class MyModule extends ControllerBase {

  /** @var \Drupal\Core\Path\AliasManagerInterface $aliasManager */
  protected $aliasManager;

  /**
   * MyModule constructor.
   *
   * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
   */
  public function __construct(AliasManagerInterface $alias_manager) {
    $this->aliasManager = $alias_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('path.alias_manager')
    );
  }

  /**
   * Callback function for ajax request.
   */
  public function getUserContent() {
    $alias = $this->aliasManager->getPathByAlias($_POST['url']);
    // Your code.
  }

}

拡張するだけで十分ですControllerBase。それはContainerInjectionInterfaceすでにから行われているため、実装する必要はありませんControllerBase
キアムルノ

@kiamlaluno、それは正しいです。コードは完璧に機能します。
ARUN

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.