"ड्रुपल कॉल को कक्षाओं में टाला जाना चाहिए, इसके बजाय निर्भरता इंजेक्शन का उपयोग करें"


16

दिए गए 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
अन्य प्रश्न स्पष्ट रूप से यह नहीं कहते हैं कि ओपी यहाँ दिखाई जा रही त्रुटि से कैसे बचें। यह बल्कि एक उपयोगकर्ता से किया गया सवाल है जो अपनी योजना के बारे में पुष्टि करना चाहता है।
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 : निर्दिष्ट करता है कि ऐरे सीधे HTML मार्कअप प्रदान करता है। जब तक मार्कअप बहुत सरल नहीं होता है, जैसे कि एक पैराग्राफ टैग में स्पष्टीकरण, सामान्य रूप से इसके बजाय #theme या # टाइप का उपयोग करना बेहतर होता है, ताकि थीम मार्कअप को अनुकूलित कर सके। ध्यान दें कि मान के माध्यम से पारित किया जाता है \Drupal\Component\Utility\Xss::filterAdmin(), जो एक्सएसएस वैक्टर नहीं हैं जो HTML टैग की अनुमति सूची की अनुमति देता है, जो एक्सएसएस वैक्टर नहीं हैं। (Ie, <script>और <style>अनुमति नहीं है।) देखें \Drupal\Component\Utility\Xss::$adminTagsटैग की सूची है कि अनुमति दी जाएगी के लिए। यदि आपके मार्कअप को ऐसे किसी भी टैग की आवश्यकता है जो इस श्वेतसूची में नहीं हैं, तो आप थीम हुक और टेम्पलेट फ़ाइल और / या एक परिसंपत्ति पुस्तकालय को लागू कर सकते हैं। वैकल्पिक रूप से, आप रेंडर सरणी कुंजी #allowed_tags का उपयोग करके बदल सकते हैं कि कौन से टैग फ़िल्टर किए गए हैं।

  • #allowed_tags : यदि #markup की आपूर्ति की जाती है, तो इसका उपयोग यह बदलने के लिए किया जा सकता है कि कौन से टैग मार्कअप को फ़िल्टर करने के लिए उपयोग कर रहे हैं। मान टैग का एक सरणी होना चाहिए जो Xss::filter()स्वीकार करेगा। यदि #plain_text सेट है तो इस मान को अनदेखा कर दिया जाता है।


1
इससे मुझे बहुत मदद मिलती है। निर्भरता इंजेक्शन ठीक काम कर रहा है। :) धन्यवाद।
ARUN

केवल एक सरणी प्रदान करने के लिए view_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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.