Error al añadir producto en el carrito de compra PHP/MYSQLI

publicado por: Anonymous

Estoy realizando un sistema ecommerce nativamente con PHP, todo funciona perfectamente.

Excepto que no logro duplicar los productos en el carro de la compra cuando un cliente agrega el mismo producto pero con un color o talla diferente al que se haya agregado al carrito.

Si el cliente vuelve a elegir el mismo producto con una talla o color diferente lo que hace es actualizar la talla anterior y su color y esto no es lo ideal, lo ideal es que duplique ese producto.

Ejemplo: (Lo que deseo lograr cuando se agrega el mismo producto pero con talla o color diferente)
introducir la descripción de la imagen aquí

Mi código

cart.php

<?php
session_start();
require "config.ini.php";

$itemCount = isset($_SESSION['cart']) ? count($_SESSION['cart']) : 0;
if (isset($_SESSION['qty'])) {
    $meQty = 0;
    foreach ($_SESSION['qty'] as $meItem){
        $meQty = $meQty + $meItem;
    }
} else {
    $meQty = 0;
}

if (isset($_SESSION['cart']) and $itemCount > 0){
    $itemIds = "";
  foreach ($_SESSION['cart'] as $itemId){
    $itemIds = $itemIds . $itemId . ",";
  }

  $inputItems = rtrim($itemIds, ",");
  $meSql = "SELECT * FROM products WHERE id in ({$inputItems})";
  $meQuery = mysqli_query($kcon, $meSql);
  $meCount = mysqli_num_rows($meQuery);
} else {
    $meCount = 0;
}

if ($meCount == 0){
    echo "<div class="alert alert-warning">No hay artículos en la cesta</div>";
}else{
?>


<form action="updatecart.php" method="post" name="fromupdate">            
  <table class="table">
    <tr>
      <td>Producto</td>
      <td>Precio</td>
      <td>Cantidad</td>
      <td>Total</td>
    </tr>
    <?php
    $total_price = 0;
    $num = 0;
    $iva = 12;
    $shipping = 50;
    while ($meResult = mysqli_fetch_assoc($meQuery)){
        $key = array_search($meResult['id'], $_SESSION['cart']);
      $total_price = $total_price + ($meResult['price'] * $_SESSION['qty'][$key]);
      $intemId=$meResult['id'];
      $color = $_SESSION['colors'][$intemId];
      $size = $_SESSION['size'][$intemId];
      if ($total_price > 50){
        $shipping = 0;
      }
    ?>
    <tr>
      <td class="cart-image">
        <img src="<?php echo $meResult['image']; ?>" />
        <div class="cart-items">
          <h3><?php echo $meResult['product']; ?><?php echo $color; ?><?php echo $size?></h3>
        </div>
      </td>
      <td class="cart-price"><?php echo $meResult['price']; ?></td>
      <td>
        <input type="text" name="qtyupdate[<?php echo $num; ?>]" value="<?php echo $_SESSION['qty'][$key]; ?>" class="form-control" style="width: 60px;text-align: center;" autocomplete="off" data-validation="number" data-validation-allowing="float">
        <input type="hidden" name="arr_key_<?php echo $num; ?>" value="<?php echo $key; ?>">
        <a class="btn btn-danger btn-lg" href="removecart.php?itemId=<?php echo $meResult['id']; ?>" role="button">
        <span class="glyphicon glyphicon-trash"></span>Eliminar</a>
      </td>
      <td>$<?php echo number_format(($meResult['price'] * $_SESSION['qty'][$key]),2); ?></td>
      <?php
        $num++;
    }
  }
?>

updatecart.php

<?php
session_start();

$itemId = isset($_GET['itemId']) ? $_GET['itemId'] : "";

$_SESSION['colors'][$itemId]=$_POST['colors'];
$_SESSION['size'][$itemId]=$_POST['size'];

