Magento 1: ¿por qué algunos métodos de observación llaman a getEvent () y otros no?

8

Algo que noté recientemente y tengo curiosidad al respecto.

Ejemplo 1: el uso de getEvent()

En Mage_Core_Model_Localeel setLocale()método, se distribuye un evento:

Mage::dispatchEvent('core_locale_set_locale', array('locale'=>$this));

Un observador para este evento es bindLocale()deMage_Adminhtml_Model_Observer

public function bindLocale($observer)
{
    if ($locale=$observer->getEvent()->getLocale()) {
        if ($choosedLocale = Mage::getSingleton('adminhtml/session')->getLocale()) {
            $locale->setLocaleCode($choosedLocale);
        }
    }
    return $this;
}

Entonces, como puede ver, para recuperar la configuración regional, primero llamamos getEvent()al observador.

Ejemplo 2: sin getEvent()

En Mage_Wishlist_Block_Customer_Wishlist_Item_Optionsel __construct()método, se distribuye un evento:

Mage::dispatchEvent('product_option_renderer_init', array('block' => $this));

Por lo tanto, estamos de acuerdo en que se usa la misma sintaxis para los ejemplos 1 y 2.

Sin embargo, un observador para este segundo ejemplo es initOptionRenderer()deMage_Bundle_Model_Observer

public function initOptionRenderer(Varien_Event_Observer $observer)
{
    $block = $observer->getBlock();
    $block->addOptionsRenderCfg('bundle', 'bundle/catalog_product_configuration');
    return $this;
}

Y como puede ver, para recuperar el bloque, no llamamos getEvent()al observador

Pregunta

  • ¿Por qué se getEvent()llama al método en el ejemplo 1? ¿O por qué getEvent()no se llama en el ejemplo # 2?
  • ¿Cuál es el propósito del getEvent()método?
  • ¿Dónde se debe usar getEvent()y dónde no se debe usar?
Raphael en Digital Pianism
fuente

Respuestas:

7

Probablemente tiene razones históricas, que van más allá de la versión 1.0.

El Varien_Eventobjeto es el lugar lógico para contener parámetros para un evento concreto, pero dado que Magento pasa un Varien_Observerobjeto a todos los métodos de observación, el acceso directo a los parámetros tiene sentido (y ha estado allí al menos desde 1.1).

En realidad, no veo ningún valor en dos objetos diferentes, ya que se usan hoy .

Pero obviamente no fue planeado así desde el principio. En el método Mage::addObserver(), no solo se establecen los nombres de eventos y observadores y los argumentos estáticos del <args>nodo XML, sino también una devolución de llamada:

$observer->setName($observerName)->addData($data)->setEventName($eventName)->setCallback($callback);

De esta manera, los observadores pueden despacharse, con $observer->dispatch($event). En ese caso, los observadores no tendrían los datos del evento en sí mismos y necesitaría que los utilizara getEvent()para acceder a ellos. Pero el método no se usa en ningún lado, por lo que en la práctica no importa.

Si desea practicar algo de arqueología de software y excavar más, encontrará más código muerto que sugiere ideas originales que nunca llegaron al producto final, como el Varien_Event_Observer_Collection.

Fabian Schmengler
fuente
Gracias. Iba a mencionar aspectos "históricos". Parece que hiciste eso por nosotros :)
Rajeev K Tomy
8

Una cosa está clara.

Llamar $observer->getEvent()->getSomething()y $observer->getSomething()devolver lo mismo.

Echa un vistazo al Mage_Core_Model_App::dispatchEventmétodo.

En un momento tienes $event = new Varien_Event($args);dónde $argsestán los argumentos pasados ​​al dispatchEventmétodo.
Y se Varien_Eventextiende Varien_Objectpara que pueda acceder mágicamente a los elementos $argsdesde la Varien_Eventinstancia.

pero también existe esta línea $observer->addData($args);donde $argsestán las mismas cosas que arriba.

Varien_Event_Observertambién se extiende Varien_Objectpara que esto le permita acceder mágicamente a los elementos a $argstravés del objeto Observador.

Conclusión:

El $_datamiembro en la clase Observador y en la clase Evento contiene el mismo tipo de cosas. El observador tiene además algunos otros campos. como event, event_name.

Digamos que se $argsve así:

array(
   'some_arg' => 'someArg',
   'other_arg' => 'otherArg',
)

Al despachar el evento, el $_dataobjeto en el evento se vería así:

array(
   'some_arg' => 'someArg',
   'other_arg' => 'otherArg',
   'name' => 'event name here'
)

y en la clase Observador se vería así:

array(
   'some_arg' => 'someArg',
   'other_arg' => 'otherArg',
   'event_name' => 'event name here',
   'event' => instance of Varien_event,
   'callback' => ..., 
   'name' => 'observer name here'
)

Pero no puedo responder por qué existe esta falta de coherencia.
Solo puedo especular que el código fue escrito por 2 desarrolladores diferentes.
Si vale algo, siempre lo uso $observer->getEvent()->getSomething().

[EDITAR]

¿Por qué se llama al método getEvent () en el ejemplo # 1? ¿O por qué no se llama a getEvent () en el ejemplo # 2?

Falta de coherencia

¿Cuál es el propósito del método getEvent ()?

El Varien_Eventobjeto debe ser un objeto envoltorio sobre los argumentos pasados ​​al observador

¿Dónde se debe usar getEvent () y dónde no se debe usar? Úsalos como quieras. Obtendrá el mismo resultado todo el tiempo.

Marius
fuente
Obtuve la explicación sobre la falta de coherencia, mira mi respuesta
Raphael en Digital Pianism
Siempre prefiero $observer->getEvent()tomar cualquier dato en observador. Sé que podemos obtener datos $observerdirectamente. Pero no hago eso porque siempre siento que la inyección de objetos Varien_Eventes muy específica para contener datos de eventos. Por lo tanto, siempre dependo del objeto de evento. Siento que ese es el enfoque correcto.
Rajeev K Tomy
@RajeevKTomy vea mi respuesta, en realidad no tiene sentido usarlo, getEvent()excepto si necesita el nombre del evento O desea ser compatible con Magento 1.0
Raphael en Digital Pianism
3

Explicación sobre la falta de consistencia.

Según Vinai y lo que Vitaly Korotun le dijo en algún momento:

getEvent()Es legado. De vuelta en Magento 1.0 días, los datos del evento no se pudieron extraer directamente del observador.

Entonces, si no necesita obtener event_namey no le importa demasiado que su código sea compatible con Magento 1.0, puede omitirlo getEvent().

Raphael en Digital Pianism
fuente