Squashed All Unecessary Commits And Done All changes

This commit is contained in:
devansh bawari 2021-01-06 17:03:52 +05:30
parent 445d116fc0
commit 6ddcb160b5
28 changed files with 524 additions and 398 deletions

View File

@ -3,15 +3,15 @@
namespace Webkul\CartRule\Helpers;
use Carbon\Carbon;
use Webkul\Checkout\Facades\Cart;
use Webkul\Rule\Helpers\Validator;
use Webkul\Checkout\Models\CartItem;
use Illuminate\Database\Eloquent\Builder;
use Webkul\CartRule\Repositories\CartRuleRepository;
use Webkul\CartRule\Repositories\CartRuleCouponRepository;
use Webkul\CartRule\Repositories\CartRuleCouponUsageRepository;
use Webkul\CartRule\Repositories\CartRuleCustomerRepository;
use Webkul\Customer\Repositories\CustomerGroupRepository;
use Webkul\Checkout\Models\CartItem;
use Webkul\Rule\Helpers\Validator;
use Webkul\Checkout\Facades\Cart;
use Webkul\CartRule\Repositories\CartRuleCouponRepository;
use Webkul\CartRule\Repositories\CartRuleCustomerRepository;
use Webkul\CartRule\Repositories\CartRuleCouponUsageRepository;
class CartRule
{
@ -153,7 +153,9 @@ class CartRule
if (Cart::getCurrentCustomer()->check()) {
$customerGroupId = Cart::getCurrentCustomer()->user()->customer_group_id;
} else {
if ($customerGuestGroup = $this->customerGroupRepository->findOneByField('code', 'guest')) {
$customerGuestGroup = $this->customerGroupRepository->getCustomerGuestGroup();
if ($customerGuestGroup) {
$customerGroupId = $customerGuestGroup->id;
}
}

View File

@ -3,8 +3,8 @@
namespace Webkul\CatalogRule\Helpers;
use Carbon\Carbon;
use Webkul\CatalogRule\Repositories\CatalogRuleProductPriceRepository;
use Webkul\Customer\Repositories\CustomerGroupRepository;
use Webkul\CatalogRule\Repositories\CatalogRuleProductPriceRepository;
class CatalogRuleProductPrice
{
@ -161,7 +161,7 @@ class CatalogRuleProductPrice
case 'by_fixed':
$price = max(0, $price - $rule->discount_amount);
break;
case 'by_percent':
@ -191,7 +191,7 @@ class CatalogRuleProductPrice
}
/**
* Get catalog rules product price for specific date, channel and customer group
* Get catalog rules product price for specific date, channel and customer group.
*
* @param \Webkul\Product\Contracts\Product $product
* @return array|void
@ -201,7 +201,7 @@ class CatalogRuleProductPrice
if ($this->getCurrentCustomer()->check()) {
$customerGroupId = $this->getCurrentCustomer()->user()->customer_group_id;
} else {
$customerGroup = $this->customerGroupRepository->findOneByField('code', 'guest');
$customerGroup = $this->customerGroupRepository->getCustomerGuestGroup();
if (! $customerGroup) {
return;
@ -210,11 +210,6 @@ class CatalogRuleProductPrice
$customerGroupId = $customerGroup->id;
}
return $this->catalogRuleProductPriceRepository->findOneWhere([
'product_id' => $product->id,
'channel_id' => core()->getCurrentChannel()->id,
'customer_group_id' => $customerGroupId,
'rule_date' => Carbon::now()->format('Y-m-d'),
]);
return $this->catalogRuleProductPriceRepository->checkInLoadedCatalogRulePrice($product, $customerGroupId);
}
}

View File

@ -2,12 +2,13 @@
namespace Webkul\CatalogRule\Repositories;
use Illuminate\Support\Carbon;
use Webkul\Core\Eloquent\Repository;
class CatalogRuleProductPriceRepository extends Repository
{
/**
* Specify Model class name
* Specify Model class name.
*
* @return mixed
*/
@ -15,4 +16,25 @@ class CatalogRuleProductPriceRepository extends Repository
{
return 'Webkul\CatalogRule\Contracts\CatalogRuleProductPrice';
}
/**
* Check if catalog rule prices already loaded. If already loaded then load from it.
*
* @return object
*/
public function checkInLoadedCatalogRulePrice($product, $customerGroupId)
{
static $catalogRulePrices = [];
if (array_key_exists($product->id, $catalogRulePrices)) {
return $catalogRulePrices[$product->id];
}
return $catalogRulePrices[$product->id] = $this->findOneWhere([
'product_id' => $product->id,
'channel_id' => core()->getCurrentChannel()->id,
'customer_group_id' => $customerGroupId,
'rule_date' => Carbon::now()->format('Y-m-d'),
]);
}
}

View File

@ -4,14 +4,14 @@ namespace Webkul\Core;
use Carbon\Carbon;
use Webkul\Core\Models\Channel;
use Webkul\Core\Repositories\CurrencyRepository;
use Webkul\Core\Repositories\ExchangeRateRepository;
use Webkul\Core\Repositories\CountryRepository;
use Webkul\Core\Repositories\CountryStateRepository;
use Webkul\Core\Repositories\ChannelRepository;
use Webkul\Core\Repositories\LocaleRepository;
use Webkul\Core\Repositories\CoreConfigRepository;
use Illuminate\Support\Facades\Config;
use Webkul\Core\Repositories\LocaleRepository;
use Webkul\Core\Repositories\ChannelRepository;
use Webkul\Core\Repositories\CountryRepository;
use Webkul\Core\Repositories\CurrencyRepository;
use Webkul\Core\Repositories\CoreConfigRepository;
use Webkul\Core\Repositories\CountryStateRepository;
use Webkul\Core\Repositories\ExchangeRateRepository;
use Webkul\Customer\Repositories\CustomerGroupRepository;
class Core
@ -72,9 +72,20 @@ class Core
*/
protected $coreConfigRepository;
/** @var Channel */
/**
* @var \Webkul\Core\Models\Channel
*/
private static $channel;
/**
* Register your core config keys here which you don't want to
* load in static array. These keys will load from database
* everytime the `getConfigData` method is called.
*/
private $coreConfigExceptions = [
'catalog.products.guest-checkout.allow-guest-checkout'
];
/**
* Create a new instance.
*
@ -118,7 +129,7 @@ class Core
}
/**
* Returns all channels
* Returns all channels.
*
* @return \Illuminate\Support\Collection
*/
@ -134,7 +145,7 @@ class Core
}
/**
* Returns currenct channel models
* Returns currenct channel models.
*
* @return \Webkul\Core\Contracts\Channel
*/
@ -158,7 +169,7 @@ class Core
}
/**
* Set the current channel
* Set the current channel.
*
* @param Channel $channel
*/
@ -168,7 +179,7 @@ class Core
}
/**
* Returns currenct channel code
* Returns currenct channel code.
*
* @return \Webkul\Core\Contracts\Channel
*/
@ -184,7 +195,7 @@ class Core
}
/**
* Returns default channel models
* Returns default channel models.
*
* @return \Webkul\Core\Contracts\Channel
*/
@ -206,7 +217,7 @@ class Core
}
/**
* Returns the default channel code configured in config/app.php
* Returns the default channel code configured in `config/app.php`.
*
* @return string
*/
@ -222,7 +233,7 @@ class Core
}
/**
* Returns all locales
* Returns all locales.
*
* @return \Illuminate\Support\Collection
*/
@ -238,7 +249,7 @@ class Core
}
/**
* Returns current locale
* Returns current locale.
*
* @return \Webkul\Core\Contracts\Locale
*/
@ -260,7 +271,7 @@ class Core
}
/**
* Returns all Customer Groups
* Returns all customer groups.
*
* @return \Illuminate\Support\Collection
*/
@ -276,7 +287,7 @@ class Core
}
/**
* Returns all currencies
* Returns all currencies.
*
* @return \Illuminate\Support\Collection
*/
@ -292,7 +303,7 @@ class Core
}
/**
* Returns base channel's currency model
* Returns base channel's currency model.
*
* @return \Webkul\Core\Contracts\Currency
*/
@ -314,7 +325,7 @@ class Core
}
/**
* Returns base channel's currency code
* Returns base channel's currency code.
*
* @return string
*/
@ -330,7 +341,7 @@ class Core
}
/**
* Returns base channel's currency model
* Returns base channel's currency model.
*
* @return \Webkul\Core\Contracts\Currency
*/
@ -348,7 +359,7 @@ class Core
}
/**
* Returns base channel's currency code
* Returns base channel's currency code.
*
* @return string
*/
@ -364,7 +375,7 @@ class Core
}
/**
* Returns current channel's currency model
* Returns current channel's currency model.
*
* @return \Webkul\Core\Contracts\Currency
*/
@ -386,7 +397,7 @@ class Core
}
/**
* Returns current channel's currency code
* Returns current channel's currency code.
*
* @return string
*/
@ -402,7 +413,27 @@ class Core
}
/**
* Converts price
* Returns exchange rates.
*
* @return object
*/
public function getExchangeRate($targetCurrencyId)
{
static $exchangeRate;
if ($exchangeRate || $exchangeRate === '') {
return $exchangeRate;
}
$found = $this->exchangeRateRepository->findOneWhere([
'target_currency' => $targetCurrencyId,
]);
return $exchangeRate = ($found ? $found : '');
}
/**
* Converts price.
*
* @param float $amount
* @param string $targetCurrencyCode
@ -438,11 +469,9 @@ class Core
return $amount;
}
$exchangeRate = $this->exchangeRateRepository->findOneWhere([
'target_currency' => $targetCurrency->id,
]);
$exchangeRate = $this->getExchangeRate($targetCurrency->id);
if (null === $exchangeRate || ! $exchangeRate->rate) {
if ('' === $exchangeRate || null === $exchangeRate || ! $exchangeRate->rate) {
return $amount;
}
@ -456,7 +485,7 @@ class Core
}
/**
* Converts to base price
* Converts to base price.
*
* @param float $amount
* @param string $targetCurrencyCode
@ -485,7 +514,7 @@ class Core
}
/**
* Format and convert price with currency symbol
* Format and convert price with currency symbol.
*
* @param float $price
*
@ -501,7 +530,7 @@ class Core
}
/**
* Return currency symbol from currency code
* Return currency symbol from currency code.
*
* @param float $price
*
@ -515,7 +544,7 @@ class Core
}
/**
* Format and convert price with currency symbol
* Format and convert price with currency symbol.
*
* @param float $price
*
@ -532,7 +561,7 @@ class Core
}
/**
* Format and convert price with currency symbol
* Format and convert price with currency symbol.
*
* @return array
*/
@ -547,14 +576,14 @@ class Core
$pattern = str_replace("#,##0.00", "%v", $pattern);
return [
'symbol' => core()->currencySymbol(core()->getCurrentCurrencyCode()),
'symbol' => $this->currencySymbol($this->getCurrentCurrencyCode()),
'decimal' => $formater->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL),
'format' => $pattern,
];
}
/**
* Format price with base currency symbol
* Format price with base currency symbol.
*
* @param float $price
*
@ -582,7 +611,7 @@ class Core
}
/**
* Checks if current date of the given channel (in the channel timezone) is within the range
* Checks if current date of the given channel (in the channel timezone) is within the range.
*
* @param int|string|\Webkul\Core\Contracts\Channel $channel
* @param string|null $dateFrom
@ -616,7 +645,7 @@ class Core
}
/**
* Get channel timestamp, timstamp will be builded with channel timezone settings
* Get channel timestamp, timstamp will be builded with channel timezone settings.
*
* @param \Webkul\Core\Contracts\Channel $channel
*
@ -638,7 +667,7 @@ class Core
}
/**
* Check whether sql date is empty
* Check whether sql date is empty.
*
* @param string $date
*
@ -671,7 +700,7 @@ class Core
}
/**
* Retrieve information from payment configuration
* Retrieve information from payment configuration.
*
* @param string $field
* @param int|string|null $channelId
@ -681,51 +710,20 @@ class Core
*/
public function getConfigData($field, $channel = null, $locale = null)
{
if (null === $channel) {
$channel = request()->get('channel') ?: ($this->getCurrentChannelCode() ?: $this->getDefaultChannelCode());
}
static $loadedConfigs = [];
if (null === $locale) {
$locale = request()->get('locale') ?: app()->getLocale();
}
$fields = $this->getConfigField($field);
$channel_based = false;
$locale_based = false;
if (isset($fields['channel_based']) && $fields['channel_based']) {
$channel_based = true;
}
if (isset($fields['locale_based']) && $fields['locale_based']) {
$locale_based = true;
}
if (isset($fields['channel_based']) && $fields['channel_based']) {
if (isset($fields['locale_based']) && $fields['locale_based']) {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
'channel_code' => $channel,
'locale_code' => $locale,
]);
} else {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
'channel_code' => $channel,
]);
}
if (array_key_exists($field, $loadedConfigs) && ! in_array($field, $this->coreConfigExceptions)) {
$coreConfigValue = $loadedConfigs[$field];
} else {
if (isset($fields['locale_based']) && $fields['locale_based']) {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
'locale_code' => $locale,
]);
} else {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
]);
if (null === $channel) {
$channel = request()->get('channel') ?: ($this->getCurrentChannelCode() ?: $this->getDefaultChannelCode());
}
if (null === $locale) {
$locale = request()->get('locale') ?: app()->getLocale();
}
$loadedConfigs[$field] = $coreConfigValue = $this->getCoreConfigValue($field, $channel, $locale);
}
if (! $coreConfigValue) {
@ -742,7 +740,7 @@ class Core
}
/**
* Retrieve a group of information from the core config table
* Retrieve a group of information from the core config table.
*
* @param mixed $criteria
*
@ -754,7 +752,7 @@ class Core
}
/**
* Retrieve all countries
* Retrieve all countries.
*
* @return \Illuminate\Support\Collection
*/
@ -764,7 +762,7 @@ class Core
}
/**
* Returns country name by code
* Returns country name by code.
*
* @param string $code
*
@ -778,7 +776,7 @@ class Core
}
/**
* Retrieve all country states
* Retrieve all country states.
*
* @param string $countryCode
*
@ -790,7 +788,7 @@ class Core
}
/**
* Retrieve all grouped states by country code
* Retrieve all grouped states by country code.
*
* @return \Illuminate\Support\Collection
*/
@ -806,7 +804,7 @@ class Core
}
/**
* Retrieve all grouped states by country code
* Retrieve all grouped states by country code.
*
* @return \Illuminate\Support\Collection
*/
@ -824,7 +822,7 @@ class Core
}
/**
* Returns time intervals
* Returns time intervals.
*
* @param \Illuminate\Support\Carbon $startDate
* @param \Illuminate\Support\Carbon $endDate
@ -884,7 +882,6 @@ class Core
}
/**
*
* @param string $date
* @param int $day
*
@ -906,7 +903,7 @@ class Core
}
/**
* Method to sort through the acl items and put them in order
* Method to sort through the acl items and put them in order.
*
* @param array $items
*
@ -1022,6 +1019,86 @@ class Core
return $array;
}
/**
* @param array $array1
*
* @return array
*/
public function convertEmptyStringsToNull($array)
{
foreach ($array as $key => $value) {
if ($value == "" || $value == "null") {
$array[$key] = null;
}
}
return $array;
}
/**
* Create singleton object through single facade.
*
* @param string $className
*
* @return object
*/
public function getSingletonInstance($className)
{
static $instance = [];
if (array_key_exists($className, $instance)) {
return $instance[$className];
}
return $instance[$className] = app($className);
}
/**
* Returns a string as selector part for identifying elements in views.
*
* @param float $taxRate
*
* @return string
*/
public static function taxRateAsIdentifier(float $taxRate): string
{
return str_replace('.', '_', (string)$taxRate);
}
/**
* Get Shop email sender details.
*
* @return array
*/
public function getSenderEmailDetails()
{
$sender_name = $this->getConfigData('general.general.email_settings.sender_name') ? $this->getConfigData('general.general.email_settings.sender_name') : config('mail.from.name');
$sender_email = $this->getConfigData('general.general.email_settings.shop_email_from') ? $this->getConfigData('general.general.email_settings.shop_email_from') : config('mail.from.address');
return [
'name' => $sender_name,
'email' => $sender_email,
];
}
/**
* Get Admin email details.
*
* @return array
*/
public function getAdminEmailDetails()
{
$admin_name = $this->getConfigData('general.general.email_settings.admin_name') ? $this->getConfigData('general.general.email_settings.admin_name') : config('mail.admin.name');
$admin_email = $this->getConfigData('general.general.email_settings.admin_email') ? $this->getConfigData('general.general.email_settings.admin_email') : config('mail.admin.address');
return [
'name' => $admin_name,
'email' => $admin_email,
];
}
/**
* @param array $array1
* @param array $array2
@ -1044,82 +1121,38 @@ class Core
}
/**
* @param array $array1
*
* @return array
* Get core config values.
*/
public function convertEmptyStringsToNull($array)
protected function getCoreConfigValue($field, $channel, $locale)
{
foreach ($array as $key => $value) {
if ($value == "" || $value == "null") {
$array[$key] = null;
$fields = $this->getConfigField($field);
if (isset($fields['channel_based']) && $fields['channel_based']) {
if (isset($fields['locale_based']) && $fields['locale_based']) {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
'channel_code' => $channel,
'locale_code' => $locale,
]);
} else {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
'channel_code' => $channel,
]);
}
} else {
if (isset($fields['locale_based']) && $fields['locale_based']) {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
'locale_code' => $locale,
]);
} else {
$coreConfigValue = $this->coreConfigRepository->findOneWhere([
'code' => $field,
]);
}
}
return $array;
}
/**
* Create singletom object through single facade
*
* @param string $className
*
* @return object
*/
public function getSingletonInstance($className)
{
static $instance = [];
if (array_key_exists($className, $instance)) {
return $instance[$className];
}
return $instance[$className] = app($className);
}
/**
* Returns a string as selector part for identifying elements in views
*
* @param float $taxRate
*
* @return string
*/
public static function taxRateAsIdentifier(float $taxRate): string
{
return str_replace('.', '_', (string)$taxRate);
}
/**
* Get Shop email sender details
*
* @return array
*/
public function getSenderEmailDetails()
{
$sender_name = core()->getConfigData('general.general.email_settings.sender_name') ? core()->getConfigData('general.general.email_settings.sender_name') : config('mail.from.name');
$sender_email = core()->getConfigData('general.general.email_settings.shop_email_from') ? core()->getConfigData('general.general.email_settings.shop_email_from') : config('mail.from.address');
return [
'name' => $sender_name,
'email' => $sender_email,
];
}
/**
* Get Admin email details
*
* @return array
*/
public function getAdminEmailDetails()
{
$admin_name = core()->getConfigData('general.general.email_settings.admin_name') ? core()->getConfigData('general.general.email_settings.admin_name') : config('mail.admin.name');
$admin_email = core()->getConfigData('general.general.email_settings.admin_email') ? core()->getConfigData('general.general.email_settings.admin_email') : config('mail.admin.address');
return [
'name' => $admin_name,
'email' => $admin_email,
];
return $coreConfigValue;
}
}