if ($_SERVER['REQUEST_METHOD'] == 'POST' and isset($_POST['qtyupdate'])) {
    for ($i = 0; $i < count($_POST['qtyupdate']); $i++) {
        $key = $_POST['arr_key_' . $i];
        $_SESSION['qty'][$key] = $_POST['qtyupdate'][$i];
    }

} else {
    $qty = isset($_POST['qty']) ? $_POST['qty'] : 1;
    if (!isset($_SESSION['cart'])) {
        $_SESSION['cart'] = array();
        $_SESSION['qty'][] = array();
    }
    if (in_array($itemId, $_SESSION['cart'])) {
        $key = array_search($itemId, $_SESSION['cart']);
        $_SESSION['qty'][$key] = $_SESSION['qty'][$key] + $qty;
    } else {
        array_push($_SESSION['cart'], $itemId);
        $key = array_search($itemId, $_SESSION['cart']);
        $_SESSION['qty'][$key] = $qty;
    }
}
header('location:cart.php');
?>

En el detalle del producto tengo el select donde se agrega la talla del producto:

<select name="size">
   <option value="XL">XL</option>
   <option value="M">M</option> 
</select>

Y el color del producto:

<div id="cont-colors">            
  <input id="id-7" type="radio" name="colors" class="selector-colors" value="Verde">
  <label for="id-7" title="Verde" id="colors" style="background:#008000;"></label>
  <input id="id-8" type="radio" name="colors" class="selector-colors" value="Azulado">
  <label for="id-8" title="Azulado" id="colors" style="background:#008080;"></label>
</div>

Y enviado:

 <form method="post" action="updatecart.php?itemId=3">

solución

Según veo el código la razón por la que se modifica la cantidad y el color es por que en updatecart.php estas sobre escribiendo su valor.

$_SESSION['colors'][$itemId]=$_POST['colors'];
$_SESSION['size'][$itemId]=$_POST['size'];

Como los mismos artículos tienen el mismo id aun que tengan el distinto color o tamaño el ultimo color y tamaño que se asigne sera el valor general del articulo.

Para solucionar este problema debes crear mas dimensiones a tu matriz una por Articulo,Color, y Tamaño:

$_SESSION['car'][$idArticulo][$color][$size] = $cantidad;
//$_SESSION['car'][1]['verde']['M'] = 2

Esto necesitara cambiar la lógica de la aplicación específicamente como guardas el carrito de compra.

Podrías hacelo así:

cart.php

<?php
session_start();
require "config.ini.php";


/**
 * Un elemento del carrito llegaria de la siguente forma:
 *
 * $_SESSION['car'][$idArticulo][$color][$size] = $cantidad;
 * $_SESSION['car'][1][verde][M] = 2
 *
 *
 */



/** Guardamos los el arreglo de articulos en una variable
 * para hacerla mas legible
 */

$articulos = isset ($_SESSION['cart'])  ?
             $_SESSION['cart'] :
             array();



/* Obtenemo el numero de articulos solicitados */
$itemCount = count($articulos);

/**
 * Inicalizamos variables  que se usaran en el while.
 * (Cambio de posicion para hacer mas legible el codigo )
 */

$total_price = 0;
$num = 0;
$iva = 12;
$shipping = 50;


/**
 * Cantidad de articulos totales en el carrito
 * (No utilizado en el codigo original)
 */

$meQty = 0;

/**
 * Obtenemos los ids de los articulos y los convertimos
 * en cadena seperada por comas
 */

$inputItems = implode(',',array_keys($_SESSION['car']));

/* Ejecutamos el query */
$meSql = "SELECT * FROM products WHERE id in ($inputItems)";
$meQuery = mysqli_query($kcon, $meSql);

/* Numero de articulos que existen en la base de datos */
$meCount = mysqli_num_rows($meQuery);

/* Si no hay articulos en el carrito */
if ($meCount == 0) :

?>
  <div class="alert alert-warning">No hay artículos en la cesta</div>

<?php

  /* Si no hay articulos detenemos la ejecucion */
  exit(0);

endif;

/* Continuamos si hay articulos en el carrito */





