यदि दो मॉड्यूल दोनों 'हुक_मेनू' में एक ही मेनू पथ को परिभाषित करते हैं, तो कौन सा Drupal चुनेगा?


14

उदाहरण के लिए, "मॉड्यूलोन" पथ को परिभाषित करता है 'व्यवस्थापक / हैलो', जो आउटपुट print_moduleone_stuff()

/**
 * Implements hook_menu()
 */
function moduleone_menu() {
  $items['admin/hello'] = array(
    'title' => 'Module One Hello World',
    'page callback' => print_moduleone_stuff,
  );
  return $items;
}

"moduletwo" पथ 'व्यवस्थापक / हैलो' को परिभाषित करता है, जो आउटपुट print_moduletwo_stuff()

/**
 * Implements hook_menu()
 */
function moduletwo_menu() {
  $items['admin/hello'] = array(
    'title' => 'Module Two Hello World',
    'page callback' => print_moduletwo_stuff,
  );
  return $items;
}

दोनों मॉड्यूल ने अलग-अलग परिणाम के लिए 'व्यवस्थापक / हैलो' मार्ग को परिभाषित किया। इन दो मॉड्यूल को सक्षम करने के साथ, Drupal दूसरे की तुलना में एक का चयन कैसे करता है? द्रुपाल संघर्ष को कैसे हल करता है?

जवाबों:


16

समारोह प्रेरक hook_menu()है () menu_router_build , से बुलाया menu_rebuild () । इसमें निम्न कोड है।

  foreach (module_implements('menu') as $module) {
    $router_items = call_user_func($module . '_menu');
    if (isset($router_items) && is_array($router_items)) {
      foreach (array_keys($router_items) as $path) {
        $router_items[$path]['module'] = $module;
      }
      $callbacks = array_merge($callbacks, $router_items);
    }
  }
  // Alter the menu as defined in modules, keys are like user/%user.
  drupal_alter('menu', $callbacks);

यदि एक ही मार्ग को परिभाषित करने वाले दो मॉड्यूल हैं, तो दिए गए सरणी में अंतिम मॉड्यूल module_implements()अन्य मॉड्यूल से परिभाषित मूल्य को ओवरराइड करेगा।

द्वारा आवश्यक दूसरा पैरामीटर निम्नानुसार module_implements()परिभाषित किया गया है:

$sortडिफ़ॉल्ट रूप से, मॉड्यूल वजन और फ़ाइल नाम द्वारा आदेशित किए जाते हैं, इस विकल्प को सेटिंग्स TRUE, मॉड्यूल सूची को मॉड्यूल नाम द्वारा आदेश दिया जाएगा।

चूंकि menu_router_build()दूसरा पैरामीटर पास नहीं करता है menu_implements(), इसलिए फ़ंक्शन उस पैरामीटर के लिए डिफ़ॉल्ट मान का उपयोग कर रहा है। इसका मतलब है कि मॉड्यूल की सूची उनके वजन और फ़ाइल नाम द्वारा आदेशित है; जब दो मॉड्यूल का वजन समान होता है, तो सूची में दिखाई देने वाला पहला मॉड्यूल वह होता है जो वर्णानुक्रम में पहले आता है।

इसके अलावा, किसी भी मॉड्यूल को लागू hook_module_implements_alter()करने वाले हुक को रद्द करने के आदेश को बदल सकते हैं।

इस कारण से, आपको यह पता नहीं लगाना चाहिए कि हुक किस क्रम में लगाए गए हैं।
यदि कोड का उद्देश्य किसी अन्य मॉड्यूल द्वारा कार्यान्वित मार्ग को बदल रहा है, उदाहरण के लिए क्योंकि एक मार्ग को हटा दिया जाना चाहिए जब एक दूसरा मॉड्यूल स्थापित और सक्षम हो, तो कोड का उपयोग करना चाहिए hook_menu_alter()। यदि आप यह समझने की कोशिश कर रहे हैं कि मार्ग संघर्ष के मामले में कौन सा मॉड्यूल "जीत" होगा, मैं इस तरह के मार्ग संघर्ष से बचूंगा, और एक ऐसे मार्ग को परिभाषित करूंगा जो पहले से ही किसी अन्य मॉड्यूल से परिभाषित नहीं है।

यदि तब आप कार्यान्वित कर रहे हैं hook_menu_alter(), और आप सुनिश्चित करना चाहते हैं कि आपका मॉड्यूल अंतिम रूप से निष्पादित हो, तो ऐसा मॉड्यूल हो जो प्रभावी रूप से एक मार्ग को ओवरराइड करता हो, आपको hook_module_implements_alter()भी लागू करना चाहिए ।

function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'menu_alter') {
    // Move mymodule_menu_alter() to the end of the list. module_implements()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['mymodule'];
    unset($implementations['mymodule']);
    $implementations['mymodule'] = $group;
  }
}

इतना स्पष्ट और उपयोगी, धन्यवाद। इस मामले में उपयोग hook_menu_alter () का उल्लेख करने के लिए भी धन्यवाद।
जिल्जरियो

क्या होगा अगर दो मॉड्यूल एक ही मार्ग को हुक_मेनू_लेटर () में परिभाषित करते हैं? एक ही नियम लागू?
गिल्जरियो

hook_menu_alter()का उपयोग नए मेनू को परिभाषित करने के लिए नहीं किया जाता है, बल्कि मौजूदा वाले को बदलने के लिए किया जाता है। यदि दो मॉड्यूल एक ही मेनू को बदलते हैं, तो जो परिवर्तन बचता है वह पिछले मॉड्यूल के लिए निष्पादित मॉड्यूल से होता है।
kiamlaluno

4

जिस भी मॉड्यूल में तालिका weightमें कम मान है, systemउसे पहले कहा जाएगा, इसलिए उच्च weightमान वाला मॉड्यूल इस मामले में 'जीत' जाएगा।

यदि वेट दो (या अधिक) मॉड्यूल के लिए समान हैं, तो मेरा मानना ​​है कि सीधे MySQL टेबल से आने वाले ऑर्डर के अलावा कोई विशिष्ट ऑर्डर नहीं किया गया है (मैं उस बारे में गलत हो सकता है)।

जैसा कि इनवोक से वापसी के परिणाम hook_menuसिर्फ मेनू आइटम के एक ही सरणी में डाल दिए जाते हैं, कभी भी एक 'संघर्ष' नहीं होगा, जैसे कि बाद में कॉल के परिणाम hook_menuबस पहले की कॉल से उन लोगों को ओवरराइड करेंगे।


4
प्रो ड्रुपल डेवलपमेंट के अनुसार , समान वजन वाले मॉड्यूल को उनके सिस्टम नाम से वर्णानुक्रम में कहा जाता है।
mpdonadio

2
उस पुस्तक द्वारा बताई गई रिपोर्ट सही है: हुक को लागू करने वाले मॉड्यूल की सूची को आमतौर पर वजन और वर्णानुक्रम द्वारा क्रमबद्ध किया जाता है; यदि इसे दूसरे पैरामीटर के रूप में module_implements()प्राप्त FALSEकिया जाता है, तो इसे सॉर्ट नहीं किया जाएगा , लेकिन फ़ंक्शंस module_invoke_all()इसे केवल एक पैरामीटर के साथ कॉल करता है।
kiamlaluno

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