1

I have a cart variable as a multidimensional array as shown below

$totalCart   =  {"17":[{"id":"17","name":"New! iPhone 6 64gb GSM Unlocked Smartphone Space Gray, Refurbished","quantity":"1","price":"5000","attributes":[{"Ram Size":"1gb 16gb"},{"Color":"Black"}]},
                       {"id":"17","name":"New! iPhone 6 64gb GSM Unlocked Smartphone Space Gray, Refurbished","quantity":"1","price":"5000","attributes":[{"Ram Size":" 4gb 64gb"},{"Color":" Gold"}]}]}

Anytime an item is added to the cart it checks to see if the item id exists in the cart variable.

1) If it exists, it checks if its child has the same attributes as the attribute of the product that will be added.

a) If it has the same attributes it should increment the quantity or just add the new price to it.

b) Else it does not have the same attribute it should add this product to be as a new child but with different attributes

2) If it does not exist it should add it as a new parent product with a child

I am working on an ecommerce site that sells a products with different attributes. For instance i have an iphone with attributes such as 64gb, 128gb and at the same time different colors gold, black for instance. Now a customer want to by this products but different quantities of each variant. Lets say for instance an iphone 64gb, gold with a quantity of 12 and the same iphone 128gb, black with a quantity of 5

Now this is my implementation:

public function addToCart(Request $request) {
    $productId = $request->productId;
    $productName = $request->productName;
    $productPrice = $request->productPrice;
    $qty = $request->qty;
    $productPhoto =  $request->productPhoto;
    $subTypes = [];

    if(isset($request->subtypes)) {
        foreach ($request->subtypes as $key => $value) {
            $result = $array = explode('_', $value);
            $subTypes[] = array($result[0] => $result[1]);
        }
    }
    $cart = session()->get('cart');


    // if cart is empty then this the first product
    if ($cart == null) {

        $cart[$productId][0] = [
            "id" => $productId,
            "name" => $productName,
            "quantity" => $qty,
            "price" => $productPrice,
            "photo" => $productPhoto,
            "attributes" => $subTypes
        ];
       /* $cart = [
            $productId[0] => [
                "id" => $productId,
                "name" => $productName,
                "quantity" => $qty,
                "price" => $productPrice,
                "photo" => $productPhoto,
                "attributes" => $subTypes
            ]
        ];*/
        session()->put('cart', $cart);
        return json_encode(['totalCart' => $cart]);
       return json_encode(['status' => 'ok','totalCart' => count($cart)]);

    }

    // if cart not empty then check if this product exist then increment quantity
   else if(isset($cart[$productId])) {

        foreach ($cart[$productId] as $key => $value2 ){
            if ($this->compareArray($value2['attributes'], $subTypes )){
                if ((int)$qty > 0) {
                    $cart[$productId][$key]['quantity'] = $cart[$productId][$key]['quantity'] + (int)$qty;
                }
                else{
                    $cart[$productId][$key]['price'] = $cart[$productId][$key]['price'] + (int)$productPrice;

                }
            }else{
                array_push($cart[$productId], [
                    "id" => $productId,
                    "name" => $productName,
                    "quantity" => $qty,
                    "price" => $productPrice,
                    "photo" => $productPhoto,
                    "attributes" => $subTypes
                ]
            );
            }
        }


       session()->put('cart', $cart);
       return json_encode(['totalCart' => $cart]);
       return json_encode(['status' => 'ok','totalCart' => count($cart)]);


    }else {

       // if item not exist in cart then add to cart
       $cart[$productId][0] = [
           "id" => $productId,
           "name" => $productName,
           "quantity" => $qty,
           "price" => $productPrice,
           "photo" => $productPhoto,
           "attributes" => $subTypes
       ];


       session()->put('cart', $cart);
       return json_encode(['totalCart' => $cart]);
       return json_encode(['status' => 'ok','totalCart' => count($cart)]);
    }
}

public function compareArray ($array1, $array2) { foreach ($array1 as $key => $value) { if ($array2[$key] != $value) { return false; } else { return true; } } }

But the foreach loop stops anytime the first condition is met. whereas there is actually a child product that has a matching attribute with the attribute of the product to be added. How do I make sure that entire child of each parent product is checked?

dWinder
  • 11,597
  • 3
  • 24
  • 39
Chinelo
  • 45
  • 1
  • 1
  • 10

2 Answers2

0

$arraysAreEqual = ($a == $b); // TRUE if $a and $b have the same key/value pairs. $arraysAreEqual = ($a === $b); // TRUE if $a and $b have the same key/value pairs in the same order and of the same types. see: PHP - Check if two arrays are equal

Pseudocode:

// array_diff_key returns an array off different items compared to second parameter
if ($card === array_diff_key($totalCard,$card)) {
  // $card does not exist
  // toDo: add to $totalCard
} else {
   if($product === $totalCard[$productId]) {
     // raise quantity
   } else {
     // add as new child
   }
}
MGrahl
  • 11
  • 1
  • hello MGrahi i tried the === sign and it worked but the else part of the conditional statement still executes despite the fact that it found a matching product – Chinelo Jan 09 '19 at 10:37
0

Your compareArray function has wrong logic. Currently, it will stop is the first attribute is the same.

You need to replace

if ($this->compareArray($value2['attributes'], $subTypes )){

with:

if ($value2['attributes'] === $subTypes) {

Edited

Also notice that you loop on all products and check there attribute -> this cause to add the product to the list if at least one of the products has different attribute. To fix that use the following logic:

$found = false;
foreach ($cart[$productId] as $key => $value2 ) {
    if ($value2['attributes'] === $subTypes) {
        $found = true; // mark flag
        if ((int)$qty > 0) {
            $cart[$productId][$key]['quantity'] = $cart[$productId][$key]['quantity'] + (int)$qty;
        } else {
            $cart[$productId][$key]['price'] = $cart[$productId][$key]['price'] + (int)$productPrice;
        }
    }
}
if (!$found) { // if non prudect found add hi,
    array_push($cart[$productId], [ "id" => $productId, ... // add all field to new product ]);
}
dWinder
  • 11,597
  • 3
  • 24
  • 39
  • i tried your method it worked.But at the same time it still adds the product as a child. even after it matches. I dont know if i structured the if else statement properly. – Chinelo Jan 09 '19 at 10:13
  • @Chinelo That happens because if you has 2 product with the same ID but different attributes -> the one with the same attribute been treated fine but when the for loop gets to the different one it add him - I will update my answer to address this issue also – dWinder Jan 10 '19 at 08:43