?>
<form action="updatecart.php" method="post" name="fromupdate">
  <table class="table">
    <tr>
      <td>Producto</td>
      <td>Precio</td>
      <td>Cantidad</td>
      <td>Total</td>
    </tr> <?php
    /* Inicia while */
    while ($meResult = mysqli_fetch_assoc($meQuery)):

      $id = $meResult['id'];
      foreach($articulos[$meResult['id']]  as $color => $sizes) :
        foreach($sizes as $size => $cantidad) :


          /**
           * Sumamos las cantidades para obtner la
           * cantidad total de articulos solicitados
           * (en codigo original no observo algun uso)
           * Supongo que se usa como sumatoria en la tabla
           * por ello lo agrego aqui.
          */

          $meQty += $cantidad;

          $precio = $meResult['price'] * $cantidad;

          $total += $precio;

        ?>
          <tr>
            <td class="cart-image">

              <img src="<?php echo $meResult['image']; ?>" />

              <div class="cart-items">
                <h3>
                    <?php echo $meResult['product']; ?>
                    <?php echo $color; ?>
                    <?php echo $size; ?>
                </h3>
              </div>

            </td>

            <td class="cart-price">

              <?php echo $meResult['price']; ?>

            </td>


            <td>

              <input type="text"
                     name="qtyupdate[<?php echo $id; ?>][<?php echo $color; ?>][<?php echo $size; ?>]"
                     value="<?php echo $cantidad ?>"
                     class="form-control"
                     style="width: 60px;text-align: center;"
                     autocomplete="off"
                     data-validation="number"
                     data-validation-allowing="float" >

              <input type="hidden"
                     name="arr_key_<?php echo $num; ?>"
                     value="<?php echo $key; ?>" >


              <a class="btn btn-danger btn-lg"
                 href="removecart.php?itemId=<?php echo $id; ?>"
                 role="button" >

                <span class="glyphicon glyphicon-trash"></span>Eliminar

              </a>

            </td>

            <td>

              $<?php echo number_format($precio, 2); ?>

            </td>

          </tr><?php

        endforeach;
      endforeach;
    endwhile;


?>

    <tr>
      <td colspan="2" class="cart-image">&nbsp;</td>

      <!-- Numero total de Articulos -->
      <td><?php echo $meQty ?></td>

      <!-- Cantidad total a pagar -->
      <td>$<?php echo number_format($total, 2); ?></td>

    </tr>
  </table class="table">
</form>

updatecart.php

<?php

session_start();

if (
    $_SERVER['REQUEST_METHOD'] == 'POST' &&
    isset($_POST['qtyupdate']) ) {

  $cantidades = isset($_POST['qtyupdate']) ?
              $_POST['qtyupdate'] :
              array();

  foreach ($cantidades as $idArticulo => $colores) {


      foreach($colores as $color => $sizes) {

        foreach($sizes as $size => $cantidad) {

          $_SESSION['cart'][$idArticulo][$color][$size] = $cantidad;
        }
      }
  }

  header('Location: cart.php');
  exit(0);
}



/* Cuando deseas modificar un solo elemento */

$itemId = isset($_GET['itemId']) ? $_GET['itemId'] : "";
$qty = isset($_POST['qty']) ? $_POST['qty'] : 1;

/*
*
* Si el color o el tamaño cambian deberas enviar el color y
* tamaño anterior para localizarlos en el carrito
*
**/

/*
*  valores anteriores necesarios para localizar el articulo
*  en la matriz
**/

$colorAnt = isset($_POST['colorsAnt']) ?
            $_POST['colorsAnt'] :
            '';
$sizeAnt  = isset($_POST['sizeAnt']) ?
            $_POST['sizeAnt'] :
            '';


/*
*  Si los nuevos valores no estan definidos consideramos
*  que no cambiaron y son iguales a los anteriores
*
**/

$size     = isset($_POST['size']) ?
            $_POST['size'] :
            $sizeAnt;

$color    = isset($_POST['colors']) ?
            $_POST['colors'] :
            $colorAnt;
/*
*  El valor anterior de la cantidad se asignara despues
*  Primero hay que asegurarse que el articulo esta presente
*  en el matriz (Carro de compra)
**/
$qty = isset($_POST['qty']) ?
            $_POST['qty'] :
            1;

$error = '';





// Validacion de Parametros
if (empty($itemId) ||
    ( (empty($colorAnt) || empty($sizeAnt)) &&
      (empty($color) || empty($size))
    )
) {

  $error = urlencode(
    '¡ Parametros incompletos no es posible localizar o ' .
    'agregar el articulo!'
  );

  $error .= '?error=' . $error;

  header('Location: cart.php' .$error );
  header('Location: cart.php?error=' .$error );
  exit(0);


} // Termina validacion de parametros



