For demo
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@if ($product->type == 'configurable')
|
||||
|
||||
@section('css')
|
||||
@parent
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -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 }}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
/node_modules
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
use Webkul\Channel\Channel;
|
||||
|
||||
if (! function_exists('channel')) {
|
||||
function channel()
|
||||
{
|
||||
return new Channel;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Core;
|
||||
|
||||
use Webkul\Core\Models\Locale as LocaleModel;
|
||||
|
||||
class Locale
|
||||
{
|
||||
public function all() {
|
||||
return LocaleModel::all();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
|
@ -167,4 +167,12 @@ abstract class Repository implements RepositoryInterface {
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getModel()
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
use Webkul\Core\Core;
|
||||
|
||||
|
||||
if (! function_exists('core')) {
|
||||
function core()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ProductReview extends Model
|
||||
{
|
||||
protected $fillable = [];
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Shop\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Webkul\Category\Repositories\CategoryRepository as Category;
|
||||
use Webkul\Product\Repositories\ProductRepository as Product;
|
||||
|
||||
/**
|
||||
* Category controller
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* 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');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index($slug)
|
||||
{
|
||||
$category = $this->category->findBySlugOrFail($slug);
|
||||
|
||||
return view($this->_config['view'], compact('category'));
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ use Illuminate\Http\Request;
|
|||
use Illuminate\Http\Response;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Webkul\Core\Repositories\SliderRepository as Sliders;
|
||||
use Webkul\Channel\Channel as Channel;
|
||||
/**
|
||||
* Admin user session controller
|
||||
*
|
||||
|
|
@ -19,16 +18,15 @@ class HomeController extends controller
|
|||
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']]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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']);
|
||||
}
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,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'
|
||||
]);
|
||||
});
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Shop\Product;
|
||||
|
||||
abstract class AbstractProduct
|
||||
{
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 928 B After Width: | Height: | Size: 928 B |
|
Before Width: | Height: | Size: 905 B After Width: | Height: | Size: 905 B |
|
|
@ -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'
|
||||
]
|
||||
];
|
||||
|
|
@ -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" />
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
@ -0,0 +1 @@
|
|||
<button class="btn btn-md btn-primary addtocart">Add to Cart</button>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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 |
|
|
@ -8,7 +8,6 @@
|
|||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
*:focus {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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 |