View File

@ -7,6 +7,7 @@ use Webkul\Category\Models\CategoryProxy;
use Webkul\Core\Eloquent\TranslatableModel;
use Webkul\Inventory\Models\InventorySourceProxy;
use Webkul\Core\Contracts\Channel as ChannelContract;
use Webkul\Product\Models\ProductOrderedInventoryProxy;
class Channel extends TranslatableModel implements ChannelContract
{

View File

@ -2,28 +2,8 @@
namespace Webkul\Customer\Helpers;
use Webkul\Customer\Repositories\WishlistRepository;
class Wishlist
{
/**
* WishlistRepository object
*
* @var \Webkul\Customer\Repositories\WishlistRepository
*/
protected $wishlistRepository;
/**
* Create a new controller instance.
*
* @param \Webkul\Customer\Repositories\WishlistRepository
* @return void
*/
public function __construct(WishlistRepository $wishlistRepository)
{
$this->wishlistRepository = $wishlistRepository;
}
/**
* Returns wishlist products for current customer.
*
@ -34,12 +14,10 @@ class Wishlist
{
$wishlist = false;
if (auth()->guard('customer')->user()) {
$wishlist = $this->wishlistRepository->findOneWhere([
'channel_id' => core()->getCurrentChannel()->id,
'product_id' => $product->product_id,
'customer_id' => auth()->guard('customer')->user()->id,
]);
if ($customer = auth()->guard('customer')->user()) {
$wishlist = $customer->wishlist_items->filter(function ($item) use ($product) {
return $item->channel_id == core()->getCurrentChannel()->id && $item->product_id == $product->product_id;
})->first();
}
if ($wishlist) {

View File

@ -42,4 +42,20 @@ class CustomerGroupRepository extends Repository
return $customer;
}
/**
* Returns guest group.
*
* @return object
*/
public function getCustomerGuestGroup()
{
static $customerGuestGroup;
if ($customerGuestGroup) {
return $customerGuestGroup;
}
return $customerGuestGroup = $this->findOneByField('code', 'guest');
}
}

View File

@ -15,4 +15,24 @@ class InventorySourceRepository extends Repository
{
return 'Webkul\Inventory\Contracts\InventorySource';
}
/**
* Returns channel inventory source ids.
*
* @return collection
*/
public function getChannelInventorySourceIds()
{
static $channelInventorySourceIds;
if ($channelInventorySourceIds) {
return $channelInventorySourceIds;
}
$found = core()->getCurrentChannel()->inventory_sources()
->where('status', 1)
->pluck('id');
return $channelInventorySourceIds = ($found ? $found : collect([]));
}
}

