“Sınıflarda Drupal çağrılarından kaçınılmalı, bunun yerine bağımlılık enjeksiyonu kullanılmalı”


16

Verilen URL'nin URL takma adını almak için aşağıdaki kodu kullanarak modülümde:

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

Ama modülümde Otomatik İnceleme ( http://pareview.sh/ ) çalıştırdığım bir uyarının altına alıyorum:

16 | UYARI | \ Sınıflarda Drupal çağrılarından kaçınılmalı, bunun yerine bağımlılık enjeksiyonu kullanılmalıdır.

Bağımlılık enjeksiyonu kullanarak yukarıdaki kodu nasıl güncelleyebilirim? Sınıf kodumun tamamı aşağıda verilmiştir.

<?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
Diğer soru, OP'nin burada gösterdiği hatayı nasıl önleyeceğini açıkça söylemiyor. Bu daha ziyade planı hakkında bir onay almak isteyen bir kullanıcı tarafından yapılan bir soru.
kiamlaluno

Yanıtlar:


16

Al BlockLibraryControllerörnek olarak sınıf; denetleyicinizle aynı sınıfı genişletir.

Siz tanımlayın:

  • create()Değerleri bağımlılık kapsayıcısından alan ve sınıfınızın yeni bir nesnesini oluşturan statik ve genel bir yöntem
  • Nesne özelliklerinde önceki yöntemden geçirilen değerleri kaydeden bir sınıf yapıcısı
  • Sınıf yapıcısında iletilen değerleri kaydetmek için bir nesne özellikleri kümesi

Sizin durumunuzda, kod aşağıdakine benzer olacaktır.

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.
  }

}

Gösterdiğiniz use \Drupal\Core\Path\AliasManagerInterface;kodu içeren dosyanın üzerine koymayı unutmayın .

Yan not olarak, görünümü oluşturmak için kullanılacak kod yanlıştır: Sen kullanımına gerek yoktur drupal_render(), çünkü views_embed_view()zaten bir renderable dizisi döndürür.
Ardından, döndürdüğünüz oluşturma dizisi muhtemelen beklediğiniz çıktıyı vermiyordur. #name muhtemelen Drupal'dan kullanılmayacak ve # işaretleme, Render API'sına genel bakış bölümünde açıklandığı gibi, kendisine aktardığınız işaretlemeyi filtreliyor .

  • #markup : Dizinin doğrudan HTML işaretlemesi sağladığını belirtir. İşaretleme, paragraf etiketindeki bir açıklama gibi çok basit olmadığı sürece, normalde # temayı veya # türü kullanmak tercih edilir, böylece tema işaretlemeyi özelleştirebilir. \Drupal\Component\Utility\Xss::filterAdmin()XSS vektörleri olmayan HTML etiketlerinin izin verilen bir listesine izin verirken, bilinen XSS vektörlerini ayıran değerin iletildiğini unutmayın . (Yani <script>ve <style>izin verilmiyor.) \Drupal\Component\Utility\Xss::$adminTagsİzin verilecek etiketlerin listesi için bakın . İşaretlemenizin bu beyaz listede olmayan etiketlerden herhangi birine ihtiyacı varsa, bir tema kancası ve şablon dosyası ve / veya bir varlık kitaplığı uygulayabilirsiniz. Alternatif olarak, hangi etiketlerin filtrelendiğini değiştirmek için #allowed_tags oluşturma dizisi anahtarını kullanabilirsiniz.

  • #allowed_tags : #markup sağlanırsa, işaretlemeyi filtrelemek için hangi etiketlerin kullanılacağını değiştirmek için bu kullanılabilir. Değer Xss::filter(), kabul edecek bir etiket dizisi olmalıdır . #Plain_text ayarlanırsa bu değer yoksayılır.


1
Bu bana çok yardımcı oluyor. Bağımlılık enjeksiyonu iyi çalışıyor. :) Teşekkür ederim.
ARUN

views_embed_view () yalnızca bir dizi sağlar. Kullanmadan drupal_render () nasıl html içerik olarak görüntüleyebilir?
ARUN

Bir sayfayı işleyen denetleyici yönteminden döndürülebilen, okunabilir bir dizi döndürür.
kiamlaluno

Sadece geri gelenleri views_embed_view()geri ver.
kiamlaluno

denetleyicim ajax çağrısı için kullanıyor. döndürülen içerik sayfada dinamik olarak güncellenir. Sonucunu döndürmek ederken views_embed_view()gösteren oArray
ARUN

1

Bağımlılık enjeksiyonunu kullanmak için sınıfınızın ContainerInjectionInterfacearayüzü uygulaması gerekir . ContainerInjectionInterfaceuygulayan sınıfın create()metoda sahip olması zorunludur. Enjekte edilen bağımlılıkları kabul eden ek sınıf yapıcısı ile create()yöntem, tanımlanan bağımlılık örneklerini sınıfınıza ileterek sınıfınızın bir örneğini döndürür.

Güncelleme: Bu haklı @kiamlaluno tarafından işaret edilmiştir ContainerInjectionInterfaceberi bu durumda gerekli değildirControllerBase zaten uygulandığı için değil.

<?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.
  }

}

Uzatmanız yeterlidir ControllerBase; ContainerInjectionInterfacezaten yapıldığı için uygulamaya gerek yoktur ControllerBase.
kiamlaluno

@kiamlaluno, bu doğru. kodunuz mükemmel çalışıyor.
ARUN

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.