“ ควรหลีกเลี่ยงการโทร Drupal ในชั้นเรียน, ใช้การฉีดพึ่งพา”


17

ในโมดูลของฉันใช้โค้ดด้านล่างเพื่อรับชื่อแทน 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>',
    );
  }

}

1
การทำซ้ำที่เป็น
อะไร

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 ภาพรวม

  • #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()กลับมา
kiamlaluno

คอนโทรลเลอร์ของฉันใช้สำหรับการโทร ajax เนื้อหาที่ส่งคืนจะอัปเดตในหน้าเว็บแบบไดนามิก ในขณะที่ส่งคืนผลลัพธ์ของ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.