/*
 * Agregar un articulo al carrito si no lo necesitas puedes
 * omitir la signacion
 */

//si no se envian los colores y tamaños anteriores
if (empty($colorAnt) || empty($sizeAnt)) {

    $error = '';
    //$error = '! El articulo no se encuentra en el carrito !';



    /*
     * Si se envian el color y tamaño nuevo se considera que
     * hay que agregar el articulo al carrito.
     * Si no deseas esta funcionalidad puedes comentar la
     * linea siguiente y descomentar error
     */

      $_SESSION['car'][$itemId][$color][$size] = $qty;

     header('Location: cart.php' .$error );
     header('Location: cart.php?error=' .$error );
     exit(0);


} //Aqui termina agregar nuevo articulo



/* validar la existencia del articulo en el carrito */
if (! isset($_SESSION['car'][$itemId])) {

    /*
     * El articulo no existe en el carrito
     */
    $error = urlencode(
      '¡ El articulo no se encuentra en el carrito !'
    );


    $error .= '?error=' . $error;
    header('Location: cart.php' . $error );
    header('Location: cart.php?error=' . $error );
    exit(0);

}





/*
 * Si el usuario envio cero para cantidad se elimina el
 * articulo
*/
if (empty($qty)) {

  if (
       isset($_SESSION['car'][$itemId][$colorAnt]) &&
       isset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt])
  ) {

    unset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt]);
  }

  header('Location: cart.php' .$error );
  header('Location: cart.php?error=' .$error );
  exit(0);

} // Aqui termina eliminar articulo





/* Si cambio el tamaño*/
if ($size != $sizeAnt) {


  /* Si tambien cambio el color */
  if ($color != $colorAnt) {

    /* validamos que exista el elemento en el arreglo */
    if (
       isset($_SESSION['car'][$itemId][$colorAnt]) &&
       isset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt])
    ) {


      /* Eliminamos el elemento de ese tamaño */
      unset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt]);


      /* Si ya no hay articulos de ese color */
      if (count($_SESSION['car'][$itemId][$colorAnt]) == 0 ) {

        /* Eliminamos el articulo */
        unset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt]);
      }


    }

    $_SESSION['car'][$itemId][$color][$size] = $qty;

  } else {
    /* Si cambio el tamaño pero no cambio el color */


    if (
     isset($_SESSION['car'][$itemId][$colorAnt]) &&
     isset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt])
    ) {


      /* Eliminamos el elemento de ese tamaño */
      unset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt]);


      $_SESSION['car'][$itemId][$colorAnt][$size] = $qty;


    }

  }

  header('Location: cart.php' .$error );
  header('Location: cart.php?error=' .$error );
  exit(0);
  exit(0);

}



/*
 * Si solo cambio el color. Para el caso de ambas cosas ya
 * lo considera si cambio el tamaño
*/

if (($size === $sizeAnt) && ($color != $colorAnt)){

  /* validamos que exista el elemento en el arreglo */
  if (
     isset($_SESSION['car'][$itemId][$colorAnt]) &&
     isset($_SESSION['car'][$itemId][$colorAnt])
  ) {


    /* Eliminamos el elemento de ese tamaño */
    unset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt]);


    /* Si ya no hay articulos de ese color */
    if (count($_SESSION['car'][$itemId][$colorAnt]) == 0 ) {

      /* Eliminamos el articulo */
      unset($_SESSION['car'][$itemId][$colorAnt][$sizeAnt]);
    }


  }

  $_SESSION['car'][$itemId][$color][$sizeAnt] = $qty;
  header('Location: cart.php' .$error );
  header('Location: cart.php?error=' .$error );
  exit(0);
  exit(0);
}



/* Si no se cumple alguna de las condiciones anteriores */

$error = urlencode(
  '¡ Erro al modificar el carrito de compra !'
);


$error .= '?error=' . $error;

header('Location: cart.php' .$error );
header('Location: cart.php?error=' .$error );
exit(0);

Espero esto aclare mi punto.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *