darryldecode / laravelshoppingcart

Shopping Cart Implementation for Laravel Framework
1.34k stars 440 forks source link

save cart to orders table #110

Closed robertnicjoo closed 6 years ago

robertnicjoo commented 6 years ago

Hi, how can I save cart info in my orders table when i hit checkout button?

frezno commented 6 years ago

what exactly is your problem, @robertnicjoo ?

robertnicjoo commented 6 years ago

@frezno my problem is how to save my cart info into orders table in my database.

PS: while after I asked this question I ended-up with this code below


public function checkout(Request $request)
    {
      $cartItems = Cart::getContent();
      $order = new Order();
      $order->cart = serialize($cartItems);
      $order->user_id = Auth::user()->id;
      $order->address_id = $request->input('address_id');
      $order->payment_id = $request->input('payment_id');
      $order->orderstatus_id = $request->input('orderstatus_id');

      Auth::user()->orders()->save($order);
      Cart::clear();
      return redirect()->route('ordersindex');
    }

and with this code I can save my cart to orders table but the problem I'm facing is returning data from database to view. What I will get is something like:

O:32:"Darryldecode\Cart\CartCollection":1:{s:8:"*items";a:1:{i:29;O:32:"Darryldecode\Cart\ItemCollection":2:{s:9:"*config";a:4:{s:14:"format_numbers";b:0;s:8:"decimals";i:0;s:9:"dec_point";s:1:".";s:13:"thousands_sep";s:1:",";}s:8:"*items";a:6:{s:2:"id";i:29;s:4:"name";s:6:"effewf";s:5:"price";d:24524;s:8:"quantity";i:3;s:10:"attributes";O:41:"Darryldecode\Cart\ItemAttributeCollection":1:{s:8:"*items";a:0:{}}s:10:"conditions";a:0:{}}}}}

What I'm looking for is if there is any other way better than my way to store data in my orders table which doesn't kill me to return data from database! OR fix for my solution.

frezno commented 6 years ago

you could use unserialize to unserialze the data, @robertnicjoo but imho one shouldn't use serialize anyway to store the data.

Instead of storing the serialized data you can loop through the cart content and insert each item to a cart table, eg

(just out of the blue and not using Eloquent, for showing the idea behind it, not necessarily working exactly as shown)

public function storeCart($user_id, $cartItems)
{
        //-- Make order_id the current time
        $order_id = time();

        $query = "INSERT INTO user_carts
                      (order_id, user_id, sku, text, qty, price)
                  VALUES ";

        foreach ($cartItems as $c) {
            $query .= "($order_id, $user_id, '". $c['attributes']['sku'] ."', '". $c['name'] ." ".
                        $c['attributes']['option'] ." ". $c['attributes']['variant'] ."', ".
                        $c['quantity'] .", ". $c['price'] ."),";
        }

        //-- Replace trailing comma with a semicolon
        $query = substr_replace($query, ";", -1);

        DB::select($query);

        return $order_id;
}

ok, there we have a table with all ordered items.

In a second table you can store the remaining details of the order and the order id belonging to the order.

private function storeOrder($user_id, $order_id, $address_id, $payment_id, $orderstatus_id)
{
        $query = "INSERT INTO  user_orders
                              (user_id, order_id, address_id, payment_id, orderstatus_id)
                       VALUES ($user_id, $order_id, $address_id, $payment_id, $orderstatus_id)";

        DB::select($query);
}
darryldecode commented 6 years ago

hi, saving orders to your database is out of scope on this cart project. You can implement your own logic after your checkout process. Eg. you can have dedicated orders table on your database to store your costumer orders. And yes @frezno suggestion to avoid serialize data on your database in correct as you will have hard time doing search and you can't use the MYSQL indexes.

robertnicjoo commented 6 years ago

@frezno thanks man your answer gave me idea also makes me double confused with the query you used :)) Question: what if except serialize I save data as json then will be same issue as it is now?

@darryldecode Hi bro, appreciate your comment as your opinion that this question is out of scope of this project I have another question which is 100% in scope of this project and it didn't get answer 20 days by now! I would appreciate if you can help me with that instead, here it is https://github.com/darryldecode/laravelshoppingcart/issues/109

robertnicjoo commented 6 years ago

@frezno @darryldecode Hello again, well the good news is I managed to get info out of serialized data and here is how (In case other people need it some day)

controller

$orders = Order::orderby('id', 'desc')->paginate(10);
        $orders->transform(function($order, $key) {
          $order->cart = unserialize($order->cart);
          return $order;
        });
        return view('admin.orders.index', compact('orders'));

blade

@foreach($orders as $order)
   @foreach($order->cart as $item)
         {{$item['name']}}
   @endforeach
@endforeach

Issue

I want to have access to single order detail in show method, where I can get order row info with code below, but I also need some sort of transform method to get that specific order cart detail which still not able to do that and need help for it.

public function show($id)
    {
        $order = Order::findOrFail($id);
        return view('admin.orders.show', compact('order'));
    }
frezno commented 6 years ago

@robertnicjoo as you can see now, it's no good idea to use serialized data for your task.

if you'd do it the way i demonstrated above you won't run into such problem(s).

robertnicjoo commented 6 years ago

@frezno hi bro, I managed to get it work in my show function but there was troubles in edit function with serialized, also I read lot's of articles which they suggested to use json instead of serialized for security and other matters, so I decided to save my cart as json which the saved data is much more cleaner than serialized way,

currently when my data saves is like:

"{\"29\":{\"id\":29,\"name\":\"effewf\",\"price\":24524,\"quantity\":1,\"attributes\":[],\"conditions\":[]}}"

but I have issue to showing parts of this json code such as showing product name. I've tried many ways the most I could achieve was getting same code as above in my blade but not part of it!

What I need is how to get my json code(above) parts in my blade so I can view/edit etc.

any idea?

darryldecode commented 6 years ago

111

Blum commented 6 years ago

Hello,

For this purpose I'm using good old serialize() and it just saves the cart item object as it is.. unserialize() after that brings it all back again.

But using laravel's array or object cast doesn't seem to make it right.

darryldecode commented 6 years ago

@robertnicjoo See new release, updated docs and see the udpated demo repo here: https://github.com/darryldecode/laravelshoppingcart-demo

robertnicjoo commented 6 years ago

As we will continue this conversation on https://github.com/darryldecode/laravelshoppingcart/issues/111 I will close this.

@Blum this was by serialize bro, we decided to change it to json. Thanks for sharing anyway.