2012-08-10 93 views
2

這既是一個問題,一種答案的使用< args >。但我仍然希望找到一個更好的解決方案,並且您可能會對此有所瞭解。在Magento觀察員聲明

當在Magento中創建觀察者時,負責分派它並調用在模塊的config.xml文件中的觀察者聲明中配置的函數的方法是Mage_Core_Model_App::dispatchEvent

在該方法中,有這種碼位所採集觀察者信息:

foreach ($eventConfig->observers->children() as $obsName=>$obsConfig) { 
    $observers[$obsName] = array(
     'type' => (string)$obsConfig->type, 
     'model' => $obsConfig->class ? (string)$obsConfig->class : $obsConfig->getClassName(), 
     'method'=> (string)$obsConfig->method, 
     'args' => (array)$obsConfig->args, 
    ); 
} 

這碼位表示一個可以在這樣的一個觀察者聲明一個< ARGS>節點:

<events> 
    <event_to_observe> 
     <observers> 
      <observer_name> 
       <type>singleton</type> 
       <class>Namespace_Module_Model_ObserverClass</class> 
       <method>observerMethod</method> 

       <args> 
        <arg_name>arg_value</arg_name> 
       </args> 

      </observer_name> 
     </observers> 
    </event_to_observe> 
</events> 

後來在Mage_Core_Model_App::dispatchEvent,我們可以發現一些代碼,負責調用觀察員的方法和傳遞$observer對象作爲參數。

但是,如果我是正確的,則沒有代碼設置$observers[$obsName]['args']值,也不會設置爲$event對象,也不會設置爲$observer對象。結果是:從觀察者聲明< ARGS>節點不是在觀察者的調用方法(在我前面的例子Namespace_Module_Model_ObserverClass::observerMethod)訪問。

我的第一個賭注是,試圖得到< ARGS>使用這樣的節點:

$args = (array) Mage::getConfig()->getXpath('//events/' . $observer->getEvent()->getName() . '/observers/' . $observer->getName() . '/args'); 

但是,如何讓人失望,在$name變量(這也是在Mage_Core_Model_App::dispatchEvent用於探查)也不會傳遞到$observer對象......所以$observer->getName()沒有返回任何數據。

所以我結束了創建任何oberver方法,以獲取其< ARGS>節點調用一個輔助方法。 你可以找到這個幫手的要點以及如何在這裏使用它:

https://gist.github.com/3312869

這將是如此容易在Mage_Core_Model_App::dispatchEvent是這樣的: $observer->setMethodArgs($obs['args'])允許觀察者方法使用$observer->getMethodArgs() ..

或者我錯過了一些可以讓我們檢索< args> node的東西,但是我不確定,通過核心代碼搜索,我沒有發現任何< args>節點,這意味着Magento不會在其Core中使用此功能。

所以,現在的問題是...... 你有一個簡單而Magento的核心方法,從一個觀察者的聲明檢索< ARGS>?

+0

我很想知道你爲什麼要將參數傳遞給一個事件構造函數 - 這是什麼用例? – benmarks 2012-08-10 10:19:19

+1

用例是我想爲幾個事件使用相同的觀察者方法,因此代碼更輕。我沒有調用methodForEvent1,methodforEvent2,而是想調用methodForEvent($ args) – 2012-08-10 11:23:54

回答

1

不幸斷開與args是......不幸的。 <args>節點似乎退化。但是,如果您有一個方法根據param執行多個行爲中的一個,則可能需要將這些不同的活動置於不同的方法中。也就是說,您需要爲每個要用同一方法觀察/消耗的事件分別進行單獨配置和總體配置,但您有三種選擇:

爲每個事件調用相同的方法並控制觀察者內部的行爲方法是使用$observer->getEvent()->getName()測試事件名稱。

在每個事件觀察器配置中調用一個不同的方法,並讓這些方法在內部調用包含該行爲的方法,並傳入一個參數以指示哪個行爲。

修復您的XPath參考檢索ARGS:

Mage::getConfig()->getNode('global/events/'.$observer->getEvent()->getName().'/observers/your_config/args'); 

Mage::getConfig()->getXpath('global/events/'.$observer->getEvent()->getName().'//args'); 
$args = $cfg[0]; 

注意,後者將從拿起args爲包含args給定事件的任何全球觀察者配置。您可能要添加一個節點包含您ARGS args節點,然後使用該作爲的XPath的一部分 - 儘管這是不可能的,任何其他模塊將使用args,讓params中獨自通這會影響你的模塊的處理。

+0

我也注意到了這一點,並且始終無法找出核心如何使用它(也在所有先前版本中檢查過)。 Hervé希望能夠使用它似乎是合乎邏輯的。我已經提交了一個拉請求,以找出 - https://github.com/magento/magento2/pull/63 – 2012-08-11 19:35:51

+0

@benmarks - 謝謝你的答案,我相信如果我不能認爲你不會不高興作爲「tickerable」:)事實上,它並沒有給出一個明確的Magento Core方法來從觀察者中檢索< args >,不幸的是,你的兩個技巧都需要有一些已知的關於當前觀察者的固定數據(「your_config」第一個技巧,以及第二個中的一些固定子節點),因此不允許完全動態和因式分解的方式來檢索參數。所以,我會堅持我在https://gist.github.com/3312869提供的Gist。無論如何,再次感謝! – 2012-08-13 06:57:15

+0

@Drew Hunter - 發出拉請求是個好主意!我希望核心團隊會考慮它,或者如果不這樣做,請給出一些解釋。 – 2012-08-13 06:58:10