View File

@ -35,10 +35,16 @@ class ProductImage extends AbstractProduct
*/
public function getGalleryImages($product)
{
static $loadedGalleryImages = [];
if (! $product) {
return [];
}
if (array_key_exists($product->id, $loadedGalleryImages)) {
return $loadedGalleryImages[$product->id];
}
$images = [];
foreach ($product->images as $image) {
@ -63,16 +69,58 @@ class ProductImage extends AbstractProduct
];
}
return $images;
return $loadedGalleryImages[$product->id] = $images;
}
/**
* Get product's base image
* This method will first check whether the gallery images are already
* present or not. If not then it will load from the product.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @param array
* @return array
*/
public function getProductBaseImage($product, array $galleryImages = null)
{
static $loadedBaseImages = [];
if (array_key_exists($product->id, $loadedBaseImages)) {
return $loadedBaseImages[$product->id];
}
return $loadedBaseImages[$product->id] = $galleryImages
? $galleryImages[0]
: $this->otherwiseLoadFromProduct($product);
}
/**
* Get product varient image if available otherwise product base image.
*
* @param \Webkul\Customer\Contracts\Wishlist $item
* @return array
*/
public function getProductImage($item)
{
if ($item instanceof \Webkul\Customer\Contracts\Wishlist) {
if (isset($item->additional['selected_configurable_option'])) {
$product = $this->productRepository->find($item->additional['selected_configurable_option']);
} else {
$product = $item->product;
}
} else {
$product = $item->product;
}
return $this->getProductBaseImage($product);
}
/**
* Load product's base image.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @return array
*/
public function getProductBaseImage($product)
protected function otherwiseLoadFromProduct($product)
{
$images = $product ? $product->images : null;
@ -94,25 +142,4 @@ class ProductImage extends AbstractProduct
return $image;
}
/**
* Get product varient image if available otherwise product base image
*
* @param \Webkul\Customer\Contracts\Wishlist $item
* @return array
*/
public function getProductImage($item)
{
if ($item instanceof \Webkul\Customer\Contracts\Wishlist) {
if (isset($item->additional['selected_configurable_option'])) {
$product = $this->productRepository->find($item->additional['selected_configurable_option']);
} else {
$product = $item->product;
}
} else {
$product = $item->product;
}
return $this->getProductBaseImage($product);
}
}

