0

So I try to create a store with laravel but I have a problem with the shopping cart. If a user adds an item in the shopping cart, it changes for all users. So if I add an item and then logout from user X and login to user Y, they have the same cart.
I'm somehow new to Laravel and I really don't know what's the problem here. Thanks for help!

Cart

<?php

namespace App;

class Cart
{
    public $items = null;
    public $totalQty = 0;
    public $totalPrice = 0;
    public function __construct($oldCart)
    {
        if ($oldCart) {
            $this->items = $oldCart->items;
            $this->totalQty = $oldCart->totalQty;
            $this->totalPrice = $oldCart->totalPrice;
        }
    }
    public function add($item, $id) {
        $storedItem = ['qty' => 0, 'price' => $item->price, 'item' => $item];
        if ($this->items) {
            if (array_key_exists($id, $this->items)) {
                $storedItem = $this->items[$id];
            }
        }
        $storedItem['qty']++;
        $storedItem['price'] = $item->price * $storedItem['qty'];
        $this->items[$id] = $storedItem;
        $this->totalQty++;
        $this->totalPrice += $item->price;
    }
    public function reduceByOne($id) {
        $this->items[$id]['qty']--;
        $this->items[$id]['price'] -= $this->items[$id]['item']['price'];
        $this->totalQty--;
        $this->totalPrice -= $this->items[$id]['item']['price'];
        if ($this->items[$id]['qty'] <= 0) {
            unset($this->items[$id]);
        }
    }
    public function removeItem($id) {
        $this->totalQty -= $this->items[$id]['qty'];
        $this->totalPrice -= $this->items[$id]['price'];
        unset($this->items[$id]);
    }
}

Product Controller

<?php

namespace App\Http\Controllers;

use App\Cart;
use App\Product;
use Illuminate\Http\Request;
use Session;
use Illuminate\Support\Facades\DB;

class ProductController extends Controller
{
    public function getIndex()
    {
        $products = Product::all();
        return view('shop.index', ['products' => $products]);
    }

    public function getAddToCart(Request $request, $id){
        $product = Product::find($id);
        $oldCart = Session::has('cart') ? Session::get('cart'): null;
        $cart = new Cart($oldCart);
        $cart->add($product, $product->id);

        $request->session()->put('cart', $cart);
        return redirect()->route('product.index');
    }

    public function getAddQty(Request $request, $id){
        $product = Product::find($id);
        $oldCart = Session::has('cart') ? Session::get('cart'): null;
        $cart = new Cart($oldCart);
        $cart->add($product, $product->id);

        $request->session()->put('cart', $cart);
        return redirect()->route('product.shoppingCart');
    }

    public function getReduceByOne($id) {
        $oldCart = Session::has('cart') ? Session::get('cart') : null;
        $cart = new Cart($oldCart);
        $cart->reduceByOne($id);
        if (count($cart->items) > 0) {
            Session::put('cart', $cart);
        } else {
            Session::forget('cart');
        }
        return redirect()->route('product.shoppingCart');
    }

    public function getRemoveItem($id) {
        $oldCart = Session::has('cart') ? Session::get('cart') : null;
        $cart = new Cart($oldCart);
        $cart->removeItem($id);
            if (count($cart->items) > 0) {
                Session::put('cart', $cart);
            } 
            else {
                Session::forget('cart');
            }
        return redirect()->route('product.shoppingCart');
    }

    public function getCart(){
        if(!Session::has('cart')){
            return view('shop.shopping-cart');
        }
        $oldCart = Session::get('cart');
        $cart = new Cart($oldCart);
        $total = $cart->totalPrice;
        $count = count($cart->items);
        Session::put('cart', $cart);
        return view('shop.shopping-cart', ['products' => $cart->items, 'totalPrice' => $cart->totalPrice, 'total' => $total, 'count' => $count]);
    }

    public function getCheckout()
    {
        if(!Session::has('cart')){
            return view('shop.shopping-cart');
        }
    $oldCart = Session::get('cart');
    $cart = new Cart($oldCart);
    $total = $cart->totalPrice;
    return view('shop.checkout',[ 'total' => $total]);
    }

    public function deleteProduct(Request $request, $id){
        $product = Product::find($id);
        $oldCart = Session::has('cart') ? Session::get('cart'): null;
        $cart = new Cart($oldCart);

        session()->pull('product', $product->id);
        $request->session()->put('cart', $cart);

        return redirect()->route('product.shoppingCart');
    }
}

User Controller

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use App\Http\Requests;
use Auth;
Use Session;
use App\Cart;

class UserController extends Controller
{
    public function getSignup()
    {
        return view('user.signup');
    }

    public function postSignup(Request $request)
    {
        $this->validate($request, [
            'sex' => 'required',
            'firstname' => 'required',
            'lastname' => 'required',
            'email' => 'email|required|unique:users',
            'password' => 'required|min:4'
        ]);

        $user = new User([
            'sex' => $request->input('sex'),
            'firstname' => $request->input('firstname'),
            'lastname' => $request->input('lastname'),
            'email' => $request->input('email'),
            'password' => bcrypt($request->input('password'))
        ]);
        $user->save();
        Auth::login($user);

        return redirect()->route('user.profile');
    }
    public function getSignin()
    {
        return view('user.login');
    }

    public function postSignin(Request $request){
        $this->validate($request, [
            'email' => 'email|required',
            'password' => 'required|min:4'
        ]);

    if(Auth::attempt([
        'email' => $request->input('email'), 
        'password' => $request->input('password')])){

        return redirect()->route('user.profile');
    }
        return redirect()->back();
    }

    public function getProfile(){
        $user = User::all();

        return view('user.profile',['user' => $user]);
    }

    public function getLogout(){

        Auth::logout();

        return redirect()->route('product.index');
    }
}
Hades2x
  • 13
  • 5
  • You are storing the cart object in the session. Regardless of whether you log in or out with a different user the cart will always exist that session. You are not associating the cart with a user but with the session. Try opening an incognito window and see if you get the same cart, I can pretty much guarantee you won't. – Matt Rink Aug 25 '17 at 12:34
  • Yeah, I don't. But having the same cart for 2 users using the same browser is still a problem. – Hades2x Sep 04 '17 at 08:28

1 Answers1

0

In Laravel Session variables persists if you use the same tab to switch user. So, if you save any session variable belonging to User X, it will still be there, when user Y logs in. Reference

So, you would need to explicitly remove the session for User X when user logs out using Session::forget('key')

Session::forget('cart');

But, this will create an issue that, whenever user logs out of your application his/her cart will be empty. To tackle this problem, you can would need to associate the cart with user id.

One way can be to add user_id to your session variable's key.

While adding the cart to session:

$user_id = /*get user_id*/;
Session::put($user_id.'cart', $cart);

While retrieving the cart:

$user_id = /*get user_id*/;
Session::get($user_id.'cart', $cart);

Instead of using session to store the cart, I think you should create the table to store the cart and use the foreign key to refer user.

jaysingkar
  • 4,315
  • 1
  • 18
  • 26