Pregunta

He creado una integración API con un minorista de terceros. He creado mis propias llamadas Mage::dispatchEvent antes y después de la comunicación. Yo sobre todo utilizar éstos para el modo de depuración de registro /, pero ahora tienen la oportunidad de utilizarlos para manipular los datos de otro módulo, vagamente relacionada que usarían esta API.

En el siguiente ejemplo es posible manipular $post_string en este ámbito local sobre la base de lo que mi observador puede hacer?

Mage::dispatchEvent('my_api_delete_before', array('post_string'=>$post_string, 'my_cart'=>$this));

$result = $this->doApiCommunication($post_string);

Mage::dispatchEvent('my_api_delete_after', array('post_string'=>$post_string, 'result'=>$result, 'product'=>$product, 'cart_item_id'=>$_item->cartItemId));
¿Fue útil?

Solución

Si $post_string es una cadena, entonces no. Los cambios realizados a la misma en la clase observador no se muestran en este ámbito, porque las cadenas no se pasan por referencia a las funciones.

Hay varias soluciones para que:

rápida pero no es recomendable:

PHP le da una solución, forzando la cadena que se pasa por referencia a la función mediante la adición de un & antes del nombre de la variable, así:

Mage::dispatchEvent('my_api_delete_before', array('post_string'=>&$post_string, 'my_cart'=>$this));

Pero la razón de que esto no es recomendable, ya que dicho @dedmeet en su comentario :

usando la llamada en tiempo pase por referencia no está soportado desde la versión PHP 5.4.0

Directamente desde la PHP manual de :

Nota: No hay ninguna señal de referencia en una llamada de función - sólo en función de definiciones. Las definiciones de funciones son suficientes para pasar correctamente el argumento por referencia. A partir de PHP 5.3.0, obtendrá una advertencia diciendo que "llamadas en tiempo pase por referencia" está en desuso cuando se utiliza y en foo (& $ a) ;. Y a partir de PHP 5.4.0, llamadas en tiempo pase por referencia era retirado, por lo que aumentará el uso de un error fatal.

Así que aquí es cómo hacerlo de una manera que es

Limpiador y recomendado:

Una mejor solución sería la creación de un Varien_Object porque las clases siempre se pasan por referencia. Y cualquier clase que se extiende Varien_Object y el propio Varien_Object, le da la capacidad de utilizar los captadores y definidores que encuentre alrededor Mangento.

$obj = new Varien_Object();

// Set a value for data variable
$obj->setFoo($bar);

// The previous function is the same as the following:
// In fact, the previous function will call setData with 'foo' and $bar as its paramteres
$obj->setData('foo', $bar);

// To get the value of 'foo' you will need to call any of the following functions:
$obj->getFoo();

$obj->getData('foo');    

Así que para poner en práctica el Varien_object en el ejemplo de la OP:

class Foo_Bar_Model_Communicator{

    public function someFunction(){
        /*
         * Assuming that $post_string is getting set here somehow
         * before the next line.
         */
        $eventData = new Varien_Data();

        $eventData->setData('post_string', $post_string);   
        $eventData->setData('cart', $this); 

        Mage::dispatchEvent('my_api_delete_before', array('event_data'=>$eventData));

        /* In this case, since we sent a Varien_Object as parameter,
         * whatever the Observer class does to the object, will be reflected
         * here as well.
         * We only need to make sure that we get the string back from the
         * Varien_Object instead of using $post_string.
         */
        $new_post_string = $eventData->getData('post_string');

        $result = $this->doApiCommunication($new_post_string);

        /*
         * We can do the same for the parameters for the next event, but it
         * wasn't part of the OP's question and it won't be needed since
         * there is no code following the dispatch event.
         *
         * However it would be a better idea to make the "before" & "after"
         * events have the same type of parameters which would be less 
         * confusing later on.
         */

        Mage::dispatchEvent('my_api_delete_after', array('post_string'=>$post_string, 'result'=>$result, 'product'=>$product, 'cart_item_id'=>$_item->cartItemId));
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top