first(); // add currency to cache cache()->put('currency', $currency, now()->addMinutes(60)); $bearer = $this->getBearerToken(); if ($bearer) { [$personalAccessTokenId, $token] = explode('|', $bearer, 2); $personalAccessToken = PersonalAccessToken::find($personalAccessTokenId); if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) { // Authenticated $cart = Cart::with('product')->whereHas('product', function ($product) { $product->where('child_id', null); })->where('user_id', $personalAccessToken->tokenable_id)->orderBy('id', 'desc')->get(); } } else { // Check for local token in request headers $localToken = $this->getLocalToken(); if ($localToken) { $cart = Cart::with('product')->whereHas('product', function ($product) { $product->where('child_id', null); })->where('token', $localToken)->get(); } } $price_solutions = 0; $discount_solutions = 0; $total_solutions = 0; $price = 0; $discount = 0; $total = 0; $getReadySolutionProductsCart = collect([]); $getSingleProductsCart = collect([]); if (isset($cart)) { $getReadySolutionProductsCart = $cart->filter(function ($cart) { return $cart->product->is_ready_solution == true; }); $ready_solutions_count = 0; $price_solutions = $getReadySolutionProductsCart->filter(function ($cart) { return $cart->product->count >= $cart->count; })->map(function ($cart) use (&$ready_solutions_count) { $ready_solutions_count += $cart->count; $cart->product->price_total = !empty($cart->product->price_discount) ? $cart->product->price_discount * $cart->count : $cart->product->price * $cart->count; $cart->product->price_discount_total = !empty($cart->product->price_discount) ? ($cart->product->price - $cart->product->price_discount) * $cart->count : 0; $cart->product->price_products = $cart->product->price * $cart->count; return $cart; }); $discount_solutions = $price_solutions->sum('product.price_discount_total'); $total_solutions = $price_solutions->sum('product.price_total'); $price_solutions = $price_solutions->sum('product.price_products'); $single_products_count = 0; $getSingleProductsCart = collect($cart)->filter(function ($cart) { return $cart->product->is_ready_solution == false; }); $price = $getSingleProductsCart->filter(function ($cart) { return $cart->product->count >= $cart->count; })->map(function ($cart) use (&$single_products_count) { $single_products_count += $cart->count; $cart->product->price_total = !empty($cart->product->price_discount) ? $cart->product->price_discount * $cart->count : $cart->product->price * $cart->count; $cart->product->price_discount_total = !empty($cart->product->price_discount) ? ($cart->product->price - $cart->product->price_discount) * $cart->count : 0; $cart->product->price_products = $cart->product->price * $cart->count; return $cart; }); $discount = $price->sum('product.price_discount_total'); $total = $price->sum('product.price_total'); $price = $price->sum('product.price_products'); } // get currency from cache $currency = cache()->get('currency'); return [ 'data' => [ 'ready_solutions' => [ 'products' => CartResource::collection($getReadySolutionProductsCart), 'price' => ceiling($price_solutions * $currency->dollar, 100), 'discount' => ceiling($discount_solutions * $currency->dollar, 100), 'total' => ceiling($total_solutions * $currency->dollar, 100), ], 'ready_solutions_count' => $ready_solutions_count, 'single_products' => [ 'products' => CartResource::collection($getSingleProductsCart), 'price' => ceiling($price * $currency->dollar, 100), 'discount' => ceiling($discount * $currency->dollar, 100), 'total' => ceiling($total * $currency->dollar, 100), ], 'single_products_count' => $single_products_count ] ]; } private function getUser() { $bearer = $this->getBearerToken(); $type = null; $user = null; $token = null; if ($bearer) { [$personalAccessTokenId, $token] = explode('|', $bearer, 2); $personalAccessToken = PersonalAccessToken::find($personalAccessTokenId); if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) { // Authenticated $type = 'user'; $user = User::findOrFail($personalAccessToken->tokenable_id); $token = null; } } else { // Check for local token in request headers $localToken = $this->getLocalToken(); if ($localToken) { $type = 'token'; $user = null; $token = $localToken; } } return [ 'type' => $type, 'user' => $user, 'token' => $token ]; } public function addToCart(Request $request) { try { // Validate the request $request->validate([ 'product_id' => 'required|exists:products,id', ]); // Retrieve the bearer token from the request $bearer = $this->getBearerToken(); if ($bearer) { [$personalAccessTokenId, $token] = explode('|', $bearer, 2); $personalAccessToken = PersonalAccessToken::find($personalAccessTokenId); if ($personalAccessToken && hash_equals($personalAccessToken->token, hash('sha256', $token))) { // Authenticated $user = User::find($personalAccessToken->tokenable_id); if ($user) { $this->updateOrCreateCart($user, $request->product_id); return response()->json(['status' => true, 'data' => null]); } } } // Check for local token in request headers $localToken = $this->getLocalToken(); if (!$localToken) { return response()->json(['message' => 'Unauthorized'], 401); } $this->updateOrCreateCartByToken($localToken, $request->product_id); } catch (\Throwable $e) { return response()->json([ 'message' => $e->getMessage() ], 403); } return response()->json(['status' => true, 'data' => null]); } public function add(Cart $cart) { $user = $this->getUser(); try { DB::beginTransaction(); if (empty($user['type'])) abort(403); if ($user['type'] == 'token') { if ($cart->token != $user['token']) abort(403); } else if ($user['type'] == 'user') { if ($cart->user_id != $user['user']->id) abort(403); } $cart->update([ 'count' => $cart->count + 1 ]); } catch (\Throwable $e) { report($e); DB::rollBack(); return response()->json([ 'message' => trans('errors.try_again') ])->setStatusCode(403); } DB::commit(); return $this->getCart(); } public function decrease(Cart $cart) { $user = $this->getUser(); try { DB::beginTransaction(); if (empty($user['type'])) abort(403); if ($user['type'] == 'token') { if ($cart->token != $user['token']) abort(403); } else if ($user['type'] == 'user') { if ($cart->user_id != $user['user']->id) abort(403); } if ($cart->count <= 1) { $cart->delete(); } else { $cart->update([ 'count' => $cart->count - 1 ]); } } catch (\Throwable $e) { report($e); DB::rollBack(); return response()->json([ 'message' => trans('errors.try_again') ])->setStatusCode(403); } DB::commit(); return $this->getCart(); } public function delete($cartId) { try { DB::beginTransaction(); Cart::find($cartId)->delete(); } catch (\Throwable $e) { report($e); DB::rollBack(); return response()->json([ 'message' => trans('errors.try_again') ])->setStatusCode(403); } DB::commit(); return $this->getCart(); } protected function updateOrCreateCart($user, $productId) { $cart = $user->cart()->where('product_id', $productId)->first(); try { if ($cart) { // Update the existing cart item Cart::where('id', $cart->id)->update([ 'count' => $cart->count + 1 ]); } else { // Create a new cart item $user->cart()->create([ 'product_id' => $productId, 'count' => 1, ]); } } catch (\Throwable $e) { report($e); return response()->json([ 'message' => trans('errors.try_again') ])->setStatusCode(403); } } protected function updateOrCreateCartByToken($localToken, $productId) { $cart = Cart::where('token', $localToken) ->where('product_id', $productId) ->first(); if ($cart) { // Update the existing cart item Cart::where('id', $cart->id)->update([ 'count' => $cart->count + 1 ]); } else { // Create a new cart item Cart::create([ 'token' => $localToken, 'product_id' => $productId, 'count' => 1, ]); } } private function getLocalToken() { return request()->header('X-Application-Token'); } private function getBearerToken() { return request()->bearerToken(); } }