merging with master

This commit is contained in:
prashant-webkul 2018-08-21 16:35:43 +05:30
commit eaf721f062
64 changed files with 1240 additions and 2828 deletions

View File

@ -34,7 +34,6 @@
"webkul/laravel-attribute": "self.version",
"webkul/laravel-customer": "self.version",
"webkul/laravel-category": "self.version",
"webkul/laravel-channel": "self.version",
"webkul/laravel-product": "self.version",
"webkul/laravel-shop": "self.version",
"webkul/laravel-theme": "self.version"
@ -54,7 +53,6 @@
"Webkul\\Shop\\": "packages/Webkul/Shop/src",
"Webkul\\Core\\": "packages/Webkul/Core/src",
"Webkul\\Customer\\": "packages/Webkul/Customer/src",
"Webkul\\Channel\\": "packages/Webkul/Channel/src",
"Webkul\\Inventory\\": "packages/Webkul/Inventory/src",
"Webkul\\Product\\": "packages/Webkul/Product/src",
"Webkul\\Theme\\": "packages/Webkul/Theme/src"

View File

@ -182,7 +182,6 @@ return [
Webkul\Core\Providers\CoreServiceProvider::class,
Webkul\Shop\Providers\ShopServiceProvider::class,
Webkul\Customer\Providers\CustomerServiceProvider::class,
Webkul\Channel\Providers\ChannelServiceProvider::class,
Webkul\Inventory\Providers\InventoryServiceProvider::class,
Webkul\Product\Providers\ProductServiceProvider::class,
Webkul\Shop\Providers\ShopServiceProvider::class,

View File

@ -55,6 +55,10 @@ class ProductDataGrid
],
],
'attributeColumns' => [
'name', 'price'
],
'join' => [
//for getting name of attrib family.
@ -73,11 +77,7 @@ class ProductDataGrid
'primaryKey' => 'prods.id',
'condition' => '=',
'secondaryKey' => 'pav.product_id',
'where' => [
'column1' => 'prods.id',
'condition' => '=',
'column2' => 'pav.product_id'
]
'withAttributes' => true
],
//for getting the inventory quantity of a product
@ -111,9 +111,9 @@ class ProductDataGrid
],
[
'name' => 'attfam.name',
'alias' => 'attributeFamily',
'alias' => 'FamilyName',
'type' => 'string',
'label' => 'Attribute Family',
'label' => 'Family Name',
'sortable' => true,
],
[
@ -123,35 +123,68 @@ class ProductDataGrid
'label' => 'Product Quatity',
'sortable' => false,
],
[
'name' => 'pav.product_id',
'alias' => 'ProductID',
'type' => 'string',
'label' => 'Product ID',
'sortable' => false,
// [
// 'name' => 'pav.attribute_id',
// 'alias' => 'AttributeID',
// 'type' => 'string',
// 'label' => 'Attribute ID',
// 'sortable' => false,
],
// ],
],
//use this bag for fetching attributes as columns in product datagrid.
// 'attributes' => [
// [
// 'name' => 'pi.qty',
// 'alias' => 'ProductQuantity',
// 'type' => 'string',
// 'label' => 'Product Quatity',
// 'sortable' => false,
// ]
// ],
'filterable' => [
//column, type, and label
[
'name' => 'prods.id',
'alias' => 'productID',
'type' => 'number',
'label' => 'ID',
],
[
'name' => 'prods.sku',
'alias' => 'productCode',
'type' => 'string',
'label' => 'SKU',
],
[
'name' => 'attfam.name',
'alias' => 'FamilyName',
'type' => 'string',
'label' => 'Family Name',
],
[
'name' => 'pi.qty',
'alias' => 'ProductQuantity',
'type' => 'string',
'label' => 'Product Quatity',
],
],
//don't use aliasing in case of searchables
'searchable' => [
//column, type and label
[
'column' => 'prods.id',
'type' => 'number',
'label' => 'ID',
],
[
'column' => 'prods.sku',
'type' => 'string',
'label' => 'SKU',
],
[
'column' => 'attfam.name',
'type' => 'string',
'label' => 'Family Name',
],
[
'column' => 'pi.qty',
'type' => 'string',
'label' => 'Product Quatity',
],
],
//list of viable operators that will be used

View File