View File

@ -74,6 +74,28 @@ class Review extends AbstractProduct
return $totalRating[$product->id] = $product->reviews()->where('status', 'approved')->sum('rating');
}
/**
* Returns reviews with ratings.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
*
* @return collection
*/
public function getReviewsWithRatings($product)
{
static $reviews = [];
if (array_key_exists($product->id, $reviews)) {
return $reviews[$product->id];
}
return $reviews[$product->id] = $product->reviews()->where('status', 'approved')
->select('rating', DB::raw('count(*) as total'))
->groupBy('rating')
->orderBy('rating', 'desc')
->get();
}
/**
* Returns the Percentage rating of the product
*
@ -82,11 +104,7 @@ class Review extends AbstractProduct
*/
public function getPercentageRating($product)
{
$reviews = $product->reviews()->where('status', 'approved')
->select('rating', DB::raw('count(*) as total'))
->groupBy('rating')
->orderBy('rating', 'desc')
->get();
$reviews = $this->getReviewsWithRatings($product);
$totalReviews = $this->getTotalReviews($product);

View File

@ -12,6 +12,7 @@ use Webkul\Attribute\Models\AttributeFamilyProxy;
use Webkul\Inventory\Models\InventorySourceProxy;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Contracts\Product as ProductContract;
use Webkul\CatalogRule\Models\CatalogRuleProductPriceProxy;
class Product extends Model implements ProductContract
{
@ -338,6 +339,23 @@ class Product extends Model implements ProductContract
return parent::getAttribute($key);
}
/**
* 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);
}
/**
* @return array
*/
@ -348,9 +366,7 @@ class Product extends Model implements ProductContract
$hiddenAttributes = $this->getHidden();
if (isset($this->id)) {
$familyAttributes = core()
->getSingletonInstance(AttributeRepository::class)
->getFamilyAttributes($this->attribute_family);
$familyAttributes = $this->checkInLoadedFamilyAttributes();
foreach ($familyAttributes as $attribute) {
if (in_array($attribute->code, $hiddenAttributes)) {

View File

@ -121,16 +121,14 @@ class ProductFlat extends Model implements ProductFlatContract
*/
public function images()
{
return (ProductImageProxy::modelClass())
::where('product_images.product_id', $this->product_id)
->select('product_images.*');
return $this->hasMany(ProductImageProxy::modelClass(), 'product_id', 'product_id');
}
/**
* The videos that belong to the product.
*/
public function videos()
{
{
return $this->product->videos();
}

View File

@ -2,15 +2,13 @@
namespace Webkul\Product\Repositories;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Http\UploadedFile;
use Webkul\Core\Eloquent\Repository;
class ProductCustomerGroupPriceRepository extends Repository
{
/**
* Specify Model class name
* Specify Model class name.
*
* @return mixed
*/
@ -50,4 +48,22 @@ class ProductCustomerGroupPriceRepository extends Repository
$this->delete($customerGroupPriceId);
}
}
/**
* Check if product customer group prices already loaded then load from it.
*
* @return object
*/
public function checkInLoadedCustomerGroupPrice($product, $customerGroupId)
{
static $customerGroupPrices = [];
if (array_key_exists($product->id, $customerGroupPrices)) {
return $customerGroupPrices[$product->id];
}
return $customerGroupPrices[$product->id] = $product->customer_group_prices->filter(function ($customerGroupPrice) use ($customerGroupId) {
return $customerGroupPrice->customer_group_id == $customerGroupId || is_null($customerGroupPrice->customer_group_id);
});
}
}

View File

@ -19,11 +19,17 @@ class ProductFlatRepository extends Repository
*/
public function getCategoryProductMaximumPrice($category = null)
{
static $loadedCategoryMaxPrice = [];
if (! $category) {
return $this->model->max('max_price');
}
return $this->model
if (array_key_exists($category->id, $loadedCategoryMaxPrice)) {
return $loadedCategoryMaxPrice[$category->id];
}
return $loadedCategoryMaxPrice[$category->id] = $this->model
->leftJoin('product_categories', 'product_flat.product_id', 'product_categories.product_id')
->where('product_categories.category_id', $category->id)
->max('max_price');
@ -84,6 +90,12 @@ class ProductFlatRepository extends Repository
*/
public function getProductsRelatedFilterableAttributes($category)
{
static $loadedCategoryAttributes = [];
if (array_key_exists($category->id, $loadedCategoryAttributes)) {
return $loadedCategoryAttributes[$category->id];
}
$categoryFilterableAttributes = $category->filterableAttributes->pluck('id')->toArray();
$productCategoryArrributes = $this->getCategoryProductAttribute($category->id);
@ -95,7 +107,7 @@ class ProductFlatRepository extends Repository
}
])->whereIn('id', $allFilterableAttributes)->get();
return $attributes;
return $loadedCategoryAttributes[$category->id] = $attributes;
}
/**

View File

@ -2,13 +2,12 @@
namespace Webkul\Product\Repositories;
use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository;
class ProductInventoryRepository extends Repository
{
/**
* Specify Model class name
* Specify Model class name.
*
* @return mixed
*/
@ -49,4 +48,20 @@ class ProductInventoryRepository extends Repository
}
}
}
/**
* Check if product inventories are already loaded. If already loaded then load from it.
*
* @return object
*/
public function checkInLoadedProductInventories($product)
{
static $productInventories = [];
if (array_key_exists($product->id, $productInventories)) {
return $productInventories[$product->id];
}
return $productInventories[$product->id] = $product->inventories;
}
}

