2010-03-01 5 views
5

PREGUNTA REVISADA: Hemos seguido este método para agregarlo al carrito. He revisado completamente la pregunta.Magento personalizado agregar al carrito proceso no funciona

Estoy trabajando en un sitio que está utilizando Magento ver. 1.3.2.4 como su plataforma de comercio electrónico. Hemos creado un proceso personalizado de "Agregar al carro" que agrega varios elementos al carro a través de una solicitud de AJAX. Después de esta solicitud, se realiza algún postprocesamiento con JavaScript en el navegador antes de redireccionar a la página "Ver carro". El 99% del tiempo, este proceso parece funcionar correctamente en Firefox y Safari, pero en IE8, el proceso falla. Al agregar un artículo al carro, después de ser redirigido a la página "Su carrito", el carro de compras está vacío.

No todos los elementos en el sitio se agregan a través de este proceso AJAX. Este problema solo ocurre cuando el carro está vacío antes de agregar los artículos a través de AJAX. Es decir, si un elemento que se agrega a través del proceso normal de Magento se agrega al gato primero, las solicitudes para agregar AJAX al carrito siempre se realizan correctamente. Las cookies de eliminación de Blu y luego intentar agregarlas a través de AJAX fallarán consistentemente en IE8.

El servidor es un servidor Apache/PHP con PHP 5.2.9, eAccelerator y Suhosin. Por favor, solicite cualquier información adicional y estaremos encantados de proporcionarla. Estamos almacenando sesiones en una base de datos MySQL.

Aquí está el código para nuestro método personalizado de añadir al carrito. Este código se encuentra en /app/code/core/Mage/Checkout/controllers/CartController.php:

public function ajaxaddAction() 
{ 
    $result = array('success' => true); 

    try 
    { 
     $session = $this->_getSession(); 
     $cart = $this->_getCart(); 

     $products = json_decode($_POST['products'],true); 

     if(!is_array($products)) 
     { 
      throw new Exception("Products data not sent"); 
     } 

     foreach ($products as $product_data) 
     { 
      $product = $this->_initProduct($product_data['id']); 

      if(!$product) 
       throw new Exception("Product id {$product_data['id']} not found"); 

      $info = array('qty' => $product_data['qty']); 

      if($product_data['options']) 
       $info['options'] = $product_data['options']; 

      $cart->addProduct($product,$info); 
     } 

     $cart->save(); 

     $this->_getSession()->setCartWasUpdated(true); 

     /** 
     * @todo remove wishlist observer processAddToCart 
     */ 
     Mage::dispatchEvent('checkout_cart_add_product_complete', 
      array('product' => $products[0], 'request' => $this->getRequest(), 'response' => $this->getResponse()) 
     ); 

     $cartItems = $cart->getQuote()->getAllItems(); 

     $result['cart'] = array(); 

     foreach($cartItems as $item) 
      $result['cart'][] = json_decode($item->toJson()); 
    } 
    catch (Mage_Core_Exception $e) 
    { 
     if ($this->_getSession()->getUseNotice(true)) { 
      $this->_getSession()->addNotice($e->getMessage()); 
     } else { 
      $messages = array_unique(explode("\n", $e->getMessage())); 
      foreach ($messages as $message) { 
       $this->_getSession()->addError($message); 
      } 
     } 
     $result['success'] = false; 
     $result['exception'] = $e->getMessage(); 
    } 

    catch (Exception $e) { 
     $this->_getSession()->addException($e, $this->__('Can not add item to shopping cart')); 
     $result['success'] = false; 
     $result['exception'] = $e->getMessage(); 
    } 

    header('Content-Type: application/json',true); 

    ob_end_clean(); 

    echo json_encode($result); 

    exit(); 
} 