@ -271,23 +271,23 @@ Route::group(['middleware' => ['web']], function () {
// Channel Routes
Route::get('/channels', 'Webkul\Channel\Http\Controllers\ChannelController@index')->defaults('_config', [
Route::get('/channels', 'Webkul\Core\Http\Controllers\ChannelController@index')->defaults('_config', [
'view' => 'admin::settings.channels.index'
])->name('admin.channels.index');
Route::get('/channels/create', 'Webkul\Channel\Http\Controllers\ChannelController@create')->defaults('_config', [
Route::get('/channels/create', 'Webkul\Core\Http\Controllers\ChannelController@create')->defaults('_config', [
'view' => 'admin::settings.channels.create'
])->name('admin.channels.create');
Route::post('/channels/create', 'Webkul\Channel\Http\Controllers\ChannelController@store')->defaults('_config', [
Route::post('/channels/create', 'Webkul\Core\Http\Controllers\ChannelController@store')->defaults('_config', [
'redirect' => 'admin.channels.index'
])->name('admin.channels.store');
Route::get('/channels/edit/{id}', 'Webkul\Channel\Http\Controllers\ChannelController@edit')->defaults('_config', [
Route::get('/channels/edit/{id}', 'Webkul\Core\Http\Controllers\ChannelController@edit')->defaults('_config', [
'view' => 'admin::settings.channels.edit'
])->name('admin.channels.edit');
Route::put('/channels/edit/{id}', 'Webkul\Channel\Http\Controllers\ChannelController@update')->defaults('_config', [
Route::put('/channels/edit/{id}', 'Webkul\Core\Http\Controllers\ChannelController@update')->defaults('_config', [
'redirect' => 'admin.channels.index'
])->name('admin.channels.update');

View File

@ -1,4 +1,5 @@
@if ($product->type == 'configurable')
@section('css')
@parent
<style>

View File

@ -7,7 +7,7 @@
@section('content')
<div class="content">
<?php $locale = request()->get('locale') ?: app()->getLocale(); ?>
<?php $channel = request()->get('channel') ?: channel()->getChannel(); ?>
<?php $channel = request()->get('channel') ?: core()->getCurrentChannelCode(); ?>
<form method="POST" action="" @submit.prevent="onSubmit" enctype="multipart/form-data">
@ -18,7 +18,7 @@
<div class="control-group">
<select class="control" id="channel-switcher" name="channel">
@foreach(channel()->getAllChannels() as $channelModel)
@foreach(core()->getAllChannels() as $channelModel)
<option value="{{ $channelModel->code }}" {{ ($channelModel->code) == $channel ? 'selected' : '' }}>
{{ $channelModel->name }}

View File

@ -78,7 +78,7 @@
<div class="control-group" :class="[errors.has('currencies[]') ? 'has-error' : '']">
<label for="currencies" class="required">{{ __('admin::app.settings.channels.currencies') }}</label>
<select v-validate="'required'" class="control" id="currencies" name="currencies[]" multiple>
@foreach(core()->allCurrencies() as $currency)
@foreach(core()->getAllCurrencies() as $currency)
<option value="{{ $currency->id }}" {{ old('currencies') && in_array($currency->id, old('currencies')) ? 'selected' : '' }}>
{{ $currency->name }}
</option>
@ -90,7 +90,7 @@
<div class="control-group" :class="[errors.has('base_currency') ? 'has-error' : '']">
<label for="base_currency" class="required">{{ __('admin::app.settings.channels.base-currency') }}</label>
<select v-validate="'required'" class="control" id="base_currency" name="base_currency">
@foreach(core()->allCurrencies() as $currency)
@foreach(core()->getAllCurrencies() as $currency)
<option value="{{ $currency->id }}" {{ old('base_currency') == $currency->id ? 'selected' : '' }}>
{{ $currency->name }}
</option>

View File

@ -82,7 +82,7 @@
<label for="currencies" class="required">{{ __('admin::app.settings.channels.currencies') }}</label>
<?php $selectedOptionIds = old('currencies') ?: $channel->currencies->pluck('id')->toArray() ?>
<select v-validate="'required'" class="control" id="currencies" name="currencies[]" multiple>
@foreach(core()->allCurrencies() as $currency)
@foreach(core()->geAllCurrencies() as $currency)
<option value="{{ $currency->id }}" {{ in_array($currency->id, $selectedOptionIds) ? 'selected' : '' }}>
{{ $currency->name }}
</option>
@ -95,7 +95,7 @@
<label for="base_currency" class="required">{{ __('admin::app.settings.channels.base-currency') }}</label>
<?php $selectedOption = old('base_currency') ?: $channel->base_currency ?>
<select v-validate="'required'" class="control" id="base_currency" name="base_currency">
@foreach(core()->allCurrencies() as $currency)
@foreach(core()->geAllCurrencies() as $currency)
<option value="{{ $currency->id }}" {{ $selectedOption == $currency->id ? 'selected' : '' }}>
{{ $currency->name }}
</option>

View File

@ -187,7 +187,7 @@ class AttributeTableSeeder extends Seeder
'en' => [
'name' => 'Special Price From'
],
'type' => 'datetime',
'type' => 'date',
'position' => 13,
'is_required' => 0,
'value_per_locale' => 0,
@ -201,7 +201,7 @@ class AttributeTableSeeder extends Seeder
'en' => [
'name' => 'Special Price To'
],
'type' => 'datetime',
'type' => 'date',
'position' => 14,
'is_required' => 0,
'value_per_locale' => 0,

View File

@ -6,6 +6,7 @@ use Webkul\Core\Eloquent\Repository;
use Webkul\Category\Models\Category;
use Illuminate\Container\Container as App;
use Webkul\Category\Models\CategoryTranslation;
use Illuminate\Database\Eloquent\ModelNotFoundException;
/**
* Category Reposotory
@ -59,9 +60,11 @@ class CategoryRepository extends Repository
/**
* Specify category tree
*
* @param integer $id
* @return mixed
*/
public function getCategoryTree($id = null) {
public function getCategoryTree($id = null)
{
return $id
? Category::orderBy('position', 'ASC')->where('id', '!=', $id)->get()->toTree()
: Category::orderBy('position', 'ASC')->get()->toTree();
@ -70,9 +73,30 @@ class CategoryRepository extends Repository
/**
* Checks slug is unique or not based on locale
*
* @param integer $id
* @param string $slug
* @return boolean
*/
public function isSlugUnique($id, $slug) {
public function isSlugUnique($id, $slug)
{
return CategoryTranslation::where('category_id', '!=', $id)->where('slug', '=', $slug)->first() ? false : true;
}
/**
* Retrive category from slug
*
* @param string $slug
* @return mixed
*/
public function findBySlugOrFail($slug)
{
$category = $this->model->whereTranslation('slug', $slug)->first();
if($category)
return $category;
throw (new ModelNotFoundException)->setModel(
get_class($this->model), $slug
);
}
}

View File

@ -1 +0,0 @@
/node_modules

View File

@ -1,27 +0,0 @@
{
"name": "webkul/laravel-channel",
"license": "MIT",
"authors": [
{
"name": "Jitendra Singh",
"email": "jitendra@webkul.com"
}
],
"require": {
"baum/baum": "~1.1"
},
"autoload": {
"psr-4": {
"Webkul\\Channel\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Webkul\\Channel\\Providers\\ChannelServiceProvider"
],
"aliases": { }
}
},
"minimum-stability": "dev"
}

View File

@ -1,31 +0,0 @@
<?php
namespace Webkul\Channel;
use Webkul\Channel\Models\Channel as ChannelModel;
class Channel
{
public function getAllChannels() {
return ChannelModel::all();
}
public function getChannel() {
$channel = ChannelModel::first();
if(!$channel)
return;
return $channel->code;
}
public function getCurrentChannel() {
//just retrieve only three columns id, name and code
$current_channel = collect(ChannelModel::select('id', 'name', 'code')->first());
return $current_channel;
}
public function getChannelModel() {
return ChannelModel::first();
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace Webkul\Channel\Facades;
use Illuminate\Support\Facades\Facade;
class Channel extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'channel';
}
}

View File

@ -1,13 +0,0 @@
<?php
namespace Webkul\Channel\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

View File

@ -1,10 +0,0 @@
<?php
use Webkul\Channel\Channel;
if (! function_exists('channel')) {
function channel()
{
return new Channel;
}
}
?>

View File

@ -1,49 +0,0 @@
<?php
namespace Webkul\Channel\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Routing\Router;
use Webkul\Channel\Channel;
use Webkul\Channel\Facades\ChannelFacade;
class ChannelServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot(Router $router)
{
include __DIR__ . '/../Http/helpers.php';
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->registerChannelFacade();
}
/**
* Register Bouncer as a singleton.
*
* @return void
*/
protected function registerChannelFacade()
{
$loader = AliasLoader::getInstance();
$loader->alias('channel', ChannelFacade::class);
$this->app->singleton('channel', function () {
return new Channel();
});
}
}

View File

@ -2,16 +2,173 @@
namespace Webkul\Core;
use Webkul\Core\Models\Channel as ChannelModel;
use Webkul\Core\Models\Locale as LocaleModel;
use Webkul\Core\Models\Currency as CurrencyModel;
class Core
{
/**
* Returns all channels
*
* @return Collection
*/
public function getAllChannels() {
return ChannelModel::all();
}
/**
* Returns currenct channel models
*
* @return mixed
*/
public function getCurrentChannel() {
return ChannelModel::first();
}
/**
* Returns currenct channel code
*
* @return string
*/
public function getCurrentChannelCode() {
return ($channel = $this->getCurrentChannel()) ? $channel->code : '';
}
/**
* Returns all locales
*
* @return Collection
*/
public function getAllLocales() {
return LocaleModel::all();
}
public function allCurrencies() {
/**
* Returns all currencies
*
* @return Collection
*/
public function getAllCurrencies()
{
return CurrencyModel::all();
}
/**
* Returns current channel's currency model
*
* @return mixed
*/
public function getCurrentCurrency()
{
$currency = CurrencyModel::first();
return $currency;
}
/**
* Returns current channel's currency code
*
* @return string
*/
public function getCurrentCurrencyCode()
{
return ($currency = $this->getCurrentCurrency()) ? $currency->code : '';
}
/**
* Returns current channel's currency symbol
*
* @return string
*/
public function getCurrentCurrencySymbol()
{
return $this->getCurrentCurrency()->symbol;
}
/**
* Format and convert price with currency symbol
*
* @param float $price
* @return string
*/
public function currency($price)
{
if(!$price)
$price = 0;
$channel = $this->getCurrentChannel();
$currencyCode = $channel->base_currency->code;
return currency($price, $currencyCode);
}
/**
* Checks if current date of the given channel (in the channel timezone) is within the range
*
* @param int|string|Channel $channel
* @param string|null $dateFrom
* @param string|null $dateTo
* @return bool
*/
public function isChannelDateInInterval($dateFrom = null, $dateTo = null)
{
$channel = $this->getCurrentChannel();
$channelTimeStamp = $this->channelTimeStamp($channel);
$fromTimeStamp = strtotime($dateFrom);
$toTimeStamp = strtotime($dateTo);
if ($dateTo) {
$toTimeStamp += 86400;
}
$result = false;
if (!$this->is_empty_date($dateFrom) && $channelTimeStamp < $fromTimeStamp) {
} elseif (!$this->is_empty_date($dateTo) && $channelTimeStamp > $toTimeStamp) {
} else {
$result = true;
}
return $result;
}
/**
* Get channel timestamp
* Timstamp will be builded with channel timezone settings
*
* @param mixed $channel
* @return int
*/
public function channelTimeStamp($channel)
{
$timezone = $channel->timezone;
$currentTimezone = @date_default_timezone_get();
@date_default_timezone_set($timezone);
$date = date('Y-m-d H:i:s');
@date_default_timezone_set($currentTimezone);
return strtotime($date);
}
/**
* Check whether sql date is empty
*
* @param string $date
* @return boolean
*/
function is_empty_date($date)
{
return preg_replace('#[ 0:-]#', '', $date) === '';
}
// $timezonelist = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL);
}

View File

@ -1,12 +0,0 @@
<?php
namespace Webkul\Core;
use Webkul\Core\Models\Locale as LocaleModel;
class Locale
{
public function all() {
return LocaleModel::all();
}
}

View File

@ -18,10 +18,12 @@ class CreateChannelsTable extends Migration
$table->string('code');
$table->string('name');
$table->text('description')->nullable();
$table->integer('default_locale')->unsigned();
$table->integer('base_currency')->unsigned();
$table->foreign('default_locale')->references('id')->on('locales')->onDelete('cascade');
$table->foreign('base_currency')->references('id')->on('currencies')->onDelete('cascade');
$table->string('timezone')->nullable();
$table->string('theme')->nullable();
$table->integer('default_locale_id')->unsigned();
$table->integer('base_currency_id')->unsigned();
$table->foreign('default_locale_id')->references('id')->on('locales')->onDelete('cascade');
$table->foreign('base_currency_id')->references('id')->on('currencies')->onDelete('cascade');
$table->timestamps();
});

View File

@ -167,4 +167,12 @@ abstract class Repository implements RepositoryInterface {
return $this;
}
/**
* @return mixed
*/
public function getModel()
{
return $this->model;
}
}

View File

@ -34,7 +34,7 @@ class TranslatableModel extends Model
protected function locale()
{
if($this->isChannelBased()) {
return channel()->getDefaultChannelLocaleCode();
return core()->getDefaultChannelLocaleCode();
} else {
if ($this->defaultLocale) {
return $this->defaultLocale;

View File

@ -1,10 +1,10 @@
<?php
namespace Webkul\Channel\Http\Controllers;
namespace Webkul\Core\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Channel\Repositories\ChannelRepository as Channel;
use Webkul\Core\Repositories\ChannelRepository as Channel;
/**
@ -32,7 +32,7 @@ class ChannelController extends Controller
/**
* Create a new controller instance.
*
* @param Webkul\Channel\Repositories\ChannelRepository $channel
* @param Webkul\Core\Repositories\ChannelRepository $channel
* @return void
*/
public function __construct(Channel $channel)

View File

@ -1,6 +1,6 @@
<?php
use Webkul\Core\Core;
if (! function_exists('core')) {
function core()
{

View File

@ -1,6 +1,6 @@
<?php
namespace Webkul\Channel\Models;
namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Core\Models\Locale;
@ -34,6 +34,8 @@ class Channel extends Model
return $this->belongsToMany(Currency::class, 'channel_currencies');
}
protected $with = ['base_currency'];
/**
* Get the base currency
*/

View File

@ -43,7 +43,7 @@ class CoreServiceProvider extends ServiceProvider
*/
public function register()
{
$this->registerCoreFacade();
$this->registerFacades();
}
/**
@ -51,7 +51,7 @@ class CoreServiceProvider extends ServiceProvider
*
* @return void
*/
protected function registerCoreFacade()
protected function registerFacades()
{
$loader = AliasLoader::getInstance();
$loader->alias('core', CoreFacade::class);

View File

@ -1,6 +1,6 @@
<?php
namespace Webkul\Channel\Repositories;
namespace Webkul\Core\Repositories;
use Webkul\Core\Eloquent\Repository;
@ -19,7 +19,7 @@ class ChannelRepository extends Repository
*/
function model()
{
return 'Webkul\Channel\Models\Channel';
return 'Webkul\Core\Models\Channel';
}
/**

View File

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

View File

@ -10,12 +10,13 @@ use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductInventory;
use Webkul\Product\Models\ProductImage;
use Webkul\Inventory\Models\InventorySource;
use Webkul\Product\Models\ProductReview;
class Product extends Model
{
protected $fillable = ['type', 'attribute_family_id', 'sku', 'parent_id'];
protected $with = ['attribute_family', 'attribute_values', 'variants', 'inventories'];
protected $with = ['attribute_family', 'attribute_values', 'inventories'];
/**
* Get the product attribute family that owns the product.
@ -41,6 +42,14 @@ class Product extends Model
return $this->hasMany(self::class, 'parent_id');
}
/**
* Get the product reviews that owns the product.
*/
public function reviews()
{
return $this->hasMany(ProductReview::class);
}
/**
* Get the product that owns the product.
*/
@ -122,6 +131,14 @@ class Product extends Model
{
return $this->attribute_family->custom_attributes->pluck('code')->contains($attribute);
}
/**
* @return bool
*/
public function getFinalPrice()
{
return 0.00;
}
/**
* Get an attribute from the model.
@ -131,38 +148,34 @@ class Product extends Model
*/
public function getAttribute($key)
{
if (!method_exists(self::class, $key) && !isset($this->attributes[$key])) {
$this->attributes[$key] = '';
if ($this->isCustomAttribute($key)) {
$attributeModel = $this->attribute_family->custom_attributes()->where('attributes.code', $key)->first();
if($attributeModel) {
$channel = request()->get('channel') ?: core()->getCurrentChannelCode();
$locale = request()->get('locale') ?: app()->getLocale();
if($attributeModel->value_per_channel) {
$channel = request()->get('channel') ?: channel()->getChannel();
if($attributeModel->value_per_locale) {
$locale = request()->get('locale') ?: app()->getLocale();
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('locale', $locale)->where('attribute_id', $attributeModel->id)->first();
} else {
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('attribute_id', $attributeModel->id)->first();
}
} else {
if($attributeModel->value_per_locale) {
$locale = request()->get('locale') ?: app()->getLocale();
$attributeValue = $this->attribute_values()->where('locale', $locale)->where('attribute_id', $attributeModel->id)->first();
} else {
$attributeValue = $this->attribute_values()->where('attribute_id', $attributeModel->id)->first();
}
}
if ($this->hasGetMutator($key)) {
$this->attributes[$key] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attributeModel->type]];
return $this->getAttributeValue($key);
}
return $attributeValue[ProductAttributeValue::$attributeTypeFields[$attributeModel->type]];
$this->attributes[$key] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attributeModel->type]];
}
return $this->getAttributeValue($key);
}
return $this->getAttributeValue($key);
@ -180,31 +193,30 @@ class Product extends Model
$hiddenAttributes = $this->getHidden();
$channel = request()->get('channel') ?: core()->getCurrentChannelCode();
$locale = request()->get('locale') ?: app()->getLocale();
foreach ($this->attribute_family->custom_attributes as $attribute) {
if (in_array($attribute->code, $hiddenAttributes)) {
continue;
}
if($attribute->value_per_channel) {
$channel = request()->get('channel') ?: channel()->getChannel();
if($attribute->value_per_locale) {
$locale = request()->get('locale') ?: app()->getLocale();
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
} else {
$attributeValue = $this->attribute_values()->where('channel', $channel)->where('attribute_id', $attribute->id)->first();
}
} else {
if($attribute->value_per_locale) {
$locale = request()->get('locale') ?: app()->getLocale();
$attributeValue = $this->attribute_values()->where('locale', $locale)->where('attribute_id', $attribute->id)->first();
} else {
$attributeValue = $this->attribute_values()->where('attribute_id', $attribute->id)->first();
}
}
if (!is_null($value = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]])) {
$attributes[$attribute->code] = $value;
}
$attributes[$attribute->code] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]];
}
return $attributes;

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\Product\Models;
use Illuminate\Database\Eloquent\Model;
class ProductReview extends Model
{
protected $fillable = [];
}

View File

@ -232,7 +232,7 @@ class ProductRepository extends Repository
if($attribute->value_per_channel) {
if($attribute->value_per_locale) {
foreach(channel()->getAllChannels() as $channel) {
foreach(core()->getAllChannels() as $channel) {
foreach(core()->getAllLocales() as $locale) {
$this->attributeValue->create([
'product_id' => $variant->id,
@ -244,7 +244,7 @@ class ProductRepository extends Repository
}
}
} else {
foreach(channel()->getAllChannels() as $channel) {
foreach(core()->getAllChannels() as $channel) {
$this->attributeValue->create([
'product_id' => $variant->id,
'attribute_id' => $attribute->id,

View File

@ -4,24 +4,65 @@ namespace Webkul\Shop\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Webkul\Category\Repositories\CategoryRepository as Category;
use Webkul\Product\Repositories\ProductRepository as Product;
/**
* Products Category controller
* Category controller
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class CategoryController extends controller
class CategoryController extends Controller
{
public function __construct()
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* CategoryRepository object
*
* @var array
*/
protected $category;
/**
* ProductRepository object
*
* @var array
*/
protected $product;
/**
* Create a new controller instance.
*
* @param Webkul\Category\Repositories\CategoryRepository $category
* @param Webkul\Product\Repositories\ProductRepository $product
* @return void
*/
public function __construct(Category $category, Product $product)
{
$this->product = $product;
$this->category = $category;
$this->_config = request('_config');
}
public function index()
/**
* Display a listing of the resource.
*
* @param string $slug
* @return \Illuminate\Http\Response
*/
public function index($slug)
{
return view($this->_config['view']);
$category = $this->category->findBySlugOrFail($slug);
return view($this->_config['view'], compact('category'));
}
}

View File

@ -21,16 +21,15 @@ use Webkul\Channel\Channel as Channel;
protected $sliders;
protected $current_channel;
public function __construct(Sliders $s,Channel $c)
public function __construct(Sliders $s)
{
$this->_config = request('_config');
$this->sliders = $s;
$this->current_channel = $c;
}
public function index() {
$current_channel = $this->current_channel->getCurrentChannel();
$current_channel = core()->getCurrentChannel();
$all_sliders = $this->sliders->findWhere(['channel_id'=>$current_channel['id']]);

View File

@ -1,44 +0,0 @@
<?php
namespace Webkul\Shop\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
/**
* Product controller
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ProductController extends Controller
{
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->_config = request('_config');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('shop::products.index');
// return view($this->_config['view']);
}
}

View File

@ -5,7 +5,6 @@ namespace Webkul\Shop\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Webkul\Channel\Channel;
use Webkul\Core\Repositories\SliderRepository as Slider;
/**
@ -44,8 +43,8 @@ class SliderController extends controller
*/
public function create() {
$call = new Channel();
$channels = $call->getAllChannels();
$channels = core()->getAllChannels();
return view($this->_config['view'])->with('channels',[$channels]);
}

View File

@ -3,10 +3,10 @@
Route::group(['middleware' => ['web']], function () {
Route::get('/', 'Webkul\Shop\Http\Controllers\HomeController@index')->defaults('_config', [
'view' => 'shop::store.home.index'
'view' => 'shop::home.index'
]);
Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\ProductController@index')->defaults('_config', [
Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')->defaults('_config', [
'view' => 'shop::products.index'
]);
});

View File

@ -0,0 +1,7 @@
<?php
namespace Webkul\Shop\Product;
abstract class AbstractProduct
{
}

View File

@ -0,0 +1,96 @@
<?php
namespace Webkul\Shop\Product;
use Illuminate\Support\Facades\DB;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
use Webkul\Product\Models\ProductAttributeValue;
class Collection extends AbstractProduct
{
/**
* ProductRepository object
*
* @var array
*/
protected $product;
/**
* AttributeRepository object
*
* @var array
*/
protected $attribute;
/**
* Create a new controller instance.
*
* @param Webkul\Product\Repositories\ProductRepository $product
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
* @return void
*/
public function __construct(Product $product, Attribute $attribute)
{
$this->product = $product;
$this->attribute = $attribute;
}
/**
* @param integer $categoryId
* @return Collection
*/
public function getProductCollection($categoryId = null, $attributeToSelect = '*')
{
$qb = $this->product->getModel()
->select('products.*')
->join('product_categories', 'products.id', '=', 'product_categories.product_id')
->where('product_categories.category_id', $categoryId);
$channel = core()->getCurrentChannelCode();
$locale = app()->getLocale();
foreach (['name', 'description', 'short_description', 'price', 'special_price', 'special_price_from', 'special_price_to'] as $code) {
$attribute = $this->attribute->findBy('code', $code);
$productValueAlias = 'pav_' . $attribute->code;
$qb->leftJoin('product_attribute_values as ' . $productValueAlias, function($leftJoin) use($channel, $locale, $attribute, $productValueAlias) {
$leftJoin->on('products.id', $productValueAlias . '.product_id');
if($attribute->value_per_channel) {
if($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.channel', $channel)
->where($productValueAlias . '.locale', $locale);
} else {
$leftJoin->where($productValueAlias . '.channel', $channel);
}
} else {
if($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.locale', $locale);
}
}
$leftJoin->where($productValueAlias . '.attribute_id', $attribute->id);
});
$qb->addSelect($productValueAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $code);
// if($code == 'name') {
// $filterAlias = 'filter_' . $attribute->code;
// $qb->leftJoin('product_attribute_values as ' . $filterAlias, 'products.id', '=', $filterAlias . '.product_id');
// $qb->where($filterAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type], 'Product Name');
// }
}
// if(0) {
// $qb->orderBy('id', 'desc');
// }
return $qb->paginate(9);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Webkul\Shop\Product;
class Price extends AbstractProduct
{
/**
* Returns the product's minimal price
*
* @return float
*/
public function getMinimalPrice($product)
{
// return 0;
if($product->type == 'configurable') {
return $product->variants->min('price');
} else {
if($this->haveSpecialPrice($product)) {
return $product->special_price;
} else {
return $product->price;
}
}
}
/**
* Returns the product's minimal price
*
* @return float
*/
public function getSpecialPrice($product)
{
if($this->haveSpecialPrice($product)) {
return $product->special_price;
} else {
return $product->price;
}
}
/**
* @param Product $product
* @return boolean
*/
public function haveSpecialPrice($product)
{
if(is_null($product->special_price) || !$product->special_price)
return false;
if (core()->isChannelDateInInterval($product->special_price_from, $product->special_price_to)) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Webkul\Shop\Product;
class Review extends AbstractProduct
{
/**
* Returns the product's avg rating
*
* @return float
*/
public function getAverageRating($product)
{
return round($product->reviews->average('rating'));
}
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="254px" height="236px" viewBox="0 0 254 236" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
<title>404-image</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Desktop" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.5">
<g id="404-page" transform="translate(-960.000000, -288.000000)">
<g id="404-image" transform="translate(961.000000, 289.000000)">
<polyline id="Path-3" stroke="#242424" stroke-width="3" points="0.626953125 0.990234375 34.3359375 26.4658203 34.6796875 73.1640625 34.3359375 186.773437 160.960938 215.992187 210.71875 130.375 34.3359375 72.71875"></polyline>
<g id="Group" transform="translate(46.000000, 190.000000)" fill="#FFFFFF" stroke="#242424" stroke-width="3">
<circle id="Oval" cx="22.5" cy="22.5" r="21"></circle>
<circle id="Oval" cx="23" cy="23" r="5.5"></circle>
</g>
<g id="Group" transform="translate(208.000000, 163.000000)" fill="#FFFFFF" stroke="#242424" stroke-width="3">
<circle id="Oval" cx="22.5" cy="22.5" r="21"></circle>
<circle id="Oval" cx="23" cy="23" r="5.5"></circle>
</g>
<path d="M178,205 L182,205 L182,208 L178,208 L178,205 Z M185,205 L206,205 L206,208 L185,208 L185,205 Z" id="Combined-Shape" fill="#242424" transform="translate(192.000000, 206.500000) rotate(-23.000000) translate(-192.000000, -206.500000) "></path>
<path d="M172.473165,218.350993 L176.473165,218.350993 L176.473165,221.350993 L172.473165,221.350993 L172.473165,218.350993 Z M179.473165,218.350993 L200.473165,218.350993 L200.473165,221.350993 L179.473165,221.350993 L179.473165,218.350993 Z" id="Combined-Shape" fill="#242424" transform="translate(186.473165, 219.850993) rotate(-23.000000) translate(-186.473165, -219.850993) "></path>
<path d="M198.610065,126.237911 L222.219028,78.9333292 L163.963322,59.4411726 L147.719875,109.950161 L198.610065,126.237911 Z" id="Path-4" stroke="#242424" stroke-width="3"></path>
<polyline id="Path-5" stroke="#242424" stroke-width="3" points="131.557617 105.489258 134.746094 71.9423828 157.437808 79.0096878"></polyline>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 928 B

View File

Before

Width:  |  Height:  |  Size: 905 B

After

Width:  |  Height:  |  Size: 905 B

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,8 @@ return [
],
'products' => [
'layered-nav-title' => 'Shop By'
'layered-nav-title' => 'Shop By',
'price-label' => 'As low as',
'remove-filter-link-title' => 'Clear All'
]
];

View File

@ -4,7 +4,7 @@
<span class="featured-seperator" style="color:lightgrey;">_____</span>
</div>
<div class="featured-grid">
<div class="featured-grid product-grid max-4-col">
<div class="product-card">
<div class="product-image">
<img src="vendor/webkul/shop/assets/images/grid.png" />

View File

@ -1,11 +1,13 @@
@extends('shop::layouts.master')
@section('slider')
@include('shop::layouts.slider')
@include('shop::home.slider')
@endsection
@section('content-wrapper')
@include('shop::grids.featured.featuredproductgrid')
@include('shop::grids.newproduct.newproductgrid')
@include('shop::grids.newsupdate.newsupdategrid')
@include('shop::home.featured-products')
@include('shop::home.new-products')
@include('shop::home.news-updates')
@endsection

View File

@ -4,7 +4,7 @@
<span class="featured-seperator" style="color:lightgrey;">_____</span>
</div>
<div class="featured-grid">
<div class="new-product-grid product-grid max-4-col">
<div class="product-card">
<div class="product-image">
<img src="vendor/webkul/shop/assets/images/new.png" />
@ -25,6 +25,7 @@
<span><img src="vendor/webkul/shop/assets/images/wishadd.svg" /></span>
</div>
</div>
<div class="product-card">
<div class="product-image">
<img src="vendor/webkul/shop/assets/images/new.png" />
@ -45,6 +46,7 @@
<span><img src="vendor/webkul/shop/assets/images/wishadd.svg" /></span>
</div>
</div>
<div class="product-card">
<div class="product-image">
<img src="vendor/webkul/shop/assets/images/new.png" />
@ -65,6 +67,7 @@
<span><img src="vendor/webkul/shop/assets/images/wishadd.svg" /></span>
</div>
</div>
<div class="product-card">
<div class="product-image">
<img src="vendor/webkul/shop/assets/images/new.png" />

View File

@ -0,0 +1 @@
<button class="btn btn-md btn-primary addtocart">Add to Cart</button>

View File

@ -0,0 +1,7 @@
<div class="cart-fav-seg">
@include ('shop::products.add-to-cart', ['product' => $product])
<span><img src="{{ bagisto_asset('images/wishlist.svg') }}" /></span>
</div>

View File

@ -0,0 +1,20 @@
<div class="product-card">
<div class="product-image">
<img src="{{ bagisto_asset('images/gogs.png') }}" />
</div>
<div class="product-name">
<span>{{ $product->name }}</span>
</div>
@include ('shop::products.price', ['product' => $product])
@if ($product->reviews->count())
@include ('shop::products.review', ['product' => $product])
@endif
@include ('shop::products.add-to', ['product' => $product])
</div>

View File

@ -4,6 +4,30 @@
@include ('shop::products.layered-navigation')
<div class="main" style="display: inline-block">
<div class="product-grid max-3-col">
@inject ('productHelper', 'Webkul\Shop\Product\Collection')
<?php $products = $productHelper->getProductCollection($category->id); ?>
@foreach ($products as $product)
@include ('shop::products.card', ['product' => $product])
@endforeach
</div>
<div class="bottom-toolbar">
{{ $products->appends(request()->input())->links() }}
</div>
</div>
@stop
@push('scripts')

View File

@ -1,11 +1,13 @@
@inject ('attributeRepository', 'Webkul\Attribute\Repositories\AttributeRepository')
<layered-navigation></layered-navigation>
<div class="layered-filter-wrapper">
<layered-navigation></layered-navigation>
</div>
@push('scripts')
<script type="text/x-template" id="layered-navigation-template">
<div class="layered-filter-wrapper">
<div>
<div class="filter-title">
{{ __('shop::app.products.layered-nav-title') }}
</div>
@ -14,7 +16,8 @@
<div class="filter-attributes">
<filter-attribute-item v-for='(attribute, index) in attributes' :attribute="attribute" :key="index" :index="index" @onFilterAdded="addFilters(attribute.code, $event)"></filter-attribute-item>
<filter-attribute-item v-for='(attribute, index) in attributes' :attribute="attribute" :key="index" :index="index" @onFilterAdded="addFilters(attribute.code, $event)" :appliedFilterValues="appliedFilters[attribute.code]">
</filter-attribute-item>
</div>
@ -29,7 +32,13 @@
<div class="filter-attributes-title" @click="active = !active">
@{{ attribute.name }}
<i class="icon" :class="[active ? 'arrow-up-icon' : 'arrow-down-icon']"></i>
<div class="pull-right">
<span class="remove-filter-link" v-if="appliedFilters.length" @click.stop="clearFilters()">
{{ __('shop::app.products.remove-filter-link-title') }}
</span>
<i class="icon" :class="[active ? 'arrow-up-icon' : 'arrow-down-icon']"></i>
</div>
</div>
<div class="filter-attributes-content">
@ -38,7 +47,7 @@
<li class="item" v-for='(option, index) in attribute.options'>
<span class="checkbox">
<input type="checkbox" :id="option.id" :value="option.id" @change="addFilter($event)"/>
<input type="checkbox" :id="option.id" v-bind:value="option.id" v-model="appliedFilters" @change="addFilter($event)"/>
<label class="checkbox-view" :for="option.id"></label>
@{{ option.label }}
</span>
@ -73,6 +82,16 @@
appliedFilters: {}
}),
created () {
var urlParams = new URLSearchParams(window.location.search);
var entries = urlParams.entries();
for(pair of entries) {
this.appliedFilters[pair[0]] = pair[1].split(',');
}
},
methods: {
addFilters (attributeCode, filters) {
if(filters.length) {
@ -80,6 +99,18 @@
} else {
delete this.appliedFilters[attributeCode];
}
this.applyFilter()
},
applyFilter () {
var params = [];
for(key in this.appliedFilters) {
params.push(key + '=' + this.appliedFilters[key].join(','))
}
window.location.href = "?" + params.join('&');
}
}
@ -89,11 +120,13 @@
template: '#filter-attribute-item-template',
props: ['index', 'attribute'],
props: ['index', 'attribute', 'appliedFilterValues'],
data: () => ({
appliedFilters: [],
active: false,
sliderConfig: {
value: [
100,
@ -113,23 +146,37 @@
created () {
if(!this.index)
this.active = true;
if(this.appliedFilterValues && this.appliedFilterValues.length) {
this.appliedFilters = this.appliedFilterValues;
if(this.attribute.type == 'price') {
this.sliderConfig.value = this.appliedFilterValues;
}
this.active = true;
}
},
methods: {
addFilter (e) {
if(event.target.checked) {
this.appliedFilters.push(event.target.value);
} else {
let index = this.appliedFilters.indexOf(event.target.value)
this.appliedFilters.splice(index, 1)
}
this.$emit('onFilterAdded', this.appliedFilters)
},
priceRangeUpdated (value) {
console.log(value)
this.appliedFilters = value;
this.$emit('onFilterAdded', this.appliedFilters)
},
clearFilters () {
if(this.attribute.type == 'price') {
this.sliderConfig.value = [100, 250];
}
this.appliedFilters = [];
this.$emit('onFilterAdded', this.appliedFilters)
}
}

View File

@ -0,0 +1,27 @@
<div class="product-price">
@inject ('priceHelper', 'Webkul\Shop\Product\Price')
@if ($product->type == 'configurable')
<span class="price-label">{{ __('shop::app.products.price-label') }}</span>
<span>{{ core()->currency($priceHelper->getMinimalPrice($product)) }}</span>
@else
@if ($priceHelper->haveSpecialPrice($product))
<span class="regular-price">{{ core()->currency($product->price) }}</span>
<span class="special-price">{{ core()->currency($priceHelper->getSpecialPrice($product)) }}</span>
@else
<span>{{ core()->currency($product->price) }}</span>
@endif
@endif
</div>

View File

@ -0,0 +1,11 @@
<div class="product-ratings">
@inject ('reviewHelper', 'Webkul\Shop\Product\Review')
@for ($i = 1; $i <= $reviewHelper->getAverageRating($product); $i++)
<span class="icon star-icon"></span>
@endfor
</div>

View File

@ -11,6 +11,7 @@ use Webkul\Ui\DataGrid\Helpers\Pagination;
use Webkul\Ui\DataGrid\Helpers\Css;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Models\ProductAttributeValue;
use URL;
/**
@ -151,6 +152,15 @@ class ProductGrid
protected $actions;
/**
* Attribute Columns
* for columns which
* are attributes.
*
* @var $attributeColumns
*/
protected $attributeColumns;
/**
* URL parse $parsed
@ -165,9 +175,9 @@ class ProductGrid
// list($name, $select, $table, $join, $columns) = array_values($args);
$name = $select = $aliased = $table = false;
$join = $columns = $filterable = $searchable =
$massoperations = $css = $operators = $actions = [];
$massoperations = $attributeColumns = $css = $operators = $actions = [];
extract($args);
return $this->build($name, $select, $filterable, $searchable, $massoperations, $aliased, $perpage, $table, $join, $columns, $css, $operators,$actions);
return $this->build($name, $select, $filterable, $searchable, $massoperations, $attributeColumns , $aliased, $perpage, $table, $join, $columns, $css, $operators,$actions);
}
//contructor for getting the current locale and channel
@ -176,14 +186,12 @@ class ProductGrid
private $channel;
private $attributes;
private $allAttributes;
private $product_attribute_values;
public function __construct(AttributeRepository $attributes, ProductAttributeValueRepository $product_attribute_values) {
public function __construct(AttributeRepository $attributes) {
$this->channel = request()->get('channel') ?: channel()->getChannel();
$this->locale = request()->get('locale') ?: app()->getLocale();
$this->attributes = $attributes;
$this->product_attribute_values = $product_attribute_values;
}
@ -194,6 +202,7 @@ class ProductGrid
array $filterable = [],
array $searchable = [],
array $massoperations = [],
array $attributeColumns = [],
bool $aliased = false,
$perpage = 0,
$table = null,
@ -210,6 +219,7 @@ class ProductGrid
$this->setFilterable($filterable);
$this->setSearchable($filterable);
$this->setMassOperations($massoperations);
$this->setAttributeColumns($attributeColumns);
$this->setAlias($aliased);
$this->setPerPage($perpage);
$this->setTable($table);
@ -344,6 +354,18 @@ class ProductGrid
return $this->css;
}
/**
* To set the attributes
* bag on product datagrid.
*
* @return $this
*/
private function setAttributeColumns($attributes = []) {
$this->attributeColumns = $attributes;
return $this->attributeColumns;
}
/**
* setFilterableColumns
* @return $this
@ -544,6 +566,50 @@ class ProductGrid
}
}
public function getProducts() {
$qb = DB::table('products')->addSelect('products.*');
$channel = core()->getCurrentChannelCode();
$locale = app()->getLocale();
foreach (['name', 'description', 'short_description', 'price'] as $code) {
$attribute = $this->attributes->findBy('code', $code);
$productValueAlias = 'pav_' . $attribute->code;
$qb->leftJoin('product_attribute_values as ' . $productValueAlias, function($leftJoin) use($channel, $locale, $attribute, $productValueAlias) {
$leftJoin->on('products.id', $productValueAlias . '.product_id');
if($attribute->value_per_channel) {
if($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.channel', $channel)
->where($productValueAlias . '.locale', $locale);
} else {
$leftJoin->where($productValueAlias . '.channel', $channel);
}
} else {
if($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.locale', $locale);
}
}
$leftJoin->where($productValueAlias . '.attribute_id', $attribute->id);
});
$qb->addSelect($productValueAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $code);
if($code == 'name') {
$filterAlias = 'filter_' . $attribute->code;
$qb->leftJoin('product_attribute_values as ' . $filterAlias, 'products.id', '=', $filterAlias . '.product_id');
$qb->where($filterAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type], 'Product Name');
}
}
}
/**
* ->join('contacts', 'users.id', '=', 'contacts.user_id')
* @return $this->query
@ -551,9 +617,48 @@ class ProductGrid
private function getQueryWithJoin()
{
foreach ($this->join as $join) {
$this->query->{$join['join']}($join['table'], $join['primaryKey'], $join['condition'], $join['secondaryKey']);
if(array_key_exists('withAttributes',$join)) {
$qb = $this->query;
$channel = $this->channel;
$locale = $this->locale;
foreach ($this->attributeColumns as $code) {
$attribute = $this->attributes->findBy('code', $code);
$productValueAlias = 'pav_' . $attribute->code;
$qb->leftJoin('product_attribute_values as ' . $productValueAlias, function ($leftJoin) use ($channel, $locale, $attribute, $productValueAlias) {
$leftJoin->on('prods.id', $productValueAlias . '.product_id');
if ($attribute->value_per_channel) {
if ($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.channel', $channel)->where($productValueAlias . '.locale', $locale);
} else {
$leftJoin->where($productValueAlias . '.channel', $channel);
}
} else {
if ($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.locale', $locale);
}
}
$leftJoin->where($productValueAlias . '.attribute_id', $attribute->id);
});
$qb->addSelect($productValueAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $code);
}
}
else
$this->query->{$join['join']}($join['table'], $join['primaryKey'], $join['condition'], $join['secondaryKey']);
}
$this->query->get();
}
@ -806,11 +911,7 @@ class ProductGrid
$this->getQueryWithFilters();
}
// $this->results = $this->query->get();
// $this->results = $this->query->distinct()->paginate($this->perpage)->appends(request()->except('page'));
$this->results = $this->query->paginate($this->perpage)->appends(request()->input());
return $this->results;
} else {
@ -825,10 +926,7 @@ class ProductGrid
$this->getQueryWithFilters();
}
// $this->results = $this->query->get();
$this->results = $this->query->distinct()->paginate($this->perpage)->appends(request()->except('page'));
$this->results = $this->query->distinct()->paginate($this->perpage)->appends(request()->input());
return $this->results;
}
}
@ -845,13 +943,13 @@ class ProductGrid
{
$this->allAttributes = $this->getAttributes();
// dump($this->channel, $this->locale);
$this->getDbQueryResults();
// dd($this->results);
return view('ui::datagrid.index', [
'css' => $this->css,
'results' => $this->results,
'columns' => $this->columns,
'attribute_columns' => $this->attributeColumns,
'filterable' =>$this->filterable,
'operators' => $this->operators,
'massoperations' => $this->massoperations,

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
<title>star</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="star" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="Star" fill="#242424" fill-rule="nonzero" points="7.99999999 13.2668737 3.05572808 16 4 10.2111456 0 6.11145618 5.52786404 5.26687371 7.99999999 0 10.472136 5.26687371 16 6.11145618 12 10.2111456 12.9442719 16"></polygon>
</g>
</svg>

After

Width:  |  Height:  |  Size: 683 B

View File

@ -8,7 +8,6 @@
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-weight: 500;
}
*:focus {

View File

@ -158,6 +158,12 @@
height: 24px;
}
.star-icon {
background-image: url("../images/Star-Icon.svg");
width: 24px;
height: 24px;
}
.active {
.dashboard-icon {
background-image: url("../images/Icon-Dashboard-Active.svg");

View File

@ -89,21 +89,30 @@
<label class="checkbox-view" for="checkbox"></label>
</span>
</th>
@foreach ($columns as $column) @if($column->sortable == "true")
<th class="grid_head"
@if(strpos($column->alias, ' as '))
<?php $exploded_name = explode(' as ',$column->name); ?>
data-column-name="{{ $exploded_name[0] }}"
@else
data-column-name="{{ $column->alias }}"
@endif
@foreach ($columns as $column)
@if($column->sortable == "true")
<th class="grid_head"
@if(strpos($column->alias, ' as '))
<?php $exploded_name = explode(' as ',$column->name); ?>
data-column-name="{{ $exploded_name[0] }}"
@else
data-column-name="{{ $column->alias }}"
@endif
data-column-label="{{ $column->label }}"
data-column-sort="asc">{!! $column->sorting() !!}<span class="icon sort-down-icon"></span>
</th>
@else
<th class="grid_head" data-column-name="{{ $column->alias }}" data-column-label="{{ $column->label }}">{!! $column->sorting() !!}</th>
@endif @endforeach
data-column-label="{{ $column->label }}"
data-column-sort="asc">{!! $column->sorting() !!}<span class="icon sort-down-icon"></span>
</th>
@else
<th class="grid_head" data-column-name="{{ $column->alias }}" data-column-label="{{ $column->label }}">{!! $column->sorting() !!}</th>
@endif
@endforeach
@if(isset($attribute_columns))
@foreach($attribute_columns as $key => $value)
<th>
{{ $value }}
</th>
@endforeach
@endif
<th>
Actions
</th>
@ -112,6 +121,7 @@
<tbody class="{{ $css->tbody }}">
@foreach ($results as $result)
<tr>
<td class="">
<span class="checkbox">
<input type="checkbox" class="indexers" id="{{ $result->id }}" name="checkbox[]">
@ -119,12 +129,16 @@
</span>
</td>
@foreach ($columns as $column)
<td class="">{!! $column->render($result) !!}</td>
<td class="">{!! $column->render($result) !!}</td>
@endforeach
@foreach ($attribute_columns as $atc)
<td>{{ $result->{$atc} }}</td>
@endforeach
<td class="action">
@foreach($actions as $action)
<a @if($action['type']=="Edit") href="{{ url()->current().'/edit/'.$result->id }}" @elseif($action['type']=="Delete") href="{{ url()->current().'/delete/'.$result->id }}" @endif class="Action-{{ $action['type'] }}" id="{{ $result->id }}" onclick="return confirm_click('{{ $action['confirm_text'] }}');">
<a @if($action['type'] == "Edit") href="{{ url()->current().'/edit/'.$result->id }}" @elseif($action['type']=="Delete") href="{{ url()->current().'/delete/'.$result->id }}" @endif class="Action-{{ $action['type'] }}" id="{{ $result->id }}" onclick="return confirm_click('{{ $action['confirm_text'] }}');">
<i class="{{ $action['icon'] }}"></i>
</a>
@endforeach

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Wishlist-Add</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Wishlist-Add" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<path d="M15.9962711,26 C15.9962711,26 3.82641602,21.6804199 5.05062701,11.3846154 C5.38182072,8.59922485 8.45774362,6 11.3052808,6 C13.3974625,6 15.1753096,7.5626878 15.9962711,9.07692308 C16.9857769,7.57771184 18.5950798,6 20.6872614,6 C23.5347986,6 26.6121993,8.59909844 26.9419152,11.3846154 C28.2089844,22.0891113 15.9962711,26 15.9962711,26 Z" id="heart" stroke="#FF6472" stroke-width="3" fill="#FF6472" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 928 B

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>Wishlist</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Wishlist" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<path d="M15.9962711,26 C15.9962711,26 3.82641602,21.6804199 5.05062701,11.3846154 C5.38182072,8.59922485 8.45774362,6 11.3052808,6 C13.3974625,6 15.1753096,7.5626878 15.9962711,9.07692308 C16.9857769,7.57771184 18.5950798,6 20.6872614,6 C23.5347986,6 26.6121993,8.59909844 26.9419152,11.3846154 C28.2089844,22.0891113 15.9962711,26 15.9962711,26 Z" id="heart" stroke="#FF6472" stroke-width="3" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 905 B