"강의에서는 불필요한 호출을 피해야합니다. 대신 종속성 삽입을 사용하십시오."


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
다른 질문은 OP가 여기에 표시되는 오류를 피하는 방법을 명시 적으로 말하지 않습니다. 오히려 자신의 계획에 대한 확인을 원하는 사용자의 질문입니다.
kiamlaluno

답변:


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 overview 에 설명 된대로 전달할 마크 업을 필터링합니다 .

  • #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를 설정하면이 값이 무시됩니다.


1
이것은 나를 많이 도와줍니다. 의존성 주입이 잘 작동합니다. :) 감사합니다.
ARUN

views_embed_view () 는 배열 만 제공합니다. drupal_render ()를 사용하지 않고 어떻게 html 컨텐츠로 표시 할 수 있습니까?
ARUN

페이지를 렌더링하는 컨트롤러 메서드에서 반환 할 수있는 렌더링 가능한 배열을 반환합니다.
kiamlaluno

반환되는 것을 views_embed_view()반환하십시오.
kiamlaluno

내 컨트롤러가 아약스 호출에 사용하고 있습니다. 반환 된 컨텐츠는 페이지에서 동적으로 업데이트됩니다. views_embed_view()표시 결과를 반환하는 동안Array
ARUN

1

의존성 주입을 활용하려면 클래스가 ContainerInjectionInterface인터페이스 를 구현해야합니다 . ContainerInjectionInterface클래스를 구현하려면 create()메소드 가 있어야 합니다. 주입 된 종속성을 허용하는 추가 클래스 생성자를 사용하면 create()메소드는 정의 된 종속성 인스턴스를 클래스에 전달하여 클래스의 인스턴스를 리턴합니다.

업데이트 : @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

@kiamlaluno, 맞습니다. 코드가 완벽하게 작동합니다.
ARUN

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.