Por favor, no responder con "Mover el código para el directorio /app/code/local/". Entiendo que es un mejor lugar para eso, y lo moveré allí en el futuro, pero a menos que su respuesta resuelva el problema, simplemente publique un comentario. Para obtener una respuesta más rápida estoy comenzando una recompensa y quiero buenas respuestas a este problema específico, no solo consejos sobre mejores formas de integrar este código.

Si hay alguna información que pueda proporcionar para ayudar, por favor hágamelo saber. Estamos dentro de un plazo apretado ...

+0

pierdo mi recompensa, incluso si acepto mi propia respuesta. Y mi propia respuesta no responde completamente la pregunta. ¿Alguien quiere 550 puntos de rep? ;-) – Josh

+0

@Josh, si quieres recuperar la mitad de tu recompensa, solo repítale la respuesta de alguien, no aceptes nada, si esa respuesta recibe +2 votos a favor y si no aceptas nada, tú y él compartirán mitad/mitad de la recompensa cuando termina la recompensa. http://stackoverflow.com/faq – YOU

+0

@ S.Mark: Bueno, me gustaría obtener una respuesta más que mis puntos de recompensa. Pero incluso si hice lo que dijiste, no recuperé la mitad. De las preguntas frecuentes: en cualquier caso, siempre renunciará a la cantidad de reputación especificada en la recompensa, por lo que si comienza una recompensa, asegúrese de hacer un seguimiento y aceptar la mejor respuesta. – Josh

Respuesta

4

He pasado más de 10 horas en esto. Por el momento creo que tengo una solución parcial . Pero no estoy seguro de por qué esta solución funciona ...

Parece que Magento requiere una redirección para completar el proceso de agregar al carrito. Así que en lugar de

header('Content-Type: application/json',true); 
ob_end_clean(); 
echo json_encode($result); 
exit(); 

almaceno mi JSON en la sesión y redirigir a una nueva cesta de acción:

$this->_getSession()->setCartJsonResult(json_encode($result)); 
$this->_redirect('checkout/cart/postajaxadd'); 

Esa acción a continuación, vuelca los datos JSON

public function postajaxaddAction() 
{ 
    $session = $this->_getSession(); 

    header('Content-Type: application/json',true); 
    ob_end_clean(); 
    echo $this->_getSession()->getCartJsonResult(); 
    exit(); 
} 

esto falla a veces; sin embargo, ahora mi código JavaScript no obtiene los datos JSON que esperaba y puede repetir la solicitud. La segunda solicitud es exitosa con más frecuencia que la primera ... Sin embargo, todavía hay casos en que las solicitudes AJAX fallan sin importar qué.

+0

¿Qué tal si configura 'text/plain' en lugar de' application/json', creo que algunos navegadores no conocen ese tipo de contenido. – YOU

+0

Estoy usando Prototype y espera la aplicación/json ... Además, esto no tiene ningún efecto sobre si el artículo se agrega al carro. ¡Gracias! – Josh

1

Hemos tenido problemas para agregar cosas al carro cuando se agota el almacenamiento de la sesión y no se pueden crear sesiones nuevas. Si está almacenando sesiones en un disco o en Memcache, verifique que haya asignado suficiente espacio.

+0

Gracias por el consejo. Ese es un buen punto. Estoy almacenando sesiones en la base de datos, y el espacio está bien. – Josh

3

No estoy seguro de si esto está causando los problemas que está teniendo, pero una mejor forma de hacer una respuesta JSON sería utilizar la "forma Magento/Zend" existente de hacerlo.

En lugar de:

header('Content-Type: application/json',true); 

ob_end_clean(); 

echo json_encode($result); 

exit(); 

Uso:

$this->getResponse()->setHeader('Content-Type', 'application/json', true)->setBody(json_encode($result)); 
+0

Agradable. Eso no resolvió el problema, pero es una mejor manera de manejarlo que a mi manera. ¡Muchas gracias! – Josh

+0

Implementé ese código, es mucho más claro, pero el problema todavía existe. – Josh

Cuestiones relacionadas