From e927a04f6325f9f22d5e359a2d3b1f3b3079e911 Mon Sep 17 00:00:00 2001 From: devansh bawari Date: Fri, 2 Jul 2021 14:08:57 +0530 Subject: [PATCH 1/6] Removed Query Builder From Cart. As It Is Already Eager Loaded. --- .../Webkul/CartRule/src/Helpers/CartRule.php | 4 +- packages/Webkul/Checkout/src/Cart.php | 13 +- .../Webkul/Product/src/Models/Product.php | 124 ++++++++++-------- 3 files changed, 74 insertions(+), 67 deletions(-) diff --git a/packages/Webkul/CartRule/src/Helpers/CartRule.php b/packages/Webkul/CartRule/src/Helpers/CartRule.php index 35b3e81aa..64b0654a5 100644 --- a/packages/Webkul/CartRule/src/Helpers/CartRule.php +++ b/packages/Webkul/CartRule/src/Helpers/CartRule.php @@ -106,9 +106,9 @@ class CartRule $cart = Cart::getCart(); $appliedCartRuleIds = []; - $this->calculateCartItemTotals($cart->items()->get()); + $this->calculateCartItemTotals($cart->items); - foreach ($cart->items()->get() as $item) { + foreach ($cart->items as $item) { $itemCartRuleIds = $this->process($item); $appliedCartRuleIds = array_merge($appliedCartRuleIds, $itemCartRuleIds); diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 5a645047e..f6207a0c4 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -323,7 +323,7 @@ class Cart if ($cartItem = $cart->items()->find($itemId)) { $cartItem->delete(); - if ($cart->items()->get()->count() == 0) { + if ($cart->items->count() == 0) { $this->cartRepository->delete($cart->id); if (session()->has('cart')) { @@ -412,8 +412,7 @@ class Cart 'customer_id' => $this->getCurrentCustomer()->user()->id, 'is_active' => 1, ]); - - } elseif (session()->has('cart')) { + } else if (session()->has('cart')) { $cart = $this->cartRepository->find(session()->get('cart')->id); } @@ -547,7 +546,7 @@ class Cart $cart->tax_total = $cart->base_tax_total = 0; $cart->discount_amount = $cart->base_discount_amount = 0; - foreach ($cart->items()->get() as $item) { + foreach ($cart->items as $item) { $cart->discount_amount += $item->discount_amount; $cart->base_discount_amount += $item->base_discount_amount; @@ -646,7 +645,7 @@ class Cart Event::dispatch('checkout.cart.calculate.items.tax.before', $cart); - foreach ($cart->items()->get() as $item) { + foreach ($cart->items as $item) { $taxCategory = $this->taxCategoryRepository->find($item->product->tax_category_id); if (! $taxCategory) { @@ -768,7 +767,7 @@ class Cart $this->cartItemRepository->delete($item->id); - if ($cart->items()->get()->count() == 0) { + if ($cart->items->count() == 0) { $this->cartRepository->delete($cart->id); if (session()->has('cart')) { @@ -992,7 +991,7 @@ class Cart $result = $this->cartItemRepository->delete($itemId); - if (! $cart->items()->count()) { + if (! $cart->items->count()) { $this->cartRepository->delete($cart->id); } diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index 537024f5d..30c5ffef4 100755 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -3,15 +3,15 @@ namespace Webkul\Product\Models; use Exception; -use Webkul\Product\Type\AbstractType; use Illuminate\Database\Eloquent\Model; -use Webkul\Category\Models\CategoryProxy; -use Webkul\Attribute\Models\AttributeProxy; -use Webkul\Product\Database\Eloquent\Builder; use Webkul\Attribute\Models\AttributeFamilyProxy; -use Webkul\Inventory\Models\InventorySourceProxy; +use Webkul\Attribute\Models\AttributeProxy; use Webkul\Attribute\Repositories\AttributeRepository; +use Webkul\Category\Models\CategoryProxy; +use Webkul\Inventory\Models\InventorySourceProxy; use Webkul\Product\Contracts\Product as ProductContract; +use Webkul\Product\Database\Eloquent\Builder; +use Webkul\Product\Type\AbstractType; class Product extends Model implements ProductContract { @@ -245,8 +245,9 @@ class Product extends Model implements ProductContract } /** - * @param integer $qty + * Get inventory source quantity. * + * @param integer $qty * @return bool */ public function inventory_source_qty($inventorySourceId) @@ -257,7 +258,7 @@ class Product extends Model implements ProductContract } /** - * Retrieve type instance + * Get type instance. * * @return AbstractType */ @@ -281,8 +282,9 @@ class Product extends Model implements ProductContract } /** - * @param string $key + * Is saleable. * + * @param string $key * @return bool */ public function isSaleable() @@ -291,6 +293,8 @@ class Product extends Model implements ProductContract } /** + * Total quantity. + * * @return integer */ public function totalQuantity() @@ -299,8 +303,9 @@ class Product extends Model implements ProductContract } /** - * @param int $qty + * Have sufficient quantity. * + * @param int $qty * @return bool */ public function haveSufficientQuantity(int $qty): bool @@ -309,6 +314,8 @@ class Product extends Model implements ProductContract } /** + * Is stockable. + * * @return bool */ public function isStockable() @@ -316,24 +323,10 @@ class Product extends Model implements ProductContract return $this->getTypeInstance()->isStockable(); } - /** - * Retrieve product attributes - * - * @param Group $group - * @param bool $skipSuperAttribute - * - * @return Collection - */ - public function getEditableAttributes($group = null, $skipSuperAttribute = true) - { - return $this->getTypeInstance()->getEditableAttributes($group, $skipSuperAttribute); - } - /** * Get an attribute from the model. * * @param string $key - * * @return mixed */ public function getAttribute($key) @@ -358,44 +351,16 @@ class Product extends Model implements ProductContract } /** - * Check in loaded family attributes. + * Retrieve product attributes. * - * @return object + * @param Group $group + * @param bool $skipSuperAttribute + * + * @return Collection */ - public function checkInLoadedFamilyAttributes() + public function getEditableAttributes($group = null, $skipSuperAttribute = true) { - static $loadedFamilyAttributes = []; - - if (array_key_exists($this->attribute_family_id, $loadedFamilyAttributes)) { - return $loadedFamilyAttributes[$this->attribute_family_id]; - } - - return $loadedFamilyAttributes[$this->attribute_family_id] = core()->getSingletonInstance(AttributeRepository::class) - ->getFamilyAttributes($this->attribute_family); - } - - /** - * @return array - */ - public function attributesToArray() - { - $attributes = parent::attributesToArray(); - - $hiddenAttributes = $this->getHidden(); - - if (isset($this->id)) { - $familyAttributes = $this->checkInLoadedFamilyAttributes(); - - foreach ($familyAttributes as $attribute) { - if (in_array($attribute->code, $hiddenAttributes)) { - continue; - } - - $attributes[$attribute->code] = $this->getCustomAttributeValue($attribute); - } - } - - return $attributes; + return $this->getTypeInstance()->getEditableAttributes($group, $skipSuperAttribute); } /** @@ -429,6 +394,32 @@ class Product extends Model implements ProductContract return $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null; } + /** + * Attributes to array. + * + * @return array + */ + public function attributesToArray() + { + $attributes = parent::attributesToArray(); + + $hiddenAttributes = $this->getHidden(); + + if (isset($this->id)) { + $familyAttributes = $this->checkInLoadedFamilyAttributes(); + + foreach ($familyAttributes as $attribute) { + if (in_array($attribute->code, $hiddenAttributes)) { + continue; + } + + $attributes[$attribute->code] = $this->getCustomAttributeValue($attribute); + } + } + + return $attributes; + } + /** * Overrides the default Eloquent query builder. * @@ -455,4 +446,21 @@ class Product extends Model implements ProductContract { return $this; } + + /** + * Check in loaded family attributes. + * + * @return object + */ + public function checkInLoadedFamilyAttributes() + { + static $loadedFamilyAttributes = []; + + if (array_key_exists($this->attribute_family_id, $loadedFamilyAttributes)) { + return $loadedFamilyAttributes[$this->attribute_family_id]; + } + + return $loadedFamilyAttributes[$this->attribute_family_id] = core()->getSingletonInstance(AttributeRepository::class) + ->getFamilyAttributes($this->attribute_family); + } } From 0a44367a8e4b7dbe064628bb94cce1b342c310c5 Mon Sep 17 00:00:00 2001 From: devansh bawari Date: Tue, 20 Jul 2021 13:17:06 +0530 Subject: [PATCH 2/6] Custom Attribute Values Hold --- packages/Webkul/Product/src/Models/Product.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index 30c5ffef4..1a0653961 100755 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -370,6 +370,8 @@ class Product extends Model implements ProductContract */ public function getCustomAttributeValue($attribute) { + static $loadedAttributeValue = []; + if (! $attribute) { return; } @@ -377,6 +379,10 @@ class Product extends Model implements ProductContract $locale = core()->checkRequestedLocaleCodeInRequestedChannel(); $channel = core()->getRequestedChannelCode(); + if (array_key_exists($this->id, $loadedAttributeValue)) { + return $loadedAttributeValue[$this->id]; + } + if ($attribute->value_per_channel) { if ($attribute->value_per_locale) { $attributeValue = $this->attribute_values()->where('channel', $channel)->where('locale', $locale)->where('attribute_id', $attribute->id)->first(); @@ -391,7 +397,7 @@ class Product extends Model implements ProductContract } } - return $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null; + return $loadedAttributeValue[$this->id] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null; } /** From a15ac863198147e02b1cae1eee6436e0eb61f4f0 Mon Sep 17 00:00:00 2001 From: devansh bawari Date: Tue, 20 Jul 2021 13:30:13 +0530 Subject: [PATCH 3/6] Adjusted Some Attributes --- packages/Webkul/Product/src/Models/Product.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index 1a0653961..a5e2211b4 100755 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -372,15 +372,18 @@ class Product extends Model implements ProductContract { static $loadedAttributeValue = []; - if (! $attribute) { + if (!$attribute) { return; } $locale = core()->checkRequestedLocaleCodeInRequestedChannel(); $channel = core()->getRequestedChannelCode(); - if (array_key_exists($this->id, $loadedAttributeValue)) { - return $loadedAttributeValue[$this->id]; + if ( + array_key_exists($this->id, $loadedAttributeValue) + && array_key_exists($attribute->id, $loadedAttributeValue[$this->id]) + ) { + return $loadedAttributeValue[$this->id][$attribute->id]; } if ($attribute->value_per_channel) { @@ -397,7 +400,7 @@ class Product extends Model implements ProductContract } } - return $loadedAttributeValue[$this->id] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null; + return $loadedAttributeValue[$this->id][$attribute->id] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null; } /** From 643384eade6ebf2948ec3e206631c7166e012a9c Mon Sep 17 00:00:00 2001 From: devansh bawari Date: Tue, 20 Jul 2021 14:54:22 +0530 Subject: [PATCH 4/6] Refresh Method Added --- .../Webkul/Product/src/Models/Product.php | 29 ++++++++++++++----- tests/unit/Checkout/Cart/CartCest.php | 6 ++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index a5e2211b4..220a5a15c 100755 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -43,6 +43,13 @@ class Product extends Model implements ProductContract */ protected $typeInstance; + /** + * Loaded attribute values. + * + * @var $loadedAttributeValues + */ + public static $loadedAttributeValues = []; + /** * The "booted" method of the model. * @@ -65,6 +72,16 @@ class Product extends Model implements ProductContract }); } + /** + * Refresh the loaded attribute values. + * + * @return void + */ + public function refreshloadedAttributeValues() + { + self::$loadedAttributeValues = []; + } + /** * Get the product attribute family that owns the product. */ @@ -370,9 +387,7 @@ class Product extends Model implements ProductContract */ public function getCustomAttributeValue($attribute) { - static $loadedAttributeValue = []; - - if (!$attribute) { + if (! $attribute) { return; } @@ -380,10 +395,10 @@ class Product extends Model implements ProductContract $channel = core()->getRequestedChannelCode(); if ( - array_key_exists($this->id, $loadedAttributeValue) - && array_key_exists($attribute->id, $loadedAttributeValue[$this->id]) + array_key_exists($this->id, self::$loadedAttributeValues) + && array_key_exists($attribute->id, self::$loadedAttributeValues[$this->id]) ) { - return $loadedAttributeValue[$this->id][$attribute->id]; + return self::$loadedAttributeValues[$this->id][$attribute->id]; } if ($attribute->value_per_channel) { @@ -400,7 +415,7 @@ class Product extends Model implements ProductContract } } - return $loadedAttributeValue[$this->id][$attribute->id] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null; + return self::$loadedAttributeValues[$this->id][$attribute->id] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null; } /** diff --git a/tests/unit/Checkout/Cart/CartCest.php b/tests/unit/Checkout/Cart/CartCest.php index 0baad7700..dc53dc3cf 100644 --- a/tests/unit/Checkout/Cart/CartCest.php +++ b/tests/unit/Checkout/Cart/CartCest.php @@ -80,6 +80,8 @@ class CartCest ]) ->update(['boolean_value' => 0]); + $this->simpleProduct2->refreshloadedAttributeValues(); + Event::dispatch('catalog.product.update.after', $this->simpleProduct2->refresh()); $I->assertFalse(cart()->hasError()); @@ -107,6 +109,8 @@ class CartCest ]) ->update(['boolean_value' => 0]); + $this->simpleProduct2->refreshloadedAttributeValues(); + Event::dispatch('catalog.product.update.after', $this->downloadableProduct2->refresh()); $I->comment('add dP1 to cart, dP2 should be removed now'); @@ -128,6 +132,8 @@ class CartCest ]) ->update(['boolean_value' => 0]); + $this->simpleProduct2->refreshloadedAttributeValues(); + Event::dispatch('catalog.product.update.after', $this->virtualProduct2->refresh()); $I->comment('change quantity of vP1, vP2 should be removed now'); From a8ab1e3aa3257d87c1eb0665926c160f167c2a85 Mon Sep 17 00:00:00 2001 From: devansh bawari Date: Tue, 20 Jul 2021 15:05:32 +0530 Subject: [PATCH 5/6] Refresh Loaded Attribute Test Case Added --- tests/unit/Core/Commands/BookingCronCest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit/Core/Commands/BookingCronCest.php b/tests/unit/Core/Commands/BookingCronCest.php index 455fcf2ec..2112a55df 100644 --- a/tests/unit/Core/Commands/BookingCronCest.php +++ b/tests/unit/Core/Commands/BookingCronCest.php @@ -36,6 +36,7 @@ class BookingCronCest ['booking_product_id' => $bookingProducts[$i]->id]); $products[$i]->refresh(); + $products[$i]->refreshloadedAttributeValues(); $I->assertNotFalse($products[$i]->status); } @@ -43,6 +44,7 @@ class BookingCronCest for ($i=0; $i<$index; $i++) { $products[$i]->refresh(); + $products[$i]->refreshloadedAttributeValues(); if ($bookingProducts[$i]->available_to < Carbon::now()) { $I->assertEquals(0, $products[$i]->status); From 9999c7d5166f9218e26b75b36f88d00203c42264 Mon Sep 17 00:00:00 2001 From: devansh bawari Date: Tue, 20 Jul 2021 15:25:31 +0530 Subject: [PATCH 6/6] Loaded Cart Item Added --- packages/Webkul/Checkout/src/Cart.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index f6207a0c4..93dddb541 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -1084,7 +1084,13 @@ class Cart * @return bool */ private function isCartItemInactive(\Webkul\Checkout\Contracts\CartItem $item): bool { - return $item->product->getTypeInstance()->isCartItemInactive($item); + static $loadedCartItem = []; + + if (array_key_exists($item->product_id, $loadedCartItem)) { + return $loadedCartItem[$item->product_id]; + } + + return $loadedCartItem[$item->product_id] = $item->product->getTypeInstance()->isCartItemInactive($item); } /**