Issue #803 fixed

This commit is contained in:
jitendra 2019-04-16 15:40:58 +05:30
parent f3f61e3c91
commit eb00f36835
38 changed files with 324 additions and 361 deletions

View File

@ -301,5 +301,7 @@ return [
'DbView' => Flynsarmy\DbBladeCompiler\Facades\DbView::class,
'PDF' => Barryvdh\DomPDF\Facade::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
'Concord' => Konekt\Concord\Facades\Concord::class,
'Helper' => Konekt\Concord\Facades\Helper::class,
],
];

View File

@ -38,7 +38,12 @@ class Product {
*/
protected $productGrid;
public function __construct(ProductRepository $product, ProductGridRepository $productGrid, ProductFlatRepository $productFlat, Price $price)
public function __construct(
ProductRepository $product,
ProductGridRepository $productGrid,
ProductFlatRepository $productFlat,
Price $price
)
{
$this->product = $product;

View File

@ -183,7 +183,7 @@
];
});
var super_attributes = @json($product->super_attributes);
var super_attributes = @json($product->super_attributes()->with('options')->get());
var variants = @json($product->variants);
Vue.component('variant-form', {

View File

@ -11,7 +11,7 @@ class Attribute extends TranslatableModel implements AttributeContract
protected $fillable = ['code', 'admin_name', 'type', 'position', 'is_required', 'is_unique', 'validation', 'value_per_locale', 'value_per_channel', 'is_filterable', 'is_configurable', 'is_visible_on_front', 'is_user_defined', 'swatch_type'];
protected $with = ['options', 'translations'];
// protected $with = ['options'];
/**
* Get the options.

View File

@ -14,8 +14,6 @@ class AttributeOption extends TranslatableModel implements AttributeOptionContra
protected $fillable = ['admin_name', 'swatch_value', 'sort_order', 'attribute_id'];
protected $with = ['translations'];
/**
* Get the attribute that owns the attribute option.
*/

View File

@ -99,18 +99,14 @@ class CategoryRepository extends Repository
*/
public function getVisibleCategoryTree($id = null)
{
static $categories;
static $categories = [];
if ($categories[$id])
if(array_key_exists($id, $categories))
return $categories[$id];
if ($id) {
$categories[$id] = Category::orderBy('position', 'ASC')->where('status', 1)->descendantsOf($id)->toTree();
} else {
$categories[$id] = Category::orderBy('position', 'ASC')->where('status', 1)->get()->toTree();
}
return $categories[$id];
return $categories[$id] = $id
? Category::orderBy('position', 'ASC')->where('status', 1)->descendantsOf($id)->toTree()
: Category::orderBy('position', 'ASC')->where('status', 1)->get()->toTree();
}
/**

View File

@ -566,7 +566,10 @@ class Cart {
*/
public function getCart()
{
$cart = null;
static $cart;
if ($cart)
return $cart;
if (auth()->guard('customer')->check()) {
$cart = $this->cart->findOneWhere([
@ -592,12 +595,16 @@ class Cart {
$data = $cart->toArray();
$data['shipping_address'] = current($data['shipping_address']);
$data['shipping_address'] = $cart->shipping_address->toArray();
$data['billing_address'] = current($data['billing_address']);
$data['billing_address'] = $cart->billing_address->toArray();
$data['selected_shipping_rate'] = $cart->selected_shipping_rate->toArray();
$data['payment'] = $cart->payment->toArray();
$data['items'] = $cart->items->toArray();
return $data;
}
@ -612,7 +619,6 @@ class Cart {
$labels = [];
$attribute = $product->parent->super_attributes;
foreach ($product->parent->super_attributes as $attribute) {
$option = $attribute->options()->where('id', $product->{$attribute->code})->first();
@ -834,20 +840,22 @@ class Cart {
$items = $cart->items;
foreach ($items as $item) {
if ($item->product->type == 'configurable') {
if ($item->product->sku != $item->sku) {
$item->update(['sku' => $item->product->sku]);
$productFlat = $item->product_flat;
} else if ($item->product->name != $item->name) {
$item->update(['name' => $item->product->name]);
if ($productFlat->type == 'configurable') {
if ($productFlat->sku != $item->sku) {
$item->update(['sku' => $productFlat->sku]);
} else if ($this->price->getMinimalPrice($item->child->product) != $item->price) {
} else if ($productFlat->name != $item->name) {
$item->update(['name' => $productFlat->name]);
} else if ($this->price->getMinimalPrice($item->child->product_flat) != $item->price) {
// $price = (float) $item->custom_price ? $item->custom_price : $item->child->product->price;
if ((float)$item->custom_price) {
$price = $item->custom_price;
} else {
$price = $this->price->getMinimalPrice($item->child->product);
$price = $this->price->getMinimalPrice($item->child->product_flat);
}
$item->update([
@ -858,20 +866,20 @@ class Cart {
]);
}
} else if ($item->product->type == 'simple') {
if ($item->product->sku != $item->sku) {
$item->update(['sku' => $item->product->sku]);
} else if ($productFlat->type == 'simple') {
if ($productFlat->sku != $item->sku) {
$item->update(['sku' => $productFlat->sku]);
} else if ($item->product->name != $item->name) {
$item->update(['name' => $item->product->name]);
} else if ($productFlat->name != $item->name) {
$item->update(['name' => $productFlat->name]);
} else if ($this->price->getMinimalPrice($item->product) != $item->price) {
} else if ($this->price->getMinimalPrice($productFlat) != $item->price) {
// $price = (float) $item->custom_price ? $item->custom_price : $item->product->price;
if ((float)$item->custom_price) {
$price = $item->custom_price;
} else {
$price = $this->price->getMinimalPrice($item->product);
$price = $this->price->getMinimalPrice($productFlat);
}
$item->update([
@ -1092,7 +1100,7 @@ class Cart {
if ($product->type == 'simple') {
$data['quantity'] = 1;
$data['product'] = $wishlistItem->product->id;
$data['product'] = $product->id;
$result = $this->add($product->id, $data);

View File

@ -1,49 +0,0 @@
<?php
namespace Webkul\Checkout\Http\ViewComposers;
use Illuminate\View\View;
use Illuminate\Support\Collection;
use Webkul\Checkout\Repositories\CartRepository;
use Webkul\Checkout\Repositories\CartItemRepository;
//Product Image Helper Class
use Webkul\Product\Helpers\ProductImage;
use Cart;
/**
* cart List Composer on Navigation Menu
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class CartComposer
{
/**
* The cart implementation
* for shop bundle's navigation
* menu
*/
protected $cart;
/**
* Bind data to the view.
*
* @param View $view
* @return void
*/
public function __construct(CartRepository $cart, CartItemRepository $cartItem, ProductImage $productImage) {
$this->cart = $cart;
$this->cartItem = $cartItem;
$this->productImage = $productImage;
}
public function compose(View $view) {
}
}

View File

@ -14,7 +14,7 @@ class Cart extends Model implements CartContract
protected $hidden = ['coupon_code'];
protected $with = ['items', 'items.child', 'shipping_address', 'billing_address', 'selected_shipping_rate', 'payment'];
protected $with = ['items', 'items.child'];
/**
* To get relevant associated items with the cart instance

View File

@ -4,6 +4,7 @@ namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Product\Models\ProductProxy;
use Webkul\Product\Models\ProductFlatProxy;
use Webkul\Checkout\Contracts\CartItem as CartItemContract;
@ -22,6 +23,26 @@ class CartItem extends Model implements CartItemContract
return $this->hasOne(ProductProxy::modelClass(), 'id', 'product_id');
}
/**
* The Product Flat that belong to the product.
*/
public function product_flat()
{
return (ProductFlatProxy::modelClass())
::where('product_flat.product_id', $this->product_id)
->where('product_flat.locale', app()->getLocale())
->where('product_flat.channel', core()->getCurrentChannelCode())
->select('product_flat.*');
}
/**
* Get all of the attributes for the attribute groups.
*/
public function getProductFlatAttribute()
{
return $this->product_flat()->first();
}
public function cart()
{
return $this->hasOne(CartProxy::modelClass(), 'id', 'cart_id');

View File

@ -340,7 +340,7 @@ class Core
*/
public function convertPrice($amount, $targetCurrencyCode = null)
{
$targetCurrency = !$targetCurrencyCode
$targetCurrency = ! $targetCurrencyCode
? $this->getCurrentCurrency()
: $this->currencyRepository->findOneByField('code', $targetCurrencyCode);

View File

@ -1,56 +0,0 @@
<?php
namespace Webkul\Product\Contracts\Criteria;
use Prettus\Repository\Contracts\CriteriaInterface;
use Prettus\Repository\Contracts\RepositoryInterface;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Helpers\AbstractProduct;
/**
* Class MyCriteria.
*
* @package namespace App\Criteria;
*/
class ActiveProductCriteria extends AbstractProduct implements CriteriaInterface
{
/**
* @var AttributeRepository
*/
protected $attribute;
/**
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
* @return void
*/
public function __construct(AttributeRepository $attribute)
{
$this->attribute = $attribute;
}
/**
* Apply criteria in query repository
*
* @param string $model
* @param RepositoryInterface $repository
*
* @return mixed
*/
public function apply($model, RepositoryInterface $repository)
{
foreach (['status', 'visible_individually'] as $code) {
$attribute = $this->attribute->findOneByField('code', $code);
$alias = 'filter_' . $attribute->code;
$model = $model->leftJoin('product_attribute_values as ' . $alias, 'products.id', '=', $alias . '.product_id');
$model = $this->applyChannelLocaleFilter($attribute, $model, $alias);
$model->where($alias . '.boolean_value', 1)
->where($alias . '.attribute_id', $attribute->id);
}
return $model;
}
}

View File

@ -1,79 +0,0 @@
<?php
namespace Webkul\Product\Contracts\Criteria;
use Prettus\Repository\Contracts\CriteriaInterface;
use Prettus\Repository\Contracts\RepositoryInterface;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Helpers\AbstractProduct;
/**
* Class MyCriteria.
*
* @package namespace App\Criteria;
*/
class AttributeToSelectCriteria extends AbstractProduct implements CriteriaInterface
{
/**
* @var AttributeRepository
*/
protected $attribute;
/**
* @var array|string
*/
protected $attributeToSelect;
/**
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
* @return void
*/
public function __construct(AttributeRepository $attribute)
{
$this->attribute = $attribute;
}
/**
* Set attributes in attributeToSelect variable
*
* @param array|string $attributes
*
* @return mixed
*/
public function addAttribueToSelect($attributes)
{
$this->attributeToSelect = $attributes;
return $this;
}
/**
* Apply criteria in query repository
*
* @param string $model
* @param RepositoryInterface $repository
*
* @return mixed
*/
public function apply($model, RepositoryInterface $repository)
{
$model = $model->select('products.*');
foreach ($this->attribute->getProductDefaultAttributes() as $attribute) {
$productValueAlias = 'pav_' . $attribute->code;
$model = $model->leftJoin('product_attribute_values as ' . $productValueAlias, function($qb) use($attribute, $productValueAlias) {
$qb = $this->applyChannelLocaleFilter($attribute, $qb, $productValueAlias);
$qb->on('products.id', $productValueAlias . '.product_id')
->where($productValueAlias . '.attribute_id', $attribute->id);
});
$model = $model->addSelect($productValueAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $attribute->code);
}
return $model;
}
}

View File

@ -3,9 +3,18 @@
namespace Webkul\Product\Helpers;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductFlatProxy;
use Webkul\Product\Models\ProductFlat;
abstract class AbstractProduct
{
/**
* array
*
* @var array
*/
protected $productFlat = [];
/**
* Add Channle and Locale filter
*
@ -35,4 +44,27 @@ abstract class AbstractProduct
return $qb;
}
/**
* Sets product flat variable
*
* @param Product $product
* @return void
*/
public function setProductFlat($product)
{
if (array_key_exists($product->id, $this->productFlat))
return;
if (! $product instanceof ProductFlat) {
$this->productFlat[$product->id] = ProductFlatProxy::modelClass()
::where('product_flat.product_id', $product->id)
->where('product_flat.locale', app()->getLocale())
->where('product_flat.channel', core()->getCurrentChannelCode())
->select('product_flat.*')
->first();
} else {
$this->productFlat[$product->id] = $product;
}
}
}

View File

@ -107,7 +107,7 @@ class ConfigurableOption extends AbstractProduct
*/
public function getAllowAttributes($product)
{
return $product->super_attributes;
return $product->product->super_attributes;
}
/**
@ -124,8 +124,11 @@ class ConfigurableOption extends AbstractProduct
$allowAttributes = $this->getAllowAttributes($currentProduct);
foreach ($allowedProducts as $product) {
$productId = $product->id;
if ($product instanceof \Webkul\Product\Models\ProductFlat) {
$productId = $product->product_id;
} else {
$productId = $product->id;
}
foreach ($allowAttributes as $productAttribute) {
$productAttributeId = $productAttribute->id;
@ -154,7 +157,9 @@ class ConfigurableOption extends AbstractProduct
$attributes = [];
foreach ($product->super_attributes as $attribute) {
$allowAttributes = $this->getAllowAttributes($product);
foreach ($allowAttributes as $attribute) {
$attributeOptionsData = $this->getAttributeOptionsData($attribute, $options);
@ -211,7 +216,13 @@ class ConfigurableOption extends AbstractProduct
$prices = [];
foreach ($this->getAllowedProducts($product) as $variant) {
$prices[$variant->id] = [
if ($variant instanceof \Webkul\Product\Models\ProductFlat) {
$variantId = $variant->product_id;
} else {
$variantId = $variant->id;
}
$prices[$variantId] = [
'regular_price' => [
'formated_price' => core()->currency($variant->price),
'price' => $variant->price
@ -237,7 +248,13 @@ class ConfigurableOption extends AbstractProduct
$images = [];
foreach ($this->getAllowedProducts($product) as $variant) {
$images[$variant->id] = $this->productImage->getGalleryImages($variant);
if ($variant instanceof \Webkul\Product\Models\ProductFlat) {
$variantId = $variant->product_id;
} else {
$variantId = $variant->id;
}
$images[$variantId] = $this->productImage->getGalleryImages($variant);
}
return $images;

View File

@ -5,6 +5,7 @@ namespace Webkul\Product\Helpers;
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductFlat;
class Price extends AbstractProduct
{
@ -34,14 +35,19 @@ class Price extends AbstractProduct
*/
public function getMinimalPrice($product)
{
static $price = [];
if(array_key_exists($product->id, $price))
return $price[$product->id];
if ($product->type == 'configurable') {
return $this->getVariantMinPrice($product);
return $price[$product->id] = $this->getVariantMinPrice($product);
} else {
if ($this->haveSpecialPrice($product)) {
return $product->special_price;
} else {
return $product->price;
return $price[$product->id] = $product->special_price;
}
return $price[$product->id] = $product->price;
}
}
@ -53,20 +59,30 @@ class Price extends AbstractProduct
*/
public function getVariantMinPrice($product)
{
static $attribute;
static $price = [];
if (! $attribute)
$attribute = $this->attribute->findOneByField('code', 'price');
if(array_key_exists($product->id, $price))
return $price[$product->id];
$attribute = $this->attribute->findOneByField('code', 'price');
if ($product instanceof ProductFlat) {
$productId = $product->product_id;
} else {
$productId = $product->id;
}
//Todo => can be optimized
$qb = ProductAttributeValue::join('products', 'product_attribute_values.product_id', '=', 'products.id')
->join('attributes', 'product_attribute_values.attribute_id', '=', 'attributes.id')
->where('products.parent_id', $product->id)
->where('products.parent_id', $productId)
->where('attributes.code', 'price')
->addSelect('product_attribute_values.*');
$this->applyChannelLocaleFilter($attribute, $qb);
return $qb->min('product_attribute_values.' . ProductAttributeValue::$attributeTypeFields['price']);
return $price[$product->id] = $qb->min('product_attribute_values.' . ProductAttributeValue::$attributeTypeFields['price']);
}
/**
@ -77,10 +93,15 @@ class Price extends AbstractProduct
*/
public function getSpecialPrice($product)
{
static $price = [];
if(array_key_exists($product->id, $price))
return $price[$product->id];
if ($this->haveSpecialPrice($product)) {
return $product->special_price;
return $price[$product->id] = $product->special_price;
} else {
return $product->price;
return $price[$product->id] = $product->price;
}
}
@ -90,7 +111,7 @@ class Price extends AbstractProduct
*/
public function haveSpecialPrice($product)
{
if (is_null($product->special_price) || !$product->special_price)
if (is_null($product->special_price) || ! (float) $product->special_price)
return false;
if (core()->isChannelDateInInterval($product->special_price_from, $product->special_price_to)) {

View File

@ -15,23 +15,24 @@ class ProductImage extends AbstractProduct
*/
public function getGalleryImages($product)
{
if (! $product)
return [];
$images = [];
if ($product) {
foreach ($product->images as $image) {
if (! Storage::has($image->path))
continue;
foreach ($product->images as $image) {
if (! Storage::has($image->path))
continue;
$images[] = [
'small_image_url' => url('cache/small/' . $image->path),
'medium_image_url' => url('cache/medium/' . $image->path),
'large_image_url' => url('cache/large/' . $image->path),
'original_image_url' => url('cache/original/' . $image->path),
];
}
$images[] = [
'small_image_url' => url('cache/small/' . $image->path),
'medium_image_url' => url('cache/medium/' . $image->path),
'large_image_url' => url('cache/large/' . $image->path),
'original_image_url' => url('cache/original/' . $image->path),
];
}
if (! $product || (! $product->parent_id && !count($images))) {
if (! $product->parent_id && ! count($images)) {
$images[] = [
'small_image_url' => asset('vendor/webkul/ui/assets/images/product/small-product-placeholder.png'),
'medium_image_url' => asset('vendor/webkul/ui/assets/images/product/meduim-product-placeholder.png'),
@ -51,8 +52,12 @@ class ProductImage extends AbstractProduct
*/
public function getProductBaseImage($product)
{
if ($product && $product->images->count()) {
$images = $product->images;
if (! $product)
return [];
$images = $product->images;
if ($images->count()) {
$image = [
'small_image_url' => url('cache/small/' . $images[0]->path),
'medium_image_url' => url('cache/medium/' . $images[0]->path),

View File

@ -13,7 +13,12 @@ class Review extends AbstractProduct
*/
public function getReviews($product)
{
return $product->reviews()->where('status', 'approved');
static $reviews = [];
if(array_key_exists($product->id, $reviews))
return $reviews[$product->id];
return $reviews[$product->id] = $product->reviews()->where('status', 'approved');
}
/**
@ -24,7 +29,12 @@ class Review extends AbstractProduct
*/
public function getAverageRating($product)
{
return number_format(round($product->reviews()->where('status', 'approved')->average('rating'), 2), 1);
static $avgRating = [];
if(array_key_exists($product->id, $avgRating))
return $avgRating[$product->id];
return $avgRating[$product->id] = number_format(round($product->reviews()->where('status', 'approved')->average('rating'), 2), 1);
}
/**
@ -35,7 +45,12 @@ class Review extends AbstractProduct
*/
public function getTotalReviews($product)
{
return $product->reviews()->where('status', 'approved')->count();
static $totalReviews = [];
if(array_key_exists($product->id, $totalReviews))
return $totalReviews[$product->id];
return $totalReviews[$product->id] = $product->reviews()->where('status', 'approved')->count();
}
/**
@ -46,7 +61,12 @@ class Review extends AbstractProduct
*/
public function getTotalRating($product)
{
return $product->reviews()->where('status','approved')->sum('rating');
static $totalRating = [];
if(array_key_exists($product->id, $totalRating))
return $totalRating[$product->id];
return $totalRating[$product->id] = $product->reviews()->where('status','approved')->sum('rating');
}
/**
@ -57,17 +77,20 @@ class Review extends AbstractProduct
*/
public function getPercentageRating($product)
{
$reviews = $product->reviews()->where('status','approved')
$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] = round(($review->total/$this->getTotalReviews($product))*100);
$percentage[$i] = round(($review->total / $totalReviews) * 100);
break;
} else {
$percentage[$i]=0;

View File

@ -14,52 +14,23 @@ class View extends AbstractProduct
{
$data = [];
$attributes = $product->attribute_family->custom_attributes()->where('attributes.is_visible_on_front', 1)->get();
$attributeOptionReposotory = app('Webkul\Attribute\Repositories\AttributeOptionRepository');
$attributes = $product->product->attribute_family->custom_attributes()->where('attributes.is_visible_on_front', 1)->get();
foreach ($attributes as $attribute) {
$value = $product->{$attribute->code};
if ($attribute->type == 'boolean') {
$value = $product->{$attribute->code} ? 'Yes' : 'No';
$data[] = [
'code' => $attribute->code,
'label' => $attribute->name,
'value' => $value,
'admin_name' => $attribute->admin_name,
];
} else if ($product->{$attribute->code}) {
$value = $product->{$attribute->code};
if ($attribute->type == 'select') {
$attributeOption = $attributeOptionReposotory->find($value);
if ($attributeOption) {
$value = $attributeOption->label;
}
} else if ($attribute->type == 'multiselect') {
$optionIds = explode(",", $value);
if (count($optionIds)) {
$attributeOptions = $attributeOptionReposotory->findWhereIn('id', $optionIds);
foreach ($attributeOptions as $attributeOption) {
if ($attributeOption && $attributeOption->label) {
$result[] = $attributeOption->label;
}
}
$value = implode(", ", $result);
}
}
$data[] = [
'code' => $attribute->code,
'label' => $attribute->name,
'value' => $value,
'admin_name' => $attribute->admin_name,
];
$value = $value ? 'Yes' : 'No';
} else if ($attribute->type == 'select' || $attribute->type == 'multiselect') {
$value = $product->{$attribute->code . '_label'};
}
$data[] = [
'code' => $attribute->code,
'label' => $attribute->name,
'value' => $value,
'admin_name' => $attribute->admin_name,
];
}
return $data;

View File

@ -167,7 +167,7 @@ class ProductController extends Controller
*/
public function edit($id)
{
$product = $this->product->with(['variants'])->findOrFail($id);
$product = $this->product->with(['variants', 'variants.inventories'])->findOrFail($id);
$categories = $this->category->getCategoryTree();

View File

@ -13,7 +13,7 @@ class Product extends Model implements ProductContract
{
protected $fillable = ['type', 'attribute_family_id', 'sku', 'parent_id'];
protected $with = ['attribute_family', 'inventories'];
// protected $with = ['attribute_family', 'inventories'];
// protected $table = 'products';
@ -206,7 +206,7 @@ class Product extends Model implements ProductContract
*/
public function getAttribute($key)
{
if (! method_exists(self::class, $key) && !in_array($key, ['parent_id', 'attribute_family_id']) && !isset($this->attributes[$key])) {
if (! method_exists(self::class, $key) && ! in_array($key, ['parent_id', 'attribute_family_id']) && ! isset($this->attributes[$key])) {
if (isset($this->id)) {
$this->attributes[$key] = '';

View File

@ -28,4 +28,74 @@ class ProductFlat extends Model implements ProductFlatContract
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get product type value from base product
*/
public function getTypeAttribute()
{
return $this->product->type;
}
/**
* @param string $key
*
* @return bool
*/
public function isSaleable()
{
if (! $this->status)
return false;
if ($this->haveSufficientQuantity(1))
return true;
return false;
}
/**
* @param integer $qty
*
* @return bool
*/
public function haveSufficientQuantity($qty)
{
return $this->product->haveSufficientQuantity($qty);
}
/**
* The images that belong to the product.
*/
public function images()
{
return (ProductImageProxy::modelClass())
::where('product_images.product_id', $this->product_id)
->select('product_images.*');
}
/**
* Get all of the attributes for the attribute groups.
*/
public function getImagesAttribute()
{
return $this->images()->get();
}
/**
* The reviews that belong to the product.
*/
public function reviews()
{
return (ProductReviewProxy::modelClass())
::where('product_reviews.product_id', $this->product_id)
->select('product_reviews.*');
}
/**
* Get all of the reviews for the attribute groups.
*/
public function getReviewsAttribute()
{
return $this->images()->get();
}
}

View File

@ -5,7 +5,6 @@ namespace Webkul\Product\Repositories;
use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Product\Helpers\Price;
/**
* Product Repository
@ -26,13 +25,9 @@ class ProductFlatRepository extends Repository
public function __construct(
Product $product,
Price $price,
App $app
) {
$this->product = $product;
$this->price = $price;
parent::__construct($app);
}

View File

@ -9,8 +9,6 @@ use Webkul\Core\Eloquent\Repository;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Attribute\Repositories\AttributeOptionRepository;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Contracts\Criteria\ActiveProductCriteria;
use Webkul\Product\Contracts\Criteria\AttributeToSelectCriteria;
use Illuminate\Database\Eloquent\ModelNotFoundException;
/**
@ -518,25 +516,19 @@ class ProductRepository extends Repository
*/
public function findBySlugOrFail($slug, $columns = null)
{
$attribute = $this->attribute->findOneByField('code', 'url_key');
$product = app('Webkul\Product\Repositories\ProductFlatRepository')->findOneWhere([
'url_key' => $slug,
'locale' => app()->getLocale(),
'channel' => core()->getCurrentChannelCode(),
]);
$attributeValue = $this->attributeValue->findOneWhere([
'attribute_id' => $attribute->id,
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $slug
], ['product_id']);
if ($attributeValue && $attributeValue->product_id) {
$this->pushCriteria(app(ActiveProductCriteria::class));
$this->pushCriteria(app(AttributeToSelectCriteria::class)->addAttribueToSelect($columns));
$product = $this->findOrFail($attributeValue->product_id);
return $product;
if (! $product) {
throw (new ModelNotFoundException)->setModel(
get_class($this->model), $slug
);
}
throw (new ModelNotFoundException)->setModel(
get_class($this->model), $slug
);
return $product;
}
/**

View File

@ -9,8 +9,6 @@ use Webkul\Checkout\Repositories\CartItemRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Customer\Repositories\CustomerRepository;
use Webkul\Customer\Repositories\WishlistRepository;
use Webkul\Product\Helpers\ProductImage;
use Webkul\Product\Helpers\View as ProductView;
use Illuminate\Support\Facades\Event;
use Cart;
@ -32,7 +30,6 @@ class CartController extends Controller
* @param $cartItem
* @param $customer
* @param $product
* @param $productImage
* @param $productView
*/
protected $_config;
@ -45,8 +42,6 @@ class CartController extends Controller
protected $product;
protected $productView;
protected $suppressFlash = false;
/**
@ -61,8 +56,6 @@ class CartController extends Controller
CartItemRepository $cartItem,
CustomerRepository $customer,
ProductRepository $product,
ProductImage $productImage,
ProductView $productView,
WishlistRepository $wishlist
)
{
@ -77,10 +70,6 @@ class CartController extends Controller
$this->product = $product;
$this->productImage = $productImage;
$this->productView = $productView;
$this->wishlist = $wishlist;
$this->_config = request('_config');

View File

@ -31,6 +31,9 @@ use Webkul\Core\Repositories\SliderRepository as Sliders;
*/
public function index()
{
if (request()->route('any'))
abort(404);
$current_channel = core()->getCurrentChannel();
$all_sliders = $this->sliders->findWhere(['channel_id' => $current_channel['id']]);

View File

@ -2,7 +2,7 @@
Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function () {
//Store front home
Route::get('/', 'Webkul\Shop\Http\Controllers\HomeController@index')->defaults('_config', [
Route::get('/{any?}', 'Webkul\Shop\Http\Controllers\HomeController@index')->defaults('_config', [
'view' => 'shop::home.index'
])->name('shop.home.index');

View File

@ -73,7 +73,7 @@
$productBaseImage = $productImageHelper->getProductBaseImage($product);
?>
<div class="item mb-5">
<div class="item mb-5" style="margin-bottom: 5px;">
<div class="item-image">
<img src="{{ $productBaseImage['medium_image_url'] }}" />
</div>

View File

@ -11,9 +11,9 @@
</div>
@else
<div class="cart-wish-wrap">
<form action="{{ route('cart.add', $product->id) }}" method="POST">
<form action="{{ route('cart.add', $product->product_id) }}" method="POST">
@csrf
<input type="hidden" name="product" value="{{ $product->id }}">
<input type="hidden" name="product" value="{{ $product->product_id }}">
<input type="hidden" name="quantity" value="1">
<input type="hidden" value="false" name="is_configurable">
<button class="btn btn-lg btn-primary addtocart" {{ $product->haveSufficientQuantity(1) ? '' : 'disabled' }}>{{ __('shop::app.products.add-to-cart') }}</button>

View File

@ -1,6 +1,6 @@
{!! view_render_event('bagisto.shop.products.add_to_cart.before', ['product' => $product]) !!}
<button type="submit" class="btn btn-lg btn-primary addtocart" {{ $product->type != 'configurable' && !$product->haveSufficientQuantity(1) ? 'disabled' : '' }}>
<button type="submit" class="btn btn-lg btn-primary addtocart" {{ $product->type != 'configurable' && ! $product->haveSufficientQuantity(1) ? 'disabled' : '' }}>
{{ __('shop::app.products.add-to-cart') }}
</button>

View File

@ -1,6 +1,6 @@
{!! view_render_event('bagisto.shop.products.buy_now.before', ['product' => $product]) !!}
<button type="submit" data-href="{{ route('shop.product.buynow', $product->id)}}" class="btn btn-lg btn-primary buynow" {{ $product->type != 'configurable' && !$product->haveSufficientQuantity(1) ? 'disabled' : '' }}>
<button type="submit" data-href="{{ route('shop.product.buynow', $product->product_id)}}" class="btn btn-lg btn-primary buynow" {{ $product->type != 'configurable' && ! $product->haveSufficientQuantity(1) ? 'disabled' : '' }}>
{{ __('shop::app.products.buy-now') }}
</button>

View File

@ -1,10 +1,10 @@
{!! view_render_event('bagisto.shop.products.list.card.before', ['product' => $productFlat->product]) !!}
{!! view_render_event('bagisto.shop.products.list.card.before', ['product' => $productFlat]) !!}
<div class="product-card">
@inject ('productImageHelper', 'Webkul\Product\Helpers\ProductImage')
<?php $productBaseImage = $productImageHelper->getProductBaseImage($productFlat->product); ?>
<?php $productBaseImage = $productImageHelper->getProductBaseImage($productFlat); ?>
@if ($productFlat->new)
<div class="sticker new">
@ -28,11 +28,11 @@
</a>
</div>
@include ('shop::products.price', ['product' => $productFlat->product])
@include ('shop::products.price', ['product' => $productFlat])
@include('shop::products.add-buttons', ['product' => $productFlat->product])
@include('shop::products.add-buttons', ['product' => $productFlat])
</div>
</div>
{!! view_render_event('bagisto.shop.products.list.card.after', ['product' => $productFlat->product]) !!}
{!! view_render_event('bagisto.shop.products.list.card.after', ['product' => $productFlat]) !!}

View File

@ -42,7 +42,7 @@
</div>
<div class="review-form">
<form method="POST" action="{{ route('shop.reviews.store', $product->id ) }}" @submit.prevent="onSubmit">
<form method="POST" action="{{ route('shop.reviews.store', $product->product_id ) }}" @submit.prevent="onSubmit">
@csrf
<div class="heading mt-10 mb-25">
@ -75,7 +75,7 @@
<span class="control-error" v-if="errors.has('title')">@{{ errors.first('title') }}</span>
</div>
@if ($guest_review && !auth()->guard('customer')->user())
@if ($guest_review && ! auth()->guard('customer')->user())
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="title" class="required">
{{ __('shop::app.reviews.name') }}

View File

@ -68,7 +68,10 @@
</span>
<div class="total-reviews mt-5">
{{ __('shop::app.reviews.ratingreviews', ['rating' => $reviewHelper->getTotalRating($product), 'review' => $reviewHelper->getTotalReviews($product)]) }}
{{ __('shop::app.reviews.ratingreviews', [
'rating' => $reviewHelper->getTotalRating($product),
'review' => $reviewHelper->getTotalReviews($product)])
}}
</div>
</div>

View File

@ -66,7 +66,6 @@
@include ('shop::products.view.configurable-options')
{!! view_render_event('bagisto.shop.products.view.description.before', ['product' => $product]) !!}
<accordian :title="'{{ __('shop::app.products.description') }}'" :active="true">
@ -92,9 +91,9 @@
</product-view>
</div>
@include ('shop::products.view.related-products')
{{--@include ('shop::products.view.related-products')--}}
@include ('shop::products.view.up-sells')
{{--@include ('shop::products.view.up-sells')--}}
</section>
@ -104,7 +103,7 @@
@push('scripts')
<script type="text/x-template" id="product-view-template">
<form method="POST" id="product-form" action="{{ route('cart.add', $product->id) }}" @click="onSubmit($event)">
<form method="POST" id="product-form" action="{{ route('cart.add', $product->product_id) }}" @click="onSubmit($event)">
<slot></slot>

View File

@ -40,11 +40,8 @@
<div class="product-hero-image" id="product-hero-image">
<img :src="currentLargeImageUrl" id="pro-img"/>
{{-- Uncomment the line below for activating share links --}}
{{-- @include('shop::products.sharelinks') --}}
@auth('customer')
<a class="add-to-wishlist" href="{{ route('customer.wishlist.add', $product->id) }}">
<a class="add-to-wishlist" href="{{ route('customer.wishlist.add', $product->product_id) }}">
</a>
@endauth
</div>

View File

@ -1,7 +1,7 @@
{!! view_render_event('bagisto.shop.products.view.stock.before', ['product' => $product]) !!}
<div class="stock-status {{ $product->type != 'configurable' && !$product->haveSufficientQuantity(1) ? '' : 'active' }}">
{{ $product->type != 'configurable' && !$product->haveSufficientQuantity(1) ? __('shop::app.products.out-of-stock') : __('shop::app.products.in-stock') }}
<div class="stock-status {{ $product->type != 'configurable' && ! $product->haveSufficientQuantity(1) ? '' : 'active' }}">
{{ $product->type != 'configurable' && ! $product->haveSufficientQuantity(1) ? __('shop::app.products.out-of-stock') : __('shop::app.products.in-stock') }}
</div>
{!! view_render_event('bagisto.shop.products.view.stock.after', ['product' => $product]) !!}

View File

@ -1,7 +1,7 @@
@auth('customer')
{!! view_render_event('bagisto.shop.products.wishlist.before') !!}
<a class="add-to-wishlist" href="{{ route('customer.wishlist.add', $product->id) }}" id="wishlist-changer">
<a class="add-to-wishlist" href="{{ route('customer.wishlist.add', $product->product_id) }}" id="wishlist-changer">
<span class="icon wishlist-icon"></span>
</a>