Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MattB's avatar
Level 2

Update Session Data on cart update

I have a shopping cart with the ability to add in a discount voucher code. I have the code working and it will add the discount just fine, but it only calculates on the cart the first time. For example, if I have a cart with 2 items which totals £10, I can remove 10% and make it £9. However, if I update one of the items to be 2 of the same item, the number will update, but the discount still removes £1 and not 10% of the new total price of all items.

Here's the model for Coupon:

class Coupon extends Model
{
    public static function findByCode($code)
    {
        return self::where('code', $code)->get();
    }

    public function discount($total)
    {
        if($this->type == 'fixed'){
            return $this->value;
        } elseif($this->type == 'percent'){
            return($this->percent_off / 100.0) * $total;
        } else{
            return 0;
        }
    }
}

I suspect the issue is because the session I'm storing it in only gets built the once and not when the cart updates. Do you know how I update the session with the new subtotal value when the cart changes?

Store request:

public function store(Request $request)
    {
       $oldCart = Session::get('cart');
       $cart = new Cart($oldCart);
       $totalPrice = $cart->totalPrice;
       $coupon = Coupon::where('code', $request->coupon_code)->first();
       if(!$coupon){
           return redirect()->back()->with('fail_message', 'Coupon Code Not Found');
       }
       session()->put('coupon',[
           'name' => $coupon->code,
           'id' => $coupon->id,
           'discount' => $coupon->discount($totalPrice),
           ]);
        return redirect()->back()->with('success_message', 'Coupon Has Been Applied');
    }

Cart model:

class Cart
{
    public $items = null;
    public $totalQty = 0;
    public $totalPrice = 0;
    public $pp = 3.95;

    public function __construct($oldCart){
      if ($oldCart){
        $this->items = $oldCart->items;
        $this->totalQty = $oldCart->totalQty;
        $this->totalPrice = $oldCart->totalPrice;
      }
    }
    public function contains($id){
      return ($this->items) && array_key_exists($id, $this->items);
    }

    public function add($item, $id){
      $storedItem = ['qty' =>0, 'price' => $item->price, 'item' => $item, 'id' => $id];
      if ($this->items) {
        if (array_key_exists($id, $this->items)) {
          $storedItem = $this->items[$id];
        }
      }else{
        $this->items = array();
      }
      $storedItem['price'] = $item->price;

        $storedItem['qty']++;
        $this->totalQty++;
        $this->totalPrice+=$item->price;
        $this->items[$id] = $storedItem;
    }

    public function removeItem($id){
      $this->totalQty -= $this->items[$id]['qty'];
      $this->totalPrice -= $this->items[$id]['price'];
      unset($this->items[$id]);
    }

    public function update($item, $id, $qty){
        $storedItem = ['qty' =>0, 'price' => $item->price, 'item' => $item, 'id' => $id];
        if ($this->items) {
            if (array_key_exists($id, $this->items)) {
                $storedItem = $this->items[$id];
            }
        }else{
            $this->items = array();
        }
        if($qty <= 0){
            $this->removeItem($id);
            return;
        }
        $this->totalQty -= $storedItem['qty'];
        $this->totalPrice -= $item->price * $storedItem['qty'];

        $storedItem['qty']=$qty;
        $this->totalQty+= $storedItem['qty'];
        $this->totalPrice+=$item->price * $storedItem['qty'];
        $this->items[$id] = $storedItem;
    }
}
0 likes
1 reply
MattB's avatar
Level 2

Can this be done? Or have I done it totally the wrong way?

Please or to participate in this conversation.