Pregunta

Estoy tratando de crear un módulo mínimo de pago total que evitará que alguien consulte con un total de menos que una cantidad configurable.

Estoy usando el evento sales_quote_save_before Para mostrar un error en la página de pago/carrito cuando se abre.

<?xml version="1.0"?>
<config>
    <frontend>
        <events>
            <sales_quote_save_before>
                <observers>
                    <b2b>
                        <class>b2b/observer</class>
                        <method>checkTotalsCart</method>
                    </b2b>
                </observers>
            </sales_quote_save_before>
        </events>
    </frontend>
</config>

Y en el observador

public function checkTotalsCart()
{
    if ($this->_hasCartError()) { /* does some checks, returns bool */
        $this->_setErrorMessage();
    }
}
protected function _setErrorMessage()
{
    $session = Mage::getSingleton("b2b/session"); /* extends Mage_Core_Model_Session */
    $session->addError($this->helper->getErrorMessage());
}

El problema es que cuando actualiza el carrito de la página del carrito, el mensaje de error aparece dos veces. Supongo que ese evento está sucediendo varias veces.

enter image description here

Intenté verificar si el mensaje se estableció previamente con una variable de sesión personalizada.

protected function _setErrorMessage()
{
    $session = Mage::getSingleton("b2b/session");
    if ($session->isErrorMessageAdded()) {
        return;
    }
    $session->addError($this->helper->getErrorMessage());
    $session->isErrorMessageAdded(true);
}

Pero eso tampoco funcionó. ¿Cómo puedo asegurarme de que un mensaje de error solo aparezca una vez por solicitud de página?


Archivos de módulo relevantes

Más

¿Fue útil?

Solución

Tu pensamiento era sólido, pero tu comprensión de los métodos mágicos de Magento es un poco inestable. los hasX No es un setter, solo verifica la presencia de una propiedad de datos. Entonces te gustaría cambiar

$session->hasErrorMessage(true);

a

$session->setErrorMessage(true);

También si b2b/session es un objeto de sesión real (es decir, persiste las cosas para la sesión de PHP para la recuperación posterior) sería desconfiado de usarlo para algo como esto. Si persiste accidentalmente la propiedad 'Error_message` en la sesión, lo que significa que el usuario solo verá este mensaje de error una vez por sección, cuando (aparece) su deseo es hacer que lo vean una vez por intentos de orden no válidos.

Por lo general, prefiero una variable de clase PHP estática para algo como esto

static protected $_hasErrorMessage=false;
protected function _setErrorMessage()
{
    $session = Mage::getSingleton("b2b/session");
    if (self::$_hasErrorMessage) {
        return;
    }
    $session->addError($this->helper->getErrorMessage());
    self::$_hasErrorMessage = true;
}

Otros consejos

Vamos a explorar addError un momento. addError es un método de conveniencia para no tener que hacer llamadas de mensaje de error como así:

Mage::getModel('core/message_collection')->add(Mage::getSingleton('core/message')->error($message));

Como puede ver, eso es realmente desordenado.

La mayoría de las implementaciones de addError, incluido eso en Mage_core_model_session_abstract, tener un método llamado addMessage, que esencialmente hacen lo que se enumera anteriormente. Utiliza un método local llamado getMessages que implementa el patrón de recopilación de mensajes ya descrito. Vea abajo:

public function getMessages($clear=false)
{
    //....stuff
    if ($clear) {
        $messages = clone $this->getData('messages');
        $this->getData('messages')->clear();
        Mage::dispatchEvent('core_session_abstract_clear_messages');
        return $messages;
    }
    //...stuff
}

Entonces, ¿cómo te ayuda esto?

Podrías proporcionar el addMessage Método en su propio modelo B2B/Sesión para pasar condicionalmente true a getMessages Para borrarlo, mostrando efectivamente solo el último conjunto de mensajes:

public function addMessage(Mage_Core_Model_Message_Abstract $message, $clear=false)
{

    $this->getMessages($clear)->add($message);
    Mage::dispatchEvent('core_session_abstract_add_message');
    return $this;   
}

Una solución que he usado (pensé que no es demasiado bonita) es recorrer los mensajes para la sesión y ver si esa cadena ya existe

/**
 * @var Mage_Checkout_Model_Session $_checkout
 */
protected $_checkout;
protected function _addMessage($message)
{
    $messages = array_values((array)$this->_checkout->getMessages());

    foreach ($messages[0] as $existingMessages) {
        foreach($existingMessages as $existingMessage) {
            $existingMessage = array_values((array)$existingMessage);

            if ($existingMessage[1] == $message) {
                // If the message is already set, stop here
                return;
            }
        }
    }

    // Add this message to the session/checkout
    $this->_checkout->addError($message);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top