PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.1
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / api / Resource / FrontendResource / CartResource.php

CartResource.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.1, at api/Resource/FrontendResource/CartResource.php

832 lines 26.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\Api\Resource\FrontendResource;
4
5 use FluentCart\Api\Cookie\Cookie;
6 use FluentCart\Api\Resource\BaseResourceApi;
7 use FluentCart\App\App;
8 use FluentCart\App\Helpers\AddressHelper;
9 use FluentCart\App\Helpers\CartHelper;
10 use FluentCart\App\Helpers\Helper;
11 use FluentCart\App\Models\Cart;
12 use FluentCart\App\Models\Customer;
13 use FluentCart\App\Models\ProductVariation;
14 use FluentCart\App\Services\RateLimiter;
15 use FluentCart\Framework\Database\Orm\Builder;
16 use FluentCart\Framework\Support\Arr;
17 use FluentCart\Framework\Support\Collection;
18 use WP_Error;
19
20 class CartResource extends BaseResourceApi
21 {
22
23 /**
24 * Per-request memo for get(). In production every HTTP request runs in a
25 * fresh PHP process, so this lives exactly one request. Long-running
26 * processes that simulate multiple requests (test suites, CLI) must clear
27 * it between simulated requests via resetCartCache() — as a
28 * function-static it was unreachable and leaked the first request's cart
29 * into every subsequent one.
30 *
31 * Only a resolved Cart is memoized; a null ("no cart") result is
32 * deliberately re-queried on the next call — matching the original
33 * function-static behavior, where isset(null) === false.
34 *
35 * @var Cart|null|false false = not resolved yet
36 */
37 private static $cartCache = false;
38
39 public static function resetCartCache(): void
40 {
41 static::$cartCache = false;
42 }
43
44 public static function getQuery(): Builder
45 {
46 return Cart::query();
47 }
48
49 public static function generateCartForInstantCheckout($variationId, $quantity = 1, $params = [])
50 {
51 RateLimiter::isSpamming('generate_instant_checkout_cart_attempt', 10, 60, true);
52
53 $isCustom = Arr::get($params, 'is_custom', false);
54
55 if($isCustom) {
56 $variation = Arr::get($params, 'variation');
57 $variation = CartHelper::normalizeCustomFields($variation);
58 }
59 else {
60 // product_detail must be eager-loaded — generateCartItemFromVariation
61 // reads $variation['product_detail']['variation_type'] to stamp
62 // the cart item's variation_type. Without it the field is null on
63 // instant-checkout carts and CartRenderer can't tell whether to
64 // hide the variant-title line for simple products.
65 $variation = ProductVariation::query()
66 ->with(['product', 'product_detail', 'media', 'shippingClass'])
67 ->where('id', $variationId)->first();
68
69 $variation = apply_filters('fluent_cart/cart/item_modify', $variation, [
70 'item_id' => $variationId,
71 'quantity' => $quantity,
72 ]);
73 }
74
75 if (!$variation) {
76 return new WP_Error(__('Invalid Product', 'fluent-cart'));
77 }
78
79 $quantity = apply_filters('fluent_cart/item_max_quantity', $quantity, [
80 'variation' => $variation,
81 'product' => !$isCustom ? $variation->product : []
82 ]);
83
84 if ($variation->payment_type === 'subscription') {
85 $quantity = 1;
86 }
87
88 if(!$isCustom) {
89 $canPurchase = $variation->canPurchase($quantity);
90 if (is_wp_error($canPurchase)) {
91 return $canPurchase;
92 }
93 }
94
95 $cartQuery = Cart::query()
96 ->whereJsonLength('cart_data', 1)
97 ->whereRaw("JSON_UNQUOTE(JSON_EXTRACT(cart_data, '$[0].id')) = ?", [(string)$variationId])
98 ->whereRaw("JSON_UNQUOTE(JSON_EXTRACT(cart_data, '$[0].quantity')) = ?", [(string)$quantity])
99 ->where('cart_group', 'instant')
100 ->where('stage', '==', 'draft');
101
102 if (is_user_logged_in()) {
103 $cartQuery->where('user_id', get_current_user_id());
104 } else {
105 $cartQuery->whereNull('user_id');
106 }
107
108 $cart = $cartQuery->first();
109
110 if (!$cart) {
111 if(!$isCustom) {
112 $cart = CartHelper::generateCartFromVariation($variation, $quantity);
113 }
114 else {
115 // Legacy object-to-array conversion. Kept for backward compatibility.
116 $cart = CartHelper::generateCartFromCustomVariation(json_decode(json_encode($variation), true), $quantity);
117 }
118 } else {
119 // Refresh cart_data from the current variation on every instant hit.
120 // The inputs (variationId + quantity) are deterministic URL params,
121 // so regenerating is idempotent — and it picks up any fields that
122 // were missing on a previously-created draft (variation_type for
123 // advanced-variation rows, refreshed pricing, updated featured
124 // media). Without this, a stale draft from before a code change
125 // keeps rendering with its old shape.
126 if (!$isCustom) {
127 $cart->cart_data = [
128 CartHelper::generateCartItemFromVariation($variation, $quantity)
129 ];
130 } else {
131 $cart->cart_data = [
132 CartHelper::generateCartItemCustomItem(json_decode(json_encode($variation), true), $quantity)
133 ];
134 }
135 }
136
137 if (is_user_logged_in()) {
138 $cart->user_id = get_current_user_id();
139 }
140
141 $cart->cart_group = 'instant';
142
143 $cart->cart_hash = md5(time() . wp_generate_uuid4());
144
145 $cart->save();
146 return $cart;
147
148 }
149
150 /**
151 * Retrieve cart based on the provided parameters.
152 *
153 * This function looks for a cart associated with the provided cart hash. If no cart is found,
154 * it creates a new cart for anonymous users. If the user is logged in, it associates the cart
155 * with the logged-in user.
156 *
157 * @param array $params Optional. Additional parameters for cart retrieval.
158 * [
159 * // Include optional parameters, if any.
160 * ]
161 *
162 */
163 public static function get(array $params = [])
164 {
165 if (static::$cartCache !== false && static::$cartCache !== null) {
166 return static::$cartCache;
167 }
168
169 $autoCreate = Arr::get($params, 'create', false);
170
171 $cartHash = Arr::get($params, 'hash');
172
173 //$cartHash = App::request()->get('fct_cart_hash');
174
175 if ($cartHash) {
176 $cartQuery = static::getQuery()
177 ->where('cart_hash', $cartHash)
178 ->where('stage', '!=', 'completed')
179 ->where('cart_group', 'instant');
180
181 $tempCart = $cartQuery->first();
182
183 static::$cartCache = $tempCart;
184
185 if (!$autoCreate) {
186 return $tempCart;
187 }
188 }
189
190 static::$cartCache = static::getOrSetCartForThisDevice($autoCreate);
191
192 return static::$cartCache;
193 }
194
195 public static function find($id, $params = [])
196 {
197
198 }
199
200 /**
201 * Create cart with the provided item data.
202 *
203 * @param array $data Required. Array containing the necessary parameters
204 * [
205 * 'id' => (int) Required.The ID of the item,
206 * 'quantity' => (int) Optional.The quantity of the item
207 * ]
208 * @param array $params Optional. Additional parameters for cart creation or update.
209 * [
210 * // Include optional parameters, if any.
211 * ]
212 *
213 */
214 public static function create($data, $params = [])
215 {
216 $itemId = Arr::get($data, 'id');
217 $quantity = Arr::get($data, 'quantity', 1);
218
219 if ($quantity <= 0) {
220 return static::makeErrorResponse([
221 ['code' => 403, 'message' => __('Quantity can not be negative.', 'fluent-cart')]
222 ]);
223 }
224
225 $cart = CartResource::get([
226 'create' => true
227 ]);
228 $cartArray = $cart->cart_data;
229
230 $cartArray = self::updateCartItemsQuantity(
231 [
232 'item_id' => $itemId,
233 'increment_by' => $quantity,
234 'existing_items' => $cartArray
235 ]
236 );
237
238 if (Arr::get($cartArray, 'code', '') === 'failed') {
239 return static::makeErrorResponse([
240 ['code' => 423, 'message' => Arr::get($cartArray, 'message', __('Cart validation error!', 'fluent-cart'))]
241 ]);
242 }
243
244 $cart->cart_data = Arr::get($cartArray, 'cart_data');
245 $message = Arr::get($cartArray, 'message');
246
247 $isCreated = $cart->save();
248
249 if ($isCreated) {
250 return static::makeSuccessResponse(
251 $isCreated,
252 __('Successfully added!', 'fluent-cart')
253 );
254 }
255
256 return static::makeErrorResponse([
257 ['code' => 400, 'message' => __('Could not add', 'fluent-cart')]
258 ]);
259 }
260
261 /**
262 * Update the quantity of an item in the cart.
263 *
264 * @param array $data Required. Array containing the necessary parameters for item quantity
265 * [
266 * 'item_id' => (int) Required.The ID of the product_variation,
267 * 'quantity'=> (int) Optional.The quantity of the item
268 * ]
269 * @param int $id Required. The ID of the cart.
270 * @param array $params Optional. Additional parameters for updating cart
271 * [
272 * // Include optional parameters, if any.
273 * ]
274 *
275 */
276 public static function update($data, $id = '', $params = [])
277 {
278 $cart = self::get([
279 'create' => true,
280 'hash' => Arr::get($params, 'hash'),
281 ]);
282
283 $itemId = (int)Arr::get($data, 'item_id');
284 $quantity = Arr::get($data, 'quantity', 0);
285 $byInput = (bool)Arr::get($data, 'by_input', false);
286
287 if (!$itemId) {
288 return new WP_Error(
289 'invalid_item',
290 __('Invalid item.', 'fluent-cart')
291 );
292 }
293
294 $existingItem = $cart->findExistingItemAndIndex($itemId);
295 $existingItem = Arr::get($existingItem, 1);
296
297 $rawIsCustom = $existingItem !== null
298 ? Arr::get($existingItem, 'is_custom', false)
299 : Arr::get($data, 'is_custom', false);
300
301 $isCustom = in_array(
302 strtolower((string) $rawIsCustom),
303 ['1', 'true'],
304 true
305 );
306
307 if($isCustom){
308 // Detect item and quantity change, let external modify item
309 if ($existingItem) {
310 $changedVariation = apply_filters('fluent_cart/cart/custom_item_quantity_changed', $existingItem,
311 [
312 'old_quantity' => (int) Arr::get($existingItem, 'quantity', 0),
313 'new_quantity' => $quantity,
314 'by_input' => $byInput,
315 'is_changed' => true,
316 'is_custom' => $isCustom,
317 ]);
318
319 if (!is_object($changedVariation)) {
320 $changedVariation = (object) $changedVariation;
321 }
322
323 $variation = $changedVariation;
324
325 $quantity = isset($changedVariation->quantity)
326 ? (int) $changedVariation->quantity
327 : 0;
328 }
329 else {
330 $variation = apply_filters('fluent_cart/cart/validate_custom_item', $existingItem, [
331 'item_id' => $itemId,
332 'quantity' => $quantity,
333 'is_custom' => $isCustom,
334 ]);
335
336 if (!is_object($variation)) {
337 $variation = (object) $variation;
338 }
339 }
340
341 if (!$variation || !is_object($variation)) {
342 return new WP_Error('invalid_custom_item',
343 __('Invalid custom item data.', 'fluent-cart'));
344 }
345
346 }else{
347 $variation = ProductVariation::query()->where('id', $itemId)->with('product')->first();
348 $variation = apply_filters('fluent_cart/cart/item_modify', $variation, [
349 'item_id' => $itemId,
350 'quantity' => $quantity,
351 ]);
352 }
353
354 if (!$variation) {
355 // An item already in the cart whose variation row has since
356 // disappeared (product/variation deleted) is dropped gracefully.
357 // An id that was never in the cart and resolves to nothing is a
358 // client error — silently answering "Cart updated successfully"
359 // hid typos and probing as a 200 no-op.
360 if ($existingItem !== null) {
361 return $cart->removeItem($itemId);
362 }
363
364 return new WP_Error(
365 'invalid_item',
366 __('Invalid item.', 'fluent-cart')
367 );
368 }
369
370 $soldIndividually = $isCustom
371 ? !empty($variation->sold_individually)
372 : (bool) $variation->soldIndividually();
373
374 if ($soldIndividually) {
375 if ($quantity >= 1) {
376 $quantity = 1;
377 }
378 $byInput = true;
379 }
380
381 if($isCustom) {
382 $cart = $cart->addByCustom(
383 is_array($variation) ? $variation : (array) $variation,
384 [
385 'quantity' => $quantity,
386 'is_custom' => $isCustom,
387 ]
388 );
389
390 }
391 else {
392 $cart = $cart->addByVariation($variation, [
393 'quantity' => $quantity,
394 'by_input' => $byInput,
395 'will_validate' => true,
396 'replace' => false,
397 'is_custom' => $isCustom,
398 ]);
399 }
400
401
402 if (is_wp_error($cart)) {
403 return $cart;
404 }
405
406 $utmData = static::prepareUtmData($data);
407 if ($utmData) {
408 $cart->utm_data = array_merge(is_array($cart->utm_data) ? $cart->utm_data : [], $utmData);
409 $cart->save();
410 }
411
412 return $cart;
413 }
414
415 public static function prepareUtmData(array $params): array
416 {
417 $data = [];
418 $allowedUtmParams = [
419 'utm_campaign',
420 'utm_content',
421 'utm_term',
422 'utm_source',
423 'utm_medium',
424 'utm_id',
425 'refer_url',
426 'fbclid',
427 'gclid'
428 ];
429
430 foreach ($allowedUtmParams as $utmParam) {
431 if (isset($params[$utmParam])) {
432 $data[$utmParam] = $params[$utmParam];
433 }
434 }
435 return $data;
436 }
437
438 /**
439 * Delete cart based on the provided user ID or cart hash.
440 *
441 * @param int $id Required. The user ID associated with the cart.
442 * @param array $params Optional. Additional parameters for cart deletion.
443 * [
444 * 'cart_hash' => (string) Optional. The cart hash for additional identification.
445 * ]
446 *
447 */
448 public static function delete($id, $params = [])
449 {
450 $cart = static::get();
451
452 if (empty($cart)) {
453 return null;
454 }
455
456 $deleted = $cart->delete();
457
458 if ($deleted) {
459 Cookie::deleteCartHash();
460 }
461
462 return $deleted;
463 }
464
465 public static function getStatus(): array
466 {
467 $cart = static::get(
468 [
469 'create' => false // Do not create a new cart if it doesn't exist
470 ]
471 );
472
473 if (!$cart) {
474 return [];
475 }
476
477 return [
478 'cart_hash' => $cart->cart_hash,
479 'cart_data' => $cart->cart_data,
480 'cart_user' => $cart->user_id,
481 ];
482 }
483
484 public static function isLicensedProduct($productVariation): bool
485 {
486 return Helper::hasLicense(Arr::get($productVariation, 'product'));
487 }
488
489
490 private static function validateShouldAddProduct($productVariation, $existingItemsArray)
491 {
492 if (Arr::get($productVariation, 'product.post_status') !== 'publish') {
493 return new WP_Error(
494 'item_not_available',
495 __('Item is not available.', 'fluent-cart')
496 );
497 }
498
499 $variationIds = (new Collection($existingItemsArray))->pluck('object_id');
500 $paymentType = Arr::get($productVariation, 'other_info.payment_type', false);
501
502 $hasInstantCheckoutParam = !empty(App::request()->get(Helper::INSTANT_CHECKOUT_URL_PARAM));
503
504 //early return as don't allow subscription item to add in cart
505 if ($paymentType !== 'onetime' && !$hasInstantCheckoutParam) {
506 return new WP_Error(
507 'item_not_available',
508 __('Item is not available.', 'fluent-cart')
509 );
510 }
511 $hasSubscription = static::hasSubscriptionProduct($existingItemsArray);
512
513 if (!$variationIds->contains(Arr::get($productVariation, 'id')) || empty($existingItemsArray)) {
514 return new WP_Error(
515 'item_not_available',
516 __('Item is not available.', 'fluent-cart')
517 );
518
519 }
520
521 if ($paymentType === 'onetime' && !$hasSubscription) {
522 return true;
523 }
524
525 if ($paymentType === 'onetime' && $hasSubscription) {
526 return new WP_Error(
527 'subscription_items_can_not_combined',
528 __('Subscription items can\'t be combined with other products in the cart.', 'fluent-cart')
529 );
530 }
531
532 return new WP_Error(
533 'item_not_available',
534 __('Item is not available.', 'fluent-cart')
535 );
536 }
537
538 public static function hasSubscriptionProduct($existingItemsArray = []): bool
539 {
540 $subscriptionProduct = (new Collection($existingItemsArray))->pluck('other_info')->filter(function ($info) {
541 $otherInfo = (array)$info;
542 $type = Arr::get($otherInfo, 'payment_type', false);
543 return $type === 'subscription';
544 });
545 return $subscriptionProduct->count() > 0;
546 }
547
548 private static function removeItemFromCart($existingItemsArray, $index): array
549 {
550 unset($existingItemsArray[$index]);
551 $message = __('Item removed from cart', 'fluent-cart');
552 return [
553 'message' => $message,
554 'cart_data' => $existingItemsArray,
555 ];
556 }
557
558 public static function updateItemQuantityInCart($productVariation, $existingItemsArray, $index, $quantity = 1, $isFilteredItem = false): array
559 {
560 $canBeAdded = true;
561
562
563 if (!$isFilteredItem) {
564 $canBeAdded = static::validateShouldAddProduct($productVariation, $existingItemsArray);
565 }
566
567
568 if (is_wp_error($canBeAdded)) {
569 return [
570 'code' => 'failed',
571 'message' => $canBeAdded->get_error_message()
572 ];
573 }
574
575 $updatedQuantity = $existingItemsArray[$index]['quantity'] + $quantity;
576
577 if ($updatedQuantity < 0) {
578 $updatedQuantity = 0;
579 }
580
581 if (!$isFilteredItem) {
582
583 if (!CartHelper::shouldAddItemToCart($productVariation, $updatedQuantity)) {
584 return [
585 'code' => 'failed',
586 'message' => __("You've reached the maximum quantity for this product.", 'fluent-cart')
587 ];
588 }
589 }
590
591 if ($productVariation instanceof ProductVariation) {
592 $item = CartHelper::generateCartItemFromVariation($productVariation, $updatedQuantity);
593 } else {
594 $item = CartHelper::generateCartItemCustomItem($productVariation, $updatedQuantity);
595 }
596
597
598 $existingItemsArray[$index] = $item;
599 return [
600 'message' => __('Quantity updated!', 'fluent-cart'),
601 'cart_data' => $existingItemsArray,
602 ];
603 }
604
605 public static function addItemInCart($productVariation, $existingItemsArray, $index, $quantity = 1, $isFilteredItem = false): array
606 {
607
608 if ($quantity < 1) {
609 $quantity = 1;
610 }
611 if (!$isFilteredItem) {
612 if (!CartHelper::shouldAddItemToCart($productVariation, $quantity)) {
613 return [
614 'code' => 'failed',
615 'message' => sprintf(
616 /* translators: %s is the product title */
617 __('%s is out of stock', 'fluent-cart'),
618 Arr::get($productVariation, 'variation_title')
619 ),
620 ];
621 }
622
623 $paymentType = $productVariation instanceof ProductVariation
624 ? $productVariation->payment_type
625 : Arr::get($productVariation, 'payment_type');
626
627 if ($paymentType === 'subscription' && $quantity > 1) {
628 return [
629 'code' => 'failed',
630 'message' => __('You cannot purchase more than one subscription at a time.', 'fluent-cart'),
631 ];
632 }
633
634 if (!empty($existingItemsArray)) {
635 $hasSubscription = static::hasSubscriptionProduct($existingItemsArray);
636
637 if ($paymentType === 'subscription' || $hasSubscription) {
638 return [
639 'code' => 'failed',
640 'message' => __("Subscription items can't be combined with other products in the cart.", 'fluent-cart'),
641 ];
642 }
643 }
644 }
645
646 if ($productVariation instanceof ProductVariation) {
647 $item = CartHelper::generateCartItemFromVariation($productVariation, $quantity);
648 } else {
649 $item = CartHelper::generateCartItemCustomItem($productVariation, $quantity);
650 }
651
652
653 $existingItemsArray[] = static::getCartSingleItemPreparedArray(
654 [
655 'variation' => $productVariation,
656 'quantity' => $quantity
657 ]
658 );
659
660
661 return [
662 'message' => __('Item added in cart!', 'fluent-cart'),
663 'cart_data' => $existingItemsArray,
664 ];
665 }
666
667 private static function updateCartItemsQuantity($params = []): array
668 {
669 $itemId = Arr::get($params, 'item_id');
670
671 $incrementBy = Arr::get($params, 'increment_by');
672 $existingItemsArray = Arr::get($params, 'existing_items', []);
673 if (!is_array($existingItemsArray)) {
674 $existingItemsArray = [];
675 }
676
677
678 $index = -1;
679
680 foreach ($existingItemsArray as $itemIndex => $existingItem) {
681 if (Arr::get($existingItem, 'object_id') == $itemId) {
682 $index = $itemIndex;
683 break;
684 }
685 }
686
687
688 /** @var $productVariation ProductVariation */
689 if ($incrementBy == 0) {
690 return static::removeItemFromCart($existingItemsArray, $index);
691 }
692
693 $productVariation = ProductVariation::query()->where('id', $itemId)->with([
694 'product',
695 'product.detail',
696 'product.licensesMeta',
697 'product_detail',
698 'media',
699 'shippingClass'
700 ])->first();
701
702
703 $isFilteredItem = false;
704 if (empty($productVariation)) {
705 $isFilteredItem = true;
706 $productVariation = apply_filters('fluent_cart/cart_item_product_variation', $productVariation, $itemId, $incrementBy, $existingItemsArray);
707 }
708
709
710 if (empty($productVariation)) {
711 return [
712 'code' => 'failed',
713 'message' => __('Item is not available.', 'fluent-cart')
714 ];
715 }
716
717 //($index === 0 || !empty($index)) && isset($existingItemsArray[$index])
718 //inline check will not work
719
720 $isValidIndex = false;
721 if ($index != -1) {
722 $isValidIndex = true;
723 }
724
725 if ($isValidIndex && isset($existingItemsArray[$index])) {
726
727 return static::updateItemQuantityInCart(
728 $productVariation,
729 $existingItemsArray,
730 $index,
731 $incrementBy,
732 $isFilteredItem,
733 );
734 }
735
736 return static::addItemInCart(
737 $productVariation,
738 $existingItemsArray,
739 $index,
740 $incrementBy,
741 $isFilteredItem,
742 );
743 }
744
745
746 private static function getCartSingleItemPreparedArray($params = []): array
747 {
748
749 $variation = Arr::get($params, 'variation');
750 $quantity = Arr::get($params, 'quantity');
751 return CartHelper::generateCartItemFromVariation($variation, $quantity);
752
753 }
754
755 /**
756 * Check if cart exists
757 */
758
759 public static function getOrSetCartForThisDevice($autoCreate = false)
760 {
761
762 $cartHash = Cookie::getCartHash();
763
764 if ($cartHash) {
765 $cart = static::getQuery()
766 ->where('stage', '!=', 'completed')
767 ->where('cart_hash', $cartHash)
768 ->where('cart_group', 'global')
769 ->first();
770
771 if ($cart) {
772 return $cart;
773 }
774 }
775
776 $userId = get_current_user_id();
777 if ($userId) {
778 // Latest cart first — without an order, first() picks by primary key
779 // (cart_hash), which resurrects an arbitrary old cart for the user.
780 $cart = static::getQuery()
781 ->where('user_id', $userId)
782 ->where('stage', '!=', 'completed')
783 ->where('cart_group', 'global')
784 ->orderBy('updated_at', 'DESC')
785 ->first();
786
787 if ($cart) {
788 return $cart;
789 }
790 }
791
792 if (!$autoCreate) {
793 return null;
794 }
795
796 $cart = new Cart();
797 $cart->cart_data = [];
798
799 $cart = CartHelper::addCommonCartData($cart);
800
801 $cart->save();
802
803 Cookie::setCartHash($cart->cart_hash);
804
805 return $cart;
806 }
807
808 /**
809 * This method should be called only if no cart is found in a current device
810 */
811 private static function setupNewCart()
812 {
813 $cartArray['cart_data'] = [];
814 if ($userId = get_current_user_id()) {
815 $cartArray['user_id'] = $userId;
816 }
817 $cartArray['cart_group'] = 'global';
818 return Cart::query()->create($cartArray);
819
820 }
821
822 public static function resetCartData()
823 {
824 $cart = CartResource::get();
825
826 if (is_array($cart->cart_data) && !empty($cart->cart_data)) {
827 $cart->cart_data = [];
828 $cart->save();
829 }
830 }
831 }
832