View File

@ -12,8 +12,11 @@ use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Datatypes\CartItemValidationResult;
use Webkul\Product\Repositories\ProductImageRepository;
use Webkul\Product\Repositories\ProductVideoRepository;
use Webkul\Customer\Repositories\CustomerGroupRepository;
use Webkul\Inventory\Repositories\InventorySourceRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductCustomerGroupPriceRepository;
abstract class AbstractType
{
@ -285,7 +288,7 @@ abstract class AbstractType
$this->productVideoRepository->uploadVideos($data, $product);
app('Webkul\Product\Repositories\ProductCustomerGroupPriceRepository')->saveCustomerGroupPrices($data,
app(ProductCustomerGroupPriceRepository::class)->saveCustomerGroupPrices($data,
$product);
}
@ -432,20 +435,18 @@ abstract class AbstractType
{
$total = 0;
$channelInventorySourceIds = core()->getCurrentChannel()
->inventory_sources()
->where('status', 1)
->pluck('id');
$channelInventorySourceIds = app(InventorySourceRepository::class)->getChannelInventorySourceIds();
foreach ($this->product->inventories as $inventory) {
if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id))) {
$productInventories = $this->productInventoryRepository->checkInLoadedProductInventories($this->product);
foreach ($productInventories as $inventory) {
if (is_numeric($channelInventorySourceIds->search($inventory->inventory_source_id))) {
$total += $inventory->qty;
}
}
$orderedInventory = $this->product->ordered_inventories()
->where('channel_id', core()->getCurrentChannel()->id)
->first();
->where('channel_id', core()->getCurrentChannel()->id)->first();
if ($orderedInventory) {
$total -= $orderedInventory->qty;
@ -570,7 +571,9 @@ abstract class AbstractType
$rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product);
if ((is_null($this->product->special_price) || ! (float)$this->product->special_price)
$specialPrice = $this->product->special_price;
if ((is_null($specialPrice) || ! (float) $specialPrice)
&& ! $rulePrice
&& $customerGroupPrice == $this->product->price
) {
@ -579,7 +582,7 @@ abstract class AbstractType
$haveSpecialPrice = false;
if (! (float)$this->product->special_price) {
if (! (float) $specialPrice) {
if ($rulePrice && $rulePrice->price < $this->product->price) {
$this->product->special_price = $rulePrice->price;
@ -630,18 +633,14 @@ abstract class AbstractType
if (Cart::getCurrentCustomer()->check()) {
$customerGroupId = Cart::getCurrentCustomer()->user()->customer_group_id;
} else {
$customerGroupRepository = app('Webkul\Customer\Repositories\CustomerGroupRepository');
$customerGuestGroup = app(CustomerGroupRepository::class)->getCustomerGuestGroup();
if ($customerGuestGroup = $customerGroupRepository->findOneByField('code', 'guest')) {
if ($customerGuestGroup) {
$customerGroupId = $customerGuestGroup->id;
}
}
$customerGroupPrices = $product->customer_group_prices()->where(function ($query) use ($customerGroupId) {
$query->where('customer_group_id', $customerGroupId)
->orWhereNull('customer_group_id');
}
)->get();
$customerGroupPrices = app(ProductCustomerGroupPriceRepository::class)->checkInLoadedCustomerGroupPrice($product, $customerGroupId);
if (!$customerGroupPrices->count()) {
return $product->price;
@ -924,4 +923,19 @@ abstract class AbstractType
return false;
}
/**
* Check in loaded saleable.
*
* @return object
*/
public function checkInLoadedSaleableChecks($product, $callback)
{
static $loadedSaleableChecks = [];
if (array_key_exists($product->id, $loadedSaleableChecks)) {
return $loadedSaleableChecks[$product->id];
}
return $loadedSaleableChecks[$product->id] = $callback($product);
}
}

View File

@ -539,7 +539,7 @@ class Configurable extends AbstractType
$product = $item->child->product;
} else {
$product = $item->product;
}
}
}
}

View File

@ -111,7 +111,7 @@ class Grouped extends AbstractType
*/
public function getChildrenIds()
{
return array_unique($this->product->grouped_products()->pluck('associated_product_id')->toArray());
return array_unique($this->product->grouped_products->pluck('associated_product_id')->toArray());
}
/**

View File

@ -5,14 +5,14 @@ namespace Webkul\Product\Type;
class Simple extends AbstractType
{
/**
* Skip attribute for simple product type
* Skip attribute for simple product type.
*
* @var array
*/
protected $skipAttributes = [];
/**
* These blade files will be included in product edit page
* These blade files will be included in product edit page.
*
* @var array
*/
@ -26,33 +26,36 @@ class Simple extends AbstractType
];
/**
* Show quantity box
* Show quantity box.
*
* @var bool
*/
protected $showQuantityBox = true;
/**
* Return true if this product type is saleable
* Return true if this product type is saleable. Saleable check added because
* this is the point where all parent product will recall this.
*
* @return bool
*/
public function isSaleable()
{
if (! $this->product->status) {
return $this->checkInLoadedSaleableChecks($this->product, function ($product) {
if (! $product->status) {
return false;
}
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $product) === false) {
return false;
}
if ($this->haveSufficientQuantity(1)) {
return true;
}
return false;
}
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false) {
return false;
}
if ($this->haveSufficientQuantity(1)) {
return true;
}
return false;
});
}
/**

View File

@ -2,8 +2,8 @@
namespace Webkul\Shop\Http\Middleware;
use Webkul\Core\Repositories\CurrencyRepository;
use Closure;
use Webkul\Core\Repositories\CurrencyRepository;
class Currency
{

View File

@ -68,7 +68,7 @@
@case('addToCartHtml')
<div class="action">
<div v-html="product.defaultAddToCart"></div>
<div v-html="addToCartHtml"></div>
<span class="icon white-cross-sm-icon remove-product" @click="removeProductCompare(product.id)"></span>
</div>

View File

@ -262,7 +262,7 @@
if (imageInput.files[0].type.includes('image/')) {
var self = this;
if (imageInput.files[0].size <= 2000000) {
if (imageInput.files[0].size <= 2000000) {
self.$root.showLoader();
var formData = new FormData();
@ -344,8 +344,8 @@
];
self.$root.addFlashMessages();
}
}
} else {
imageInput.value = '';

View File

@ -2,12 +2,12 @@
@inject ('productVideoHelper', 'Webkul\Product\Helpers\ProductVideo')
@inject ('wishListHelper', 'Webkul\Customer\Helpers\Wishlist')
<?php
$images = $productImageHelper->getGalleryImages($product);
<?php
$images = $productImageHelper->getGalleryImages($product);
$videos = $productVideoHelper->getVideos($product);
$images = array_merge($images, $videos);
$images = array_merge($images, $videos);
?>

View File

@ -8,8 +8,8 @@ use Webkul\Product\Models\Product as ProductModel;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductFlatRepository;
use Webkul\Velocity\Repositories\OrderBrandsRepository;
use Webkul\Attribute\Repositories\AttributeOptionRepository;
use Webkul\Product\Repositories\ProductReviewRepository;
use Webkul\Attribute\Repositories\AttributeOptionRepository;
use Webkul\Velocity\Repositories\VelocityMetadataRepository;
class Helper extends Review
@ -173,49 +173,18 @@ class Helper extends Review
}
/**
* Returns the count rating of the product
*
* @param \Webkul\Product\Contracts\Product $product
*
* @return int
*/
public function getCountRating($product)
{
$reviews = $product->reviews()
->where('status', 'approved')
->select('rating', DB::raw('count(*) as total'))
->groupBy('rating')
->orderBy('rating','desc')
->get();
$totalReviews = $this->getTotalReviews($product);
for ($i = 5; $i >= 1; $i--) {
if (! $reviews->isEmpty()) {
foreach ($reviews as $review) {
if ($review->rating == $i) {
$percentage[$i] = $review->total;
break;
} else {
$percentage[$i]=0;
}
}
} else {
$percentage[$i]=0;
}
}
return $percentage;
}
/**
* Returns the count rating of the product
* Returns the count rating of the product.
*
* @return array
*/
public function getVelocityMetaData($locale = null, $channel = null, $default = true)
{
static $metaData;
if ($metaData) {
return $metaData;
}
if (! $locale) {
$locale = request()->get('locale') ?: app()->getLocale();
}
@ -309,12 +278,8 @@ class Helper extends Review
$reviewHelper = app('Webkul\Product\Helpers\Review');
$productImageHelper = app('Webkul\Product\Helpers\ProductImage');
$totalReviews = $reviewHelper->getTotalReviews($product);
$avgRatings = ceil($reviewHelper->getAverageRating($product));
$galleryImages = $productImageHelper->getGalleryImages($product);
$productImage = $productImageHelper->getProductBaseImage($product)['medium_image_url'];
$productImage = $productImageHelper->getProductBaseImage($product, $galleryImages)['medium_image_url'];
$largeProductImageName = "large-product-placeholder.png";
$mediumProductImageName = "meduim-product-placeholder.png";
@ -334,8 +299,8 @@ class Helper extends Review
return [
'priceHTML' => $priceHTML,
'avgRating' => $avgRatings,
'totalReviews' => $totalReviews,
'avgRating' => ceil($reviewHelper->getAverageRating($product)),
'totalReviews' => $reviewHelper->getTotalReviews($product),
'image' => $productImage,
'new' => $isProductNew,
'galleryImages' => $galleryImages,
@ -344,7 +309,6 @@ class Helper extends Review
'description' => $product->description,
'shortDescription' => $product->short_description,
'firstReviewText' => trans('velocity::app.products.be-first-review'),
'defaultAddToCart' => view('shop::products.add-buttons', ['product' => $product])->render(),
'addToCartHtml' => view('shop::products.add-to-cart', [
'product' => $product,
'addWishlistClass' => ! (isset($list) && $list) ? '' : '',
@ -373,38 +337,26 @@ class Helper extends Review
*/
public function fetchProductCollection($items, $moveToCart = false, $separator='&')
{
$productCollection = [];
$productIds = explode($separator, $items);
$productIds = collect(explode($separator, $items));
foreach ($productIds as $productId) {
// @TODO:- query only once insted of 2
return $productIds->map(function ($productId) use ($moveToCart) {
$productFlat = $this->productFlatRepository->findOneWhere(['id' => $productId]);
if ($productFlat) {
$product = $this->productRepository->findOneWhere(['id' => $productFlat->product_id]);
$formattedProduct = $this->formatProduct($productFlat, false, [
'moveToCart' => $moveToCart,
'btnText' => $moveToCart ? trans('shop::app.customer.account.wishlist.move-to-cart') : null,
]);
if ($product) {
$formattedProduct = $this->formatProduct($productFlat, false, [
'moveToCart' => $moveToCart,
'btnText' => $moveToCart ? trans('shop::app.customer.account.wishlist.move-to-cart') : null,
]);
$productMetaDetails = [];
$productMetaDetails['slug'] = $product->url_key;
$productMetaDetails['product_image'] = $formattedProduct['image'];
$productMetaDetails['priceHTML'] = $formattedProduct['priceHTML'];
$productMetaDetails['new'] = $formattedProduct['new'];
$productMetaDetails['addToCartHtml'] = $formattedProduct['addToCartHtml'];
$productMetaDetails['galleryImages'] = $formattedProduct['galleryImages'];
$productMetaDetails['defaultAddToCart'] = $formattedProduct['defaultAddToCart'];
$product = array_merge($productFlat->toArray(), $productMetaDetails);
array_push($productCollection, $product);
}
return array_merge($productFlat->toArray(), [
'slug' => $productFlat->url_key,
'product_image' => $formattedProduct['image'],
'priceHTML' => $formattedProduct['priceHTML'],
'new' => $formattedProduct['new'],
'addToCartHtml' => $formattedProduct['addToCartHtml'],
'galleryImages' => $formattedProduct['galleryImages']
]);
}
}
return $productCollection;
})->toArray();
}
}

View File

@ -2,22 +2,16 @@
namespace Webkul\Velocity\Http\Controllers\Shop;
use Webkul\Velocity\Helpers\Helper;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Velocity\Repositories\VelocityCustomerCompareProductRepository as CustomerCompareProductRepository;
class ComparisonController extends Controller
{
/**
* function for customers to get products in comparison.
* Method for customers to get products in comparison.
*
* @return \Illuminate\Http\Response|\Illuminate\View\View
*/
public function getComparisonList()
{
if (request()->get('data')) {
$productSlugs = null;
$productCollection = [];
if (auth()->guard('customer')->user()) {
@ -28,20 +22,17 @@ class ComparisonController extends Controller
'product_flat.id'
)
->where('customer_id', auth()->guard('customer')->user()->id)
->get()
->toArray();
->get();
$items = [];
foreach ($productCollection as $index => $customerCompare) {
array_push($items, $customerCompare['id']);
}
$items = implode('&', $items);
$productCollection = $this->velocityHelper->fetchProductCollection($items);
$items = $productCollection->map(function ($product) {
return $product->id;
})->join('&');
$productCollection = ! empty($items)
? $this->velocityHelper->fetchProductCollection($items)
: [];
} else {
// for product details
/* for product details */
if ($items = request()->get('items')) {
$productCollection = $this->velocityHelper->fetchProductCollection($items);
}

View File

@ -61,7 +61,6 @@ class ShopController extends Controller
switch ($slug) {
case 'new-products':
case 'featured-products':
$formattedProducts = [];
$count = request()->get('count');
if ($slug == "new-products") {
@ -70,13 +69,11 @@ class ShopController extends Controller
$products = $this->velocityProductRepository->getFeaturedProducts($count);
}
foreach ($products as $product) {
array_push($formattedProducts, $this->velocityHelper->formatProduct($product));
}
$response = [
'status' => true,
'products' => $formattedProducts,
'products' => $products->map(function ($product) {
return $this->velocityHelper->formatProduct($product);
}),
];
break;

View File

@ -33,7 +33,7 @@
</script>
@endif
<?php $productBaseImage = app('Webkul\Product\Helpers\ProductImage')->getProductBaseImage($product); ?>
<?php $productBaseImage = app('Webkul\Product\Helpers\ProductImage')->getProductBaseImage($product, $images); ?>
<meta name="twitter:card" content="summary_large_image" />

View File

@ -2,15 +2,15 @@
@inject ('customHelper', 'Webkul\Velocity\Helpers\Helper')
@php
$reviews = $reviewHelper->getReviews($product)->paginate(10);
if (! isset($total)) {
$total = $reviewHelper->getTotalReviews($product);
$avgRatings = $reviewHelper->getAverageRating($product);
$avgStarRating = round($avgRatings);
}
$percentageRatings = $reviewHelper->getPercentageRating($product);
$countRatings = $customHelper->getCountRating($product);
@endphp
{!! view_render_event('bagisto.shop.products.review.before', ['product' => $product]) !!}
@ -127,7 +127,7 @@
</div>
<div class="customer-reviews" slot="body">
@foreach ($reviewHelper->getReviews($product)->paginate(10) as $review)
@foreach ($reviews as $review)
<div class="row">
<h4 class="col-lg-12 fs18">{{ $review->title }}</h4>
@ -165,7 +165,7 @@
</h3>
<div class="customer-reviews">
@foreach ($reviewHelper->getReviews($product)->paginate(10) as $review)
@foreach ($reviews as $review)
<div class="row">
<h4 class="col-lg-12 fs18">{{ $review->title }}</h4>