web-dev-qa-db-ja.com

「Drupal呼び出しはクラスでは避けてください。代わりに依存性注入を使用してください」

指定されたURLのURLエイリアスを取得するために以下のコードを使用する私のモジュール:

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

しかし、私のモジュールでAutomated Review( 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>',
    );
  }

}
16
ARUN

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ベクトルが取り除かれ、XSSベクトルではないHTMLタグの許容リストが許可されます。 (つまり、_<script>_および_<style>_は許可されていません。)許可されるタグのリストについては、_\Drupal\Component\Utility\Xss::$adminTags_を参照してください。マークアップでこのホワイトリストにないタグが必要な場合は、テーマフックとテンプレートファイル、および/またはアセットライブラリを実装できます。または、レンダーアレイキー#allowed_tagsを使用して、フィルタリングするタグを変更することもできます。

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

16
kiamlaluno

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

pdate: @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.
  }

}
1
maijs