resolve conflict in Bundle.php
20
.env.example
|
|
@ -47,3 +47,23 @@ PUSHER_APP_CLUSTER=mt1
|
|||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
FACEBOOK_CLIENT_ID=
|
||||
FACEBOOK_CLIENT_SECRET=
|
||||
FACEBOOK_CALLBACK_URL=https://yourhost.com/customer/social-login/facebook/callback
|
||||
|
||||
TWITTER_CLIENT_ID=
|
||||
TWITTER_CLIENT_SECRET=
|
||||
TWITTER_CALLBACK_URL=https://yourhost.com/customer/social-login/twitter/callback
|
||||
|
||||
GOGGLE_CLIENT_ID=
|
||||
GOGGLE_CLIENT_SECRET=
|
||||
GOGGLE_CALLBACK_URL=https://yourhost.com/customer/social-login/google/callback
|
||||
|
||||
LINKEDIN_CLIENT_ID=
|
||||
LINKEDIN_CLIENT_SECRET=
|
||||
LINKEDIN_CALLBACK_URL=https://yourhost.com/customer/social-login/linkedin/callback
|
||||
|
||||
GITHUB_CLIENT_ID=
|
||||
GITHUB_CLIENT_SECRET=
|
||||
GITHUB_CALLBACK_URL=https://yourhost.com/customer/social-login/github/callback
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/d/total.svg" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/v/stable.svg" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/license.svg" alt="License"></a>
|
||||
<a href="https://github.com/bagisto/bagisto/actions"><img src="https://github.com/bagisto/bagisto/workflows/CI/badge.svg" alt="Backers on Open Collective"></a>
|
||||
<a href="#backers"><img src="https://opencollective.com/bagisto/backers/badge.svg" alt="Backers on Open Collective"></a>
|
||||
<a href="#sponsors"><img src="https://opencollective.com/bagisto/sponsors/badge.svg" alt="Sponsors on Open Collective"></a>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
"ext-pdo": "*",
|
||||
"ext-pdo_mysql": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"algolia/algoliasearch-client-php": "^2.2",
|
||||
"astrotomic/laravel-translatable": "^11.0.0",
|
||||
"babenkoivan/elastic-scout-driver": "^1.1",
|
||||
"barryvdh/laravel-debugbar": "^3.1",
|
||||
"barryvdh/laravel-dompdf": "0.8.6",
|
||||
"doctrine/dbal": "2.9.2",
|
||||
|
|
@ -30,6 +32,8 @@
|
|||
"kalnoy/nestedset": "5.0.1",
|
||||
"konekt/concord": "^1.2",
|
||||
"laravel/framework": "^7.0",
|
||||
"laravel/scout": "^8.0",
|
||||
"laravel/socialite": "^4.4",
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravel/ui": "^2.0",
|
||||
"maatwebsite/excel": "3.1.19",
|
||||
|
|
@ -103,7 +107,8 @@
|
|||
"Webkul\\Rule\\": "packages/Webkul/Rule/src",
|
||||
"Webkul\\CMS\\": "packages/Webkul/CMS/src",
|
||||
"Webkul\\Velocity\\": "packages/Webkul/Velocity/src",
|
||||
"Webkul\\BookingProduct\\": "packages/Webkul/BookingProduct/src"
|
||||
"Webkul\\BookingProduct\\": "packages/Webkul/BookingProduct/src",
|
||||
"Webkul\\SocialLogin\\": "packages/Webkul/SocialLogin/src"
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -268,6 +268,7 @@ return [
|
|||
Webkul\CMS\Providers\CMSServiceProvider::class,
|
||||
Webkul\Velocity\Providers\VelocityServiceProvider::class,
|
||||
Webkul\BookingProduct\Providers\BookingProductServiceProvider::class,
|
||||
Webkul\SocialLogin\Providers\SocialLoginServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -24,5 +24,6 @@ return [
|
|||
\Webkul\CartRule\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\CMS\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Velocity\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\SocialLogin\Providers\ModuleServiceProvider::class,
|
||||
]
|
||||
];
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'hosts' => [
|
||||
env('ELASTIC_HOST', 'localhost:9200'),
|
||||
]
|
||||
];
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'refresh_documents' => env('ELASTIC_SCOUT_DRIVER_REFRESH_DOCUMENTS', false)
|
||||
];
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Search Engine
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default search connection that gets used while
|
||||
| using Laravel Scout. This connection is used when syncing all models
|
||||
| to the search service. You should adjust this based on your needs.
|
||||
|
|
||||
| Supported: "algolia", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => env('SCOUT_DRIVER', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Index Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify a prefix that will be applied to all search index
|
||||
| names used by Scout. This prefix may be useful if you have multiple
|
||||
| "tenants" or applications sharing the same search infrastructure.
|
||||
|
|
||||
*/
|
||||
|
||||
'prefix' => env('SCOUT_PREFIX', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Queue Data Syncing
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows you to control if the operations that sync your data
|
||||
| with your search engines are queued. When this is set to "true" then
|
||||
| all automatic data syncing will get queued for better performance.
|
||||
|
|
||||
*/
|
||||
|
||||
'queue' => env('SCOUT_QUEUE', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Chunk Sizes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These options allow you to control the maximum chunk size when you are
|
||||
| mass importing data into the search engine. This allows you to fine
|
||||
| tune each of these chunk sizes based on the power of the servers.
|
||||
|
|
||||
*/
|
||||
|
||||
'chunk' => [
|
||||
'searchable' => 500,
|
||||
'unsearchable' => 500,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Soft Deletes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows to control whether to keep soft deleted records in
|
||||
| the search indexes. Maintaining soft deleted records can be useful
|
||||
| if your application still needs to search for the records later.
|
||||
|
|
||||
*/
|
||||
|
||||
'soft_delete' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Algolia Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure your Algolia settings. Algolia is a cloud hosted
|
||||
| search engine which works great with Scout out of the box. Just plug
|
||||
| in your application ID and admin API key to get started searching.
|
||||
|
|
||||
*/
|
||||
|
||||
'algolia' => [
|
||||
'id' => env('ALGOLIA_APP_ID', ''),
|
||||
'secret' => env('ALGOLIA_SECRET', ''),
|
||||
],
|
||||
|
||||
];
|
||||
|
|
@ -46,5 +46,35 @@ return [
|
|||
'model' => App\User::class,
|
||||
'key' => env('STRIPE_KEY'),
|
||||
'secret' => env('STRIPE_SECRET'),
|
||||
]
|
||||
],
|
||||
|
||||
'facebook' => [
|
||||
'client_id' => env('FACEBOOK_CLIENT_ID'),
|
||||
'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
|
||||
'redirect' => env('FACEBOOK_CALLBACK_URL'),
|
||||
],
|
||||
|
||||
'twitter' => [
|
||||
'client_id' => env('TWITTER_CLIENT_ID'),
|
||||
'client_secret' => env('TWITTER_CLIENT_SECRET'),
|
||||
'redirect' => env('TWITTER_CALLBACK_URL'),
|
||||
],
|
||||
|
||||
'google' => [
|
||||
'client_id' => env('GOOGLE_CLIENT_ID'),
|
||||
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
|
||||
'redirect' => env('GOOGLE_CALLBACK_URL'),
|
||||
],
|
||||
|
||||
'linkedin' => [
|
||||
'client_id' => env('LINKEDIN_CLIENT_ID'),
|
||||
'client_secret' => env('LINKEDIN_CLIENT_SECRET'),
|
||||
'redirect' => env('LINKEDIN_CALLBACK_URL'),
|
||||
],
|
||||
|
||||
'github' => [
|
||||
'client_id' => env('GITHUB_CLIENT_ID'),
|
||||
'client_secret' => env('GITHUB_CLIENT_SECRET'),
|
||||
'redirect' => env('GITHUB_CALLBACK_URL'),
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,16 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Blade File Tracer
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Shows blade file path in front
|
||||
|
|
||||
*/
|
||||
|
||||
'tracer' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -100,10 +100,11 @@ class Order extends JsonResource
|
|||
'channel' => $this->when($this->channel_id, new ChannelResource($this->channel)),
|
||||
'shipping_address' => new OrderAddress($this->shipping_address),
|
||||
'billing_address' => new OrderAddress($this->billing_address),
|
||||
'updated_at' => $this->updated_at,
|
||||
'items' => OrderItem::collection($this->items),
|
||||
'invoices' => Invoice::collection($this->invoices),
|
||||
'shipments' => Shipment::collection($this->shipments),
|
||||
'downloadable_links' => $this->downloadable_link_purchased,
|
||||
'updated_at' => $this->updated_at,
|
||||
'created_at' => $this->created_at,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/admin.js": "/js/admin.js?id=a14c779523092ac32b88",
|
||||
"/css/admin.css": "/css/admin.css?id=c17742537767f5fbf06d"
|
||||
"/css/admin.css": "/css/admin.css?id=56c882a611bdf3c058cb"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use Webkul\User\Database\Seeders\DatabaseSeeder as UserSeeder;
|
|||
use Webkul\Customer\Database\Seeders\DatabaseSeeder as CustomerSeeder;
|
||||
use Webkul\Inventory\Database\Seeders\DatabaseSeeder as InventorySeeder;
|
||||
use Webkul\CMS\Database\Seeders\DatabaseSeeder as CMSSeeder;
|
||||
use Webkul\SocialLogin\Database\Seeders\DatabaseSeeder as SocialLoginSeeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
|
|
@ -27,5 +28,6 @@ class DatabaseSeeder extends Seeder
|
|||
$this->call(UserSeeder::class);
|
||||
$this->call(CustomerSeeder::class);
|
||||
$this->call(CMSSeeder::class);
|
||||
$this->call(SocialLoginSeeder::class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ body {
|
|||
|
||||
.dropdown-list {
|
||||
top: 63px;
|
||||
right: 0px !important;
|
||||
right: 0px;
|
||||
bottom: inherit !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,56 +102,6 @@
|
|||
float: left;
|
||||
}
|
||||
|
||||
// ui
|
||||
.grid-container {
|
||||
.filter-row-one .search-filter {
|
||||
border: 2px solid #c7c7c7;
|
||||
border-radius: 2px;
|
||||
|
||||
.control {
|
||||
border: none;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
border: none;
|
||||
padding-top: 2px;
|
||||
padding-right: 5px;
|
||||
border-right: 2px solid #c7c7c7;
|
||||
border-radius: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-row-two .filter-tag {
|
||||
.wrapper,
|
||||
.icon.cross-icon {
|
||||
margin-right: 10px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-row-one .dropdown-filters {
|
||||
right: unset;
|
||||
position: static !important;
|
||||
left: 25px;
|
||||
|
||||
.per-page-label {
|
||||
position: static !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-container
|
||||
.filter-wrapper
|
||||
.filter-row-one
|
||||
.dropdown-filters
|
||||
.more-filters
|
||||
.dropdown-toggle
|
||||
.dropdown-header
|
||||
span {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.grid-container .table tbody td.action a:first-child {
|
||||
margin-left: 10px;
|
||||
margin-right: 0px;
|
||||
|
|
@ -172,7 +122,7 @@
|
|||
|
||||
.dropdown-list.bottom-right {
|
||||
left: 0px;
|
||||
right: auto;
|
||||
right: auto !important;
|
||||
}
|
||||
|
||||
.dropdown-list .dropdown-container {
|
||||
|
|
|
|||
|
|
@ -1304,6 +1304,7 @@ return [
|
|||
'order-number-prefix' => 'بادئة رقم الطلب',
|
||||
'order-number-length' => 'طول رقم الطلب',
|
||||
'order-number-suffix' => 'لاحقة رقم الطلب',
|
||||
'order-number-generator-class' => 'مولد رقم الطلب',
|
||||
'default' => 'إفتراضي',
|
||||
'sandbox' => 'صندوق الرمل',
|
||||
'all-channels' => 'الكل',
|
||||
|
|
|
|||
|
|
@ -1318,6 +1318,7 @@ return array (
|
|||
'order-number-prefix' => 'Auftragsnummer Präfix',
|
||||
'order-number-length' => 'Auftragsnummer Länge',
|
||||
'order-number-suffix' => 'Auftragsnummer Suffix',
|
||||
'order-number-generator-class' => 'Bestell nummern generator',
|
||||
'default' => 'Standard',
|
||||
'sandbox' => 'Sandbox',
|
||||
'all-channels' => 'Alle',
|
||||
|
|
|
|||
|
|
@ -1309,6 +1309,7 @@ return [
|
|||
'order-number-prefix' => 'Order Number Prefix',
|
||||
'order-number-length' => 'Order Number Length',
|
||||
'order-number-suffix' => 'Order Number Suffix',
|
||||
'order-number-generator-class' => 'Order Number Generator',
|
||||
'default' => 'Default',
|
||||
'sandbox' => 'Sandbox',
|
||||
'all-channels' => 'All Channels',
|
||||
|
|
|
|||
|
|
@ -1310,6 +1310,7 @@ return [
|
|||
'order-number-prefix' => 'پیش شماره شماره سفارش',
|
||||
'order-number-length' => 'طول شماره سفارش',
|
||||
'order-number-suffix' => 'تعداد کافی شماره سفارش',
|
||||
'order-number-generator-class' => 'تولید کننده شماره سفارش',
|
||||
'default' => 'پیش فرض',
|
||||
'sandbox' => 'Sandbox',
|
||||
'all-channels' => 'همه',
|
||||
|
|
|
|||
|
|
@ -1314,6 +1314,7 @@ return [
|
|||
'order-number-prefix' => 'Prefisso Numero Ordine',
|
||||
'order-number-length' => 'Lunghezza Numero Ordine',
|
||||
'order-number-suffix' => 'Suffisso Numero Ordine',
|
||||
'order-number-generator-class' => 'Generatore di numeri dordine',
|
||||
'default' => 'Default',
|
||||
'sandbox' => 'Sandbox',
|
||||
'all-channels' => 'Tutti',
|
||||
|
|
|
|||
|
|
@ -1310,6 +1310,7 @@ return [
|
|||
'order-number-prefix' => 'Bestelnummer prefix',
|
||||
'order-number-length' => 'Bestelnummer Lengte',
|
||||
'order-number-suffix' => 'Achtervoegsel bestelnummer',
|
||||
'order-number-generator-class' => 'Ordernummer Generator',
|
||||
'default' => 'Standaard',
|
||||
'sandbox' => 'Sandbox',
|
||||
'all-channels' => 'Alles',
|
||||
|
|
|
|||
|
|
@ -1312,6 +1312,7 @@ return [
|
|||
'order-number-prefix' => 'Prefiks numeru zamówienia',
|
||||
'order-number-length' => 'Długość numeru zamówienia',
|
||||
'order-number-suffix' => 'Sufiks numeru zamówienia”',
|
||||
'order-number-generator-class' => 'Generator numeru zamówienia',
|
||||
'default' => 'Domyślna',
|
||||
'sandbox' => 'Piaskownica',
|
||||
'all-channels' => 'Wszystkie kanały',
|
||||
|
|
|
|||
|
|
@ -1313,6 +1313,7 @@ return [
|
|||
'order-number-prefix' => 'Prefixo do Número do Pedido',
|
||||
'order-number-length' => 'Tamanho do Número do Pedido',
|
||||
'order-number-suffix' => 'Sufixo do Número de Pedido',
|
||||
'order-number-generator-class' => 'Gerador de número de pedido',
|
||||
'default' => 'Padrão',
|
||||
'sandbox' => 'Sandbox',
|
||||
'all-channels' => 'Todos',
|
||||
|
|
|
|||
|
|
@ -1299,6 +1299,7 @@ return [
|
|||
'order-number-prefix' => 'Numara Ön Eki',
|
||||
'order-number-length' => 'Numara Uzunluğu',
|
||||
'order-number-suffix' => 'Numara Son Eki',
|
||||
'order-number-generator-class' => 'Sipariş Numarası Üreticisi',
|
||||
'default' => 'Varsayılan',
|
||||
'sandbox' => 'Havuz',
|
||||
'all-channels' => 'Tümü',
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
|
||||
<tbody>
|
||||
|
||||
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index" :index="index" @onRemoveVariant="removeVariant($event)"></variant-item>
|
||||
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index" :index="variant.id" @onRemoveVariant="removeVariant($event)"></variant-item>
|
||||
|
||||
</tbody>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<input type="text" v-validate="'{{$validations}}'" class="control" id="{{ $attribute->code }}" name="{{ $attribute->code }}" value="{{ old($attribute->code) ?: $product[$attribute->code] }}" {{ in_array($attribute->code, ['sku', 'url_key']) ? 'v-slugify' : '' }} data-vv-as=""{{ $attribute->admin_name }}"" {{ $attribute->code == 'name' ? 'v-slugify-target=\'url_key\'' : '' }} />
|
||||
<input type="text" v-validate="'{{$validations}}'" class="control" id="{{ $attribute->code }}" name="{{ $attribute->code }}" value="{{ old($attribute->code) ?: $product[$attribute->code] }}" {{ in_array($attribute->code, ['sku', 'url_key']) ? 'v-slugify' : '' }} data-vv-as=""{{ $attribute->admin_name }}"" {{ $attribute->code == 'name' && ! $product[$attribute->code] ? 'v-slugify-target=\'url_key\'' : '' }} />
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<div class="control-group" :class="[errors.has('city') ? 'has-error' : '']">
|
||||
<label for="city" class="required">{{ __('shop::app.customer.account.address.create.city') }}</label>
|
||||
<input type="text" class="control" name="city" v-validate="'required|alpha_spaces'" value="{{ old('city') }}" data-vv-as=""{{ __('shop::app.customer.account.address.create.city') }}"">
|
||||
<input type="text" class="control" name="city" v-validate="'required|regex:^[a-zA-Z \-]*$'" value="{{ old('city') }}" data-vv-as=""{{ __('shop::app.customer.account.address.create.city') }}"">
|
||||
<span class="control-error" v-if="errors.has('city')">@{{ errors.first('city') }}</span>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
|
||||
<div class="control-group" :class="[errors.has('city') ? 'has-error' : '']">
|
||||
<label for="city" class="required">{{ __('shop::app.customer.account.address.create.city') }}</label>
|
||||
<input type="text" class="control" name="city" v-validate="'required'" value="{{ old('city') ?: $address->city }}" data-vv-as=""{{ __('shop::app.customer.account.address.create.city') }}"">
|
||||
<input type="text" class="control" name="city" v-validate="'required|regex:^[a-zA-Z \-]*$'" value="{{ old('city') ?: $address->city }}" data-vv-as=""{{ __('shop::app.customer.account.address.create.city') }}"">
|
||||
<span class="control-error" v-if="errors.has('city')">@{{ errors.first('city') }}</span>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -138,14 +138,14 @@
|
|||
|
||||
{!! view_render_event('sales.order.customer_email.after', ['order' => $order]) !!}
|
||||
|
||||
@if (! is_null($order->customer))
|
||||
@if (! is_null($order->customer) && ! is_null($order->customer->group))
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.customers.customers.customer_group') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->customer->group['name'] }}
|
||||
{{ $order->customer->group->name }}
|
||||
</span>
|
||||
</div>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -10,13 +10,10 @@
|
|||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"cross-env": "^6.0.3",
|
||||
"jquery": "^3.4.1",
|
||||
"laravel-mix": "^5.0.0",
|
||||
"laravel-mix-merge-manifest": "^0.1.2",
|
||||
"sass": "^1.25.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vue": "^2.6.10"
|
||||
"sass-loader": "^8.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use Webkul\Product\Models\Product;
|
|||
$factory->define(BookingProductEventTicket::class, function (Faker $faker, array $attributes) {
|
||||
return [
|
||||
'price' => $faker->randomFloat(4, 3, 900),
|
||||
'qty' => $faker->randomNumber(2),
|
||||
'qty' => $faker->numberBetween(1, 99),
|
||||
'booking_product_id' => static function () {
|
||||
return factory(BookingProduct::class)->create(['type' => 'event'])->id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,15 @@ class Booking extends Virtual
|
|||
return app($this->bookingHelper->getTypeHelper($bookingProduct->type))->isItemHaveQuantity($cartItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add product. Returns error message if can't prepare product.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -24,5 +24,6 @@ return [
|
|||
\Webkul\CartRule\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\CMS\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\Velocity\Providers\ModuleServiceProvider::class,
|
||||
\Webkul\SocialLogin\Providers\ModuleServiceProvider::class,
|
||||
]
|
||||
];
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Search Engine
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default search connection that gets used while
|
||||
| using Laravel Scout. This connection is used when syncing all models
|
||||
| to the search service. You should adjust this based on your needs.
|
||||
|
|
||||
| Supported: "algolia", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => env('SCOUT_DRIVER', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Index Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify a prefix that will be applied to all search index
|
||||
| names used by Scout. This prefix may be useful if you have multiple
|
||||
| "tenants" or applications sharing the same search infrastructure.
|
||||
|
|
||||
*/
|
||||
|
||||
'prefix' => env('SCOUT_PREFIX', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Queue Data Syncing
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows you to control if the operations that sync your data
|
||||
| with your search engines are queued. When this is set to "true" then
|
||||
| all automatic data syncing will get queued for better performance.
|
||||
|
|
||||
*/
|
||||
|
||||
'queue' => env('SCOUT_QUEUE', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Chunk Sizes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These options allow you to control the maximum chunk size when you are
|
||||
| mass importing data into the search engine. This allows you to fine
|
||||
| tune each of these chunk sizes based on the power of the servers.
|
||||
|
|
||||
*/
|
||||
|
||||
'chunk' => [
|
||||
'searchable' => 500,
|
||||
'unsearchable' => 500,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Soft Deletes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option allows to control whether to keep soft deleted records in
|
||||
| the search indexes. Maintaining soft deleted records can be useful
|
||||
| if your application still needs to search for the records later.
|
||||
|
|
||||
*/
|
||||
|
||||
'soft_delete' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Algolia Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure your Algolia settings. Algolia is a cloud hosted
|
||||
| search engine which works great with Scout out of the box. Just plug
|
||||
| in your application ID and admin API key to get started searching.
|
||||
|
|
||||
*/
|
||||
|
||||
'algolia' => [
|
||||
'id' => env('ALGOLIA_APP_ID', ''),
|
||||
'secret' => env('ALGOLIA_SECRET', ''),
|
||||
],
|
||||
|
||||
];
|
||||
|
|
@ -7,6 +7,9 @@ use Illuminate\Database\Eloquent\Factory as EloquentFactory;
|
|||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Foundation\AliasLoader;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Webkul\Theme\ViewRenderEventManager;
|
||||
use Webkul\Core\View\Compilers\BladeCompiler;
|
||||
use Webkul\Core\Console\Commands\BookingCron;
|
||||
use Webkul\Core\Core;
|
||||
use Webkul\Core\Exceptions\Handler;
|
||||
|
|
@ -43,6 +46,7 @@ class CoreServiceProvider extends ServiceProvider
|
|||
|
||||
$this->publishes([
|
||||
dirname(__DIR__) . '/Config/concord.php' => config_path('concord.php'),
|
||||
dirname(__DIR__) . '/Config/scout.php' => config_path('scout.php'),
|
||||
]);
|
||||
|
||||
$this->app->bind(
|
||||
|
|
@ -51,6 +55,16 @@ class CoreServiceProvider extends ServiceProvider
|
|||
);
|
||||
|
||||
SliderProxy::observe(SliderObserver::class);
|
||||
|
||||
$this->loadViewsFrom(__DIR__ . '/../Resources/views', 'core');
|
||||
|
||||
Event::listen('bagisto.shop.layout.head', static function(ViewRenderEventManager $viewRenderEventManager) {
|
||||
$viewRenderEventManager->addTemplate('core::blade.tracer.style');
|
||||
});
|
||||
|
||||
Event::listen('bagisto.admin.layout.head', static function(ViewRenderEventManager $viewRenderEventManager) {
|
||||
$viewRenderEventManager->addTemplate('core::blade.tracer.style');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -63,6 +77,8 @@ class CoreServiceProvider extends ServiceProvider
|
|||
$this->registerFacades();
|
||||
|
||||
$this->registerCommands();
|
||||
|
||||
$this->registerBladeCompiler();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -109,4 +125,16 @@ class CoreServiceProvider extends ServiceProvider
|
|||
{
|
||||
$this->app->make(EloquentFactory::class)->load($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Blade compiler implementation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerBladeCompiler()
|
||||
{
|
||||
$this->app->singleton('blade.compiler', function ($app) {
|
||||
return new BladeCompiler($app['files'], $app['config']['view.compiled']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'path-hint' => [
|
||||
'template' => 'Template',
|
||||
'parents' => 'Parents'
|
||||
]
|
||||
];
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<style>
|
||||
.path-hint {
|
||||
border: solid 1px transparent;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.path-hint:hover {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.path-hint-tooltip {
|
||||
padding: 0px 10px;
|
||||
position: absolute;
|
||||
background: #000000;
|
||||
z-index: 10000;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.path-hint-tooltip h4 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 3px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.path-hint-tooltip ul li {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.main-container-wrapper .product-card .product-image img {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function(event) {
|
||||
$('.testing').each(function(index) {
|
||||
if ($(this).siblings(':not(.path-hint)').length == 1
|
||||
&& $(this).next().prop("tagName") != 'INPUT'
|
||||
&& $(this).next().prop("tagName") != 'TEXTAREA'
|
||||
&& $(this).next().prop("tagName") != 'SELECT'
|
||||
) {
|
||||
$(this).next().addClass('path-hint');
|
||||
|
||||
$(this).next().attr({
|
||||
'data-toggle': 'tooltip',
|
||||
'data-title': $(this).parent('.path-hint').attr('data-title'),
|
||||
'data-id': $(this).parent('.path-hint').attr('data-id')
|
||||
});
|
||||
|
||||
$(this).unwrap();
|
||||
}
|
||||
|
||||
$(this).remove();
|
||||
})
|
||||
|
||||
$('.path-hint').on('mouseover', function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
var currentElement = $(e.currentTarget);
|
||||
|
||||
var tooltipContent = '<h4>{{ __("core::app.path-hint.template") }}</h4>' + currentElement.attr('data-title');
|
||||
|
||||
if ($(this).parents('.path-hint').length) {
|
||||
tooltipContent += '<h4>{{ __("core::app.path-hint.parents") }}</h4>';
|
||||
|
||||
tooltipContent += '<ul>';
|
||||
|
||||
$(this).parents('.path-hint').each(function(index) {
|
||||
tooltipContent += '<li>' + $(this).attr('data-title') + '</li>';
|
||||
});
|
||||
|
||||
tooltipContent += '</ul>';
|
||||
}
|
||||
|
||||
$('body').append("<span class='path-hint-tooltip' id='" + currentElement.attr('data-id') + "'>" + tooltipContent + "</span>")
|
||||
|
||||
var elementWidth = currentElement.outerWidth()
|
||||
|
||||
var tooltipWidth = $('.path-hint-tooltip').outerWidth()
|
||||
|
||||
var leftOffset = currentElement.offset().left;
|
||||
|
||||
minus = 0;
|
||||
|
||||
temp = leftOffset + (elementWidth / 2) + (tooltipWidth / 2)
|
||||
|
||||
if (temp > $(window).outerWidth()) {
|
||||
minus = temp - $(window).outerWidth();
|
||||
}
|
||||
|
||||
if (elementWidth > tooltipWidth) {
|
||||
var left = leftOffset + ((elementWidth / 2) - (tooltipWidth / 2));
|
||||
} else {
|
||||
var left = leftOffset - ((tooltipWidth / 2) - (elementWidth / 2));
|
||||
}
|
||||
|
||||
if (left <= 0) {
|
||||
left = 10;
|
||||
}
|
||||
|
||||
$('.path-hint-tooltip').css('left', left - minus)
|
||||
|
||||
$('.path-hint-tooltip').css('top', currentElement.offset().top + 20)
|
||||
})
|
||||
|
||||
$('[data-toggle="tooltip"]').on('mouseout', function(e) {
|
||||
var currentElement = $(e.currentTarget);
|
||||
|
||||
$("#" + currentElement.attr('data-id')).remove();
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Core\View\Compilers;
|
||||
|
||||
use Illuminate\View\Compilers\BladeCompiler as BaseBladeCompiler;
|
||||
|
||||
class BladeCompiler extends BaseBladeCompiler
|
||||
{
|
||||
/**
|
||||
* Append the file path to the compiled string.
|
||||
*
|
||||
* @param string $contents
|
||||
* @return string
|
||||
*/
|
||||
protected function appendFilePath($contents)
|
||||
{
|
||||
$tokens = $this->getOpenAndClosingPhpTokens($contents);
|
||||
|
||||
if (config('view.tracer')
|
||||
&& strpos($this->getPath(), 'tracer/style.blade.php') == false
|
||||
&& strpos($this->getPath(), 'master.blade.php') == false
|
||||
) {
|
||||
$finalPath = str_replace('/Providers/..', '', str_replace(base_path(), '', $this->getPath()));
|
||||
|
||||
$contents = '<div class="path-hint" data-toggle="tooltip" data-title="' . $finalPath . '" data-id="' . uniqid() . '"><span class="testing"></span>' . $contents . '</div>';
|
||||
}
|
||||
|
||||
if ($tokens->isNotEmpty() && $tokens->last() !== T_CLOSE_TAG) {
|
||||
$contents .= ' ?>';
|
||||
}
|
||||
|
||||
|
||||
return $contents."<?php /**PATH {$this->getPath()} ENDPATH**/ ?>";
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ class Payment
|
|||
|
||||
return [
|
||||
'jump_to_section' => 'payment',
|
||||
'paymentMethods' => $this->getPaymentMethods(),
|
||||
'paymentMethods' => $paymentMethods,
|
||||
'html' => view('shop::checkout.onepage.payment', compact('paymentMethods'))->render(),
|
||||
];
|
||||
}
|
||||
|
|
@ -68,4 +68,4 @@ class Payment
|
|||
|
||||
return $payment->getRedirectUrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ class BundleOption extends AbstractProduct
|
|||
{
|
||||
$options = [];
|
||||
|
||||
# eager load all inventories for bundle options
|
||||
$this->product->bundle_options->load('bundle_option_products.product.inventories');
|
||||
|
||||
foreach ($this->product->bundle_options as $option) {
|
||||
$data = $this->getOptionItemData($option);
|
||||
|
||||
|
|
@ -97,6 +100,8 @@ class BundleOption extends AbstractProduct
|
|||
'product_id' => $bundleOptionProduct->product_id,
|
||||
'is_default' => $bundleOptionProduct->is_default,
|
||||
'sort_order' => $bundleOptionProduct->sort_order,
|
||||
'in_stock' => $bundleOptionProduct->product->inventories->sum('qty') >= $bundleOptionProduct->qty,
|
||||
'inventory' => $bundleOptionProduct->product->inventories->sum('qty'),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,27 @@ class Product extends Model implements ProductContract
|
|||
|
||||
protected $typeInstance;
|
||||
|
||||
// protected $with = ['attribute_family', 'inventories'];
|
||||
/**
|
||||
* The "booted" method of the model.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
// protected $table = 'products';
|
||||
static::deleting(function ($product) {
|
||||
foreach ($product->product_flats as $productFlat) {
|
||||
$productFlat->unsearchable();
|
||||
}
|
||||
|
||||
foreach ($product->variants as $variant) {
|
||||
foreach ($variant->product_flats as $productFlat) {
|
||||
$productFlat->unsearchable();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product attribute family that owns the product.
|
||||
|
|
@ -40,6 +58,14 @@ class Product extends Model implements ProductContract
|
|||
return $this->hasMany(ProductAttributeValueProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product variants that owns the product.
|
||||
*/
|
||||
public function product_flats()
|
||||
{
|
||||
return $this->hasMany(ProductFlatProxy::modelClass(), 'product_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product variants that owns the product.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
namespace Webkul\Product\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Laravel\Scout\Searchable;
|
||||
use Webkul\Product\Contracts\ProductFlat as ProductFlatContract;
|
||||
|
||||
class ProductFlat extends Model implements ProductFlatContract
|
||||
{
|
||||
use Searchable;
|
||||
|
||||
protected $table = 'product_flat';
|
||||
|
||||
protected $guarded = [
|
||||
|
|
@ -17,6 +20,16 @@ class ProductFlat extends Model implements ProductFlatContract
|
|||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* Get the index name for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function searchableAs()
|
||||
{
|
||||
return 'products_index';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve type instance
|
||||
*
|
||||
|
|
|
|||
|
|
@ -344,12 +344,44 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function searchProductByAttribute($term)
|
||||
{
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($term) {
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
||||
return $query->distinct()
|
||||
if (config('scout.driver') == 'algolia') {
|
||||
$results = app(ProductFlatRepository::class)->getModel()::search('query', function ($searchDriver, string $query, array $options) use($term, $channel, $locale) {
|
||||
$queries = explode('_', $term);
|
||||
|
||||
$options['similarQuery'] = array_map('trim', $queries);
|
||||
|
||||
$searchDriver->setSettings([
|
||||
'attributesForFaceting' => [
|
||||
"searchable(locale)",
|
||||
"searchable(channel)"
|
||||
]
|
||||
]);
|
||||
|
||||
$options['facetFilters'] = ['locale:' . $locale, 'channel:' . $channel];
|
||||
|
||||
return $searchDriver->search($query, $options);
|
||||
})
|
||||
->where('status', 1)
|
||||
->where('visible_individually', 1)
|
||||
->orderBy('product_id', 'desc')
|
||||
->paginate(16);
|
||||
} else if(config('scout.driver') == 'elastic') {
|
||||
$queries = explode('_', $term);
|
||||
|
||||
$results = app(ProductFlatRepository::class)->getModel()::search(implode(' OR ', $queries))
|
||||
->where('status', 1)
|
||||
->where('visible_individually', 1)
|
||||
->where('channel', $channel)
|
||||
->where('locale', $locale)
|
||||
->orderBy('product_id', 'desc')
|
||||
->paginate(16);
|
||||
} else {
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($term, $channel, $locale) {
|
||||
return $query->distinct()
|
||||
->addSelect('product_flat.*')
|
||||
->where('product_flat.status', 1)
|
||||
->where('product_flat.visible_individually', 1)
|
||||
|
|
@ -361,11 +393,12 @@ class ProductRepository extends Repository
|
|||
|
||||
foreach (array_map('trim', $queries) as $value) {
|
||||
$subQuery->orWhere('product_flat.name', 'like', '%' . urldecode($value) . '%')
|
||||
->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%');
|
||||
->orWhere('product_flat.short_description', 'like', '%' . urldecode($value) . '%');
|
||||
}
|
||||
})
|
||||
->orderBy('product_id', 'desc');
|
||||
})->paginate(16);
|
||||
})->paginate(16);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,10 +555,11 @@ abstract class AbstractType
|
|||
if ($haveSpecialPrice) {
|
||||
$this->product->special_price = min($this->product->special_price, $customerGroupPrice);
|
||||
} else {
|
||||
$haveSpecialPrice = true;
|
||||
$this->product->special_price = $customerGroupPrice;
|
||||
}
|
||||
|
||||
return true;
|
||||
return $haveSpecialPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ class Bundle extends AbstractType
|
|||
if (count($optionProductsPrices)) {
|
||||
$selectionMinPrice = min($optionProductsPrices);
|
||||
|
||||
if($option->is_required) {
|
||||
if ($option->is_required) {
|
||||
$minPrice += $selectionMinPrice;
|
||||
} elseif (! $haveRequiredOptions) {
|
||||
$minPrices[] = $selectionMinPrice;
|
||||
|
|
@ -209,7 +209,7 @@ class Bundle extends AbstractType
|
|||
if (count($optionProductsPrices)) {
|
||||
$selectionMinPrice = min($optionProductsPrices);
|
||||
|
||||
if($option->is_required) {
|
||||
if ($option->is_required) {
|
||||
$minPrice += $selectionMinPrice;
|
||||
} elseif (! $haveRequiredOptions) {
|
||||
$minPrices[] = $selectionMinPrice;
|
||||
|
|
@ -688,4 +688,26 @@ class Bundle extends AbstractType
|
|||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty): bool
|
||||
{
|
||||
# to consider a bundle in stock we need to check that at least one product from each required group is available for the given quantity
|
||||
foreach ($this->product->bundle_options as $option) {
|
||||
if ($option->is_required) {
|
||||
foreach ($option->bundle_option_products as $bundleOptionProduct) {
|
||||
# as long as at least one product in the required group is available we can continue checking other groups
|
||||
if($bundleOptionProduct->product->haveSufficientQuantity($bundleOptionProduct->qty * $qty)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
# if any required option does not have any in-stock product option we will get here.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -62,6 +62,6 @@ class Virtual extends AbstractType
|
|||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
{
|
||||
return true;
|
||||
return $qty <= $this->totalQuantity() ? true : false;
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,14 @@ return [
|
|||
'channel_based' => true,
|
||||
'locale_based' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'order_number_generator-class',
|
||||
'title' => 'admin::app.admin.system.order-number-generator-class',
|
||||
'type' => 'text',
|
||||
'validation' => false,
|
||||
'channel_based' => true,
|
||||
'locale_based' => true,
|
||||
],
|
||||
]
|
||||
], [
|
||||
'key' => 'sales.orderSettings.invoice_slip_design',
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ class OrderItem extends Model implements OrderItemContract
|
|||
|
||||
$array['qty_to_refund'] = $this->qty_to_refund;
|
||||
|
||||
$array['downloadable_links'] = $this->downloadable_link_purchased;
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ use Illuminate\Support\Facades\Event;
|
|||
use Webkul\Core\Eloquent\Repository;
|
||||
use Webkul\Sales\Contracts\Order;
|
||||
use Webkul\Sales\Models\Order as OrderModel;
|
||||
use Webkul\Shop\Generators\Sequencer;
|
||||
use Webkul\Shop\Generators\OrderNumberIdSequencer;
|
||||
|
||||
class OrderRepository extends Repository
|
||||
{
|
||||
|
|
@ -63,7 +65,7 @@ class OrderRepository extends Repository
|
|||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
Event::dispatch('checkout.order.save.before', $data);
|
||||
Event::dispatch('checkout.order.save.before', [$data]);
|
||||
|
||||
if (isset($data['customer']) && $data['customer']) {
|
||||
$data['customer_id'] = $data['customer']->id;
|
||||
|
|
@ -185,25 +187,17 @@ class OrderRepository extends Repository
|
|||
*/
|
||||
public function generateIncrementId()
|
||||
{
|
||||
foreach ([ 'Prefix' => 'prefix',
|
||||
'Length' => 'length',
|
||||
'Suffix' => 'suffix', ] as
|
||||
$varSuffix => $confKey)
|
||||
{
|
||||
$var = "invoiceNumber{$varSuffix}";
|
||||
$$var = core()->getConfigData('sales.orderSettings.order_number.order_number_'.$confKey) ?: false;
|
||||
$generatorClass = core()->getConfigData('sales.orderSettings.order_number.order_number_generator-class') ?: false;
|
||||
|
||||
if ($generatorClass !== false
|
||||
&& class_exists($generatorClass)
|
||||
&& in_array(Sequencer::class, class_implements($generatorClass), true)
|
||||
) {
|
||||
/** @var $generatorClass Sequencer */
|
||||
return $generatorClass::generate();
|
||||
}
|
||||
|
||||
$lastOrder = $this->model->orderBy('id', 'desc')->limit(1)->first();
|
||||
$lastId = $lastOrder ? $lastOrder->id : 0;
|
||||
|
||||
if ($invoiceNumberLength && ($invoiceNumberPrefix || $invoiceNumberSuffix)) {
|
||||
$invoiceNumber = ($invoiceNumberPrefix) . sprintf("%0{$invoiceNumberLength}d", 0) . ($lastId + 1) . ($invoiceNumberSuffix);
|
||||
} else {
|
||||
$invoiceNumber = $lastId + 1;
|
||||
}
|
||||
|
||||
return $invoiceNumber;
|
||||
return OrderNumberIdSequencer::generate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/shop.js": "/js/shop.js?id=382caa06d43f2cac5ee6",
|
||||
"/css/shop.css": "/css/shop.css?id=5799059fc0844d8b4574"
|
||||
"/js/shop.js": "/js/shop.js?id=b0ae98b46b290f0fca8b",
|
||||
"/css/shop.css": "/css/shop.css?id=0664f52f2390473afc00"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Webkul\Shop\Generators;
|
||||
|
||||
|
||||
use Webkul\Sales\Models\Order;
|
||||
|
||||
class OrderNumberIdSequencer implements Sequencer
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function generate(): string
|
||||
{
|
||||
foreach ([
|
||||
'Prefix' => 'prefix',
|
||||
'Length' => 'length',
|
||||
'Suffix' => 'suffix',
|
||||
] as
|
||||
$varSuffix => $confKey) {
|
||||
$var = "invoiceNumber{$varSuffix}";
|
||||
$$var = core()->getConfigData('sales.orderSettings.order_number.order_number_' . $confKey) ?: false;
|
||||
}
|
||||
|
||||
$lastOrder = Order::query()->orderBy('id', 'desc')->limit(1)->first();
|
||||
$lastId = $lastOrder ? $lastOrder->id : 0;
|
||||
|
||||
if ($invoiceNumberLength && ($invoiceNumberPrefix || $invoiceNumberSuffix)) {
|
||||
$invoiceNumber = ($invoiceNumberPrefix) . sprintf("%0{$invoiceNumberLength}d",
|
||||
0) . ($lastId + 1) . ($invoiceNumberSuffix);
|
||||
} else {
|
||||
$invoiceNumber = $lastId + 1;
|
||||
}
|
||||
|
||||
return $invoiceNumber;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Webkul\Shop\Generators;
|
||||
|
||||
|
||||
interface Sequencer
|
||||
{
|
||||
/**
|
||||
* create and return the next sequence number for e.g. an order
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generate(): string;
|
||||
}
|
||||
|
|
@ -3823,6 +3823,31 @@ section.review {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-search-container {
|
||||
.icon {
|
||||
&.camera-icon {
|
||||
top: 10px;
|
||||
position: relative;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=file] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.image-search-result {
|
||||
.searched-terms {
|
||||
margin-top: 15px;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.term-list {
|
||||
line-height: 35px;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// rtl css start here
|
||||
.rtl {
|
||||
|
|
@ -3862,6 +3887,11 @@ section.review {
|
|||
border-bottom-right-radius: 0px;
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
.image-search-container {
|
||||
left: 48px;
|
||||
right: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ return [
|
|||
|
||||
'edit-profile' => [
|
||||
'title' => 'Edit Profile',
|
||||
'page-title' => 'Edit Profile Form'
|
||||
'page-title' => 'Edit Profile'
|
||||
]
|
||||
],
|
||||
|
||||
|
|
@ -201,7 +201,7 @@ return [
|
|||
'title' => 'Address',
|
||||
'add' => 'Add Address',
|
||||
'edit' => 'Edit',
|
||||
'empty' => 'You do not have any saved addresses here, please try to create it by clicking the link below',
|
||||
'empty' => 'You do not have any saved addresses here, please try to create it by clicking the add button.',
|
||||
'create' => 'Create Address',
|
||||
'delete' => 'Delete',
|
||||
'make-default' => 'Make Default',
|
||||
|
|
@ -213,7 +213,7 @@ return [
|
|||
],
|
||||
|
||||
'create' => [
|
||||
'page-title' => 'Add Address Form',
|
||||
'page-title' => 'Add Address',
|
||||
'company_name' => 'Company name',
|
||||
'first_name' => 'First name',
|
||||
'last_name' => 'Last name',
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
|
||||
<div class="control-group" :class="[errors.has('city') ? 'has-error' : '']">
|
||||
<label for="city" class="required">{{ __('shop::app.customer.account.address.create.city') }}</label>
|
||||
<input type="text" class="control" name="city" v-validate="'required|alpha_spaces'" value="{{ old('city') ?: $address->city }}" data-vv-as=""{{ __('shop::app.customer.account.address.create.city') }}"">
|
||||
<input type="text" class="control" name="city" v-validate="'required|regex:^[a-zA-Z \-]*$'" value="{{ old('city') ?: $address->city }}" data-vv-as=""{{ __('shop::app.customer.account.address.create.city') }}"">
|
||||
<span class="control-error" v-if="errors.has('city')">@{{ errors.first('city') }}</span>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,11 @@
|
|||
|
||||
@if ($order->base_discount_amount > 0)
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.order.view.discount') }}</td>
|
||||
<td>{{ __('shop::app.customer.account.order.view.discount') }}
|
||||
@if ($order->coupon_code)
|
||||
({{ $order->coupon_code }})
|
||||
@endif
|
||||
</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($order->discount_amount, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@
|
|||
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
|
||||
<label for="password">{{ __('shop::app.customer.account.profile.password') }}</label>
|
||||
|
||||
<input type="password" id="password" class="control" name="password" data-vv-as=""{{ __('shop::app.customer.account.profile.password') }}"" v-validate="'min:6'">
|
||||
<input type="password" id="password" class="control" name="password" ref="password" data-vv-as=""{{ __('shop::app.customer.account.profile.password') }}"" v-validate="'min:6'">
|
||||
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -218,8 +218,6 @@
|
|||
} else {
|
||||
this.$set(this, 'products', this.products.filter(product => product.id != productId));
|
||||
}
|
||||
|
||||
// window.showAlert(`alert-${response.data.status}`, response.data.label, response.data.message);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log("{{ __('velocity::app.error.something_went_wrong') }}");
|
||||
|
|
@ -236,12 +234,6 @@
|
|||
}
|
||||
|
||||
this.setStorageValue('compared_product', updatedItems);
|
||||
|
||||
// window.showAlert(
|
||||
// `alert-success`,
|
||||
// "{{ __('velocity::app.shop.general.alert.success') }}",
|
||||
// `${this.__('customer.compare.removed')}`
|
||||
// );
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
<?php
|
||||
$term = request()->input('term');
|
||||
|
||||
if (! is_null($term)) {
|
||||
$serachQuery = 'term='.request()->input('term');
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="header" id="header">
|
||||
<div class="header-top">
|
||||
<div class="left-content">
|
||||
|
|
@ -16,7 +24,14 @@
|
|||
<ul class="search-container">
|
||||
<li class="search-group">
|
||||
<form role="search" action="{{ route('shop.search.index') }}" method="GET" style="display: inherit;">
|
||||
<input type="search" name="term" class="search-field" placeholder="{{ __('shop::app.header.search-text') }}" required>
|
||||
<input
|
||||
required
|
||||
name="term"
|
||||
type="search"
|
||||
value="{{ $term }}"
|
||||
class="search-field"
|
||||
placeholder="{{ __('shop::app.header.search-text') }}"
|
||||
>
|
||||
|
||||
<image-search-component></image-search-component>
|
||||
|
||||
|
|
@ -31,14 +46,6 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$term = request()->input('term');
|
||||
|
||||
if (! is_null($term)) {
|
||||
$serachQuery = 'term='.request()->input('term');
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="right-content">
|
||||
|
||||
<span class="search-box"><span class="icon icon-search" id="search"></span></span>
|
||||
|
|
@ -195,6 +202,9 @@
|
|||
<button style="background: none; border: none; padding: 0px;">
|
||||
<i class="icon icon-search"></i>
|
||||
</button>
|
||||
|
||||
<image-search-component></image-search-component>
|
||||
|
||||
<input type="search" name="term" class="search">
|
||||
<i class="icon icon-menu-back right"></i>
|
||||
</div>
|
||||
|
|
@ -232,55 +242,87 @@
|
|||
|
||||
methods: {
|
||||
uploadImage: function() {
|
||||
var self = this;
|
||||
var imageInput = this.$refs.image_search_input;
|
||||
|
||||
self.$root.showLoader();
|
||||
if (imageInput.files && imageInput.files[0]) {
|
||||
if (imageInput.files[0].type.includes('image/')) {
|
||||
var self = this;
|
||||
|
||||
var formData = new FormData();
|
||||
self.$root.showLoader();
|
||||
|
||||
formData.append('image', this.$refs.image_search_input.files[0]);
|
||||
var formData = new FormData();
|
||||
|
||||
axios.post("{{ route('shop.image.search.upload') }}", formData, {headers: {'Content-Type': 'multipart/form-data'}})
|
||||
.then(function(response) {
|
||||
self.uploaded_image_url = response.data;
|
||||
formData.append('image', imageInput.files[0]);
|
||||
|
||||
var net;
|
||||
axios.post("{{ route('shop.image.search.upload') }}", formData, {headers: {'Content-Type': 'multipart/form-data'}})
|
||||
.then(function(response) {
|
||||
self.uploaded_image_url = response.data;
|
||||
|
||||
async function app() {
|
||||
var analysedResult = [];
|
||||
var net;
|
||||
|
||||
var queryString = '';
|
||||
async function app() {
|
||||
var analysedResult = [];
|
||||
|
||||
net = await mobilenet.load();
|
||||
var queryString = '';
|
||||
|
||||
const imgElement = document.getElementById('uploaded-image-url');
|
||||
net = await mobilenet.load();
|
||||
|
||||
const result = await net.classify(imgElement);
|
||||
const imgElement = document.getElementById('uploaded-image-url');
|
||||
|
||||
result.forEach(function(value) {
|
||||
queryString = value.className.split(',');
|
||||
try {
|
||||
const result = await net.classify(imgElement);
|
||||
|
||||
if (queryString.length > 1) {
|
||||
analysedResult = analysedResult.concat(queryString)
|
||||
} else {
|
||||
analysedResult.push(queryString[0])
|
||||
result.forEach(function(value) {
|
||||
queryString = value.className.split(',');
|
||||
|
||||
if (queryString.length > 1) {
|
||||
analysedResult = analysedResult.concat(queryString)
|
||||
} else {
|
||||
analysedResult.push(queryString[0])
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
self.$root.hideLoader();
|
||||
|
||||
window.flashMessages = [
|
||||
{
|
||||
'type': 'alert-error',
|
||||
'message': "{{ __('shop::app.common.error') }}"
|
||||
}
|
||||
];
|
||||
|
||||
self.$root.addFlashMessages();
|
||||
};
|
||||
|
||||
localStorage.searched_image_url = self.uploaded_image_url;
|
||||
|
||||
queryString = localStorage.searched_terms = analysedResult.join('_');
|
||||
|
||||
self.$root.hideLoader();
|
||||
|
||||
window.location.href = "{{ route('shop.search.index') }}" + '?term=' + queryString + '&image-search=1';
|
||||
}
|
||||
|
||||
app();
|
||||
})
|
||||
.catch(function(error) {
|
||||
self.$root.hideLoader();
|
||||
|
||||
localStorage.searched_image_url = self.uploaded_image_url;
|
||||
window.flashMessages = [
|
||||
{
|
||||
'type': 'alert-error',
|
||||
'message': "{{ __('shop::app.common.error') }}"
|
||||
}
|
||||
];
|
||||
|
||||
queryString = localStorage.searched_terms = analysedResult.join('_');
|
||||
|
||||
self.$root.hideLoader();
|
||||
self.$root.addFlashMessages();
|
||||
});
|
||||
} else {
|
||||
imageInput.value = '';
|
||||
|
||||
window.location.href = "{{ route('shop.search.index') }}" + '?term=' + queryString + '&image-search=1';
|
||||
}
|
||||
|
||||
app();
|
||||
})
|
||||
.catch(function() {
|
||||
self.$root.hideLoader();
|
||||
});
|
||||
alert('Only images (.jpeg, .jpg, .png, ..) are allowed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@
|
|||
},
|
||||
|
||||
created: function() {
|
||||
this.searched_terms = localStorage.searched_terms.split('_');
|
||||
|
||||
console.log(this.searched_terms)
|
||||
if (localStorage.searched_terms && localStorage.searched_terms != '') {
|
||||
this.searched_terms = localStorage.searched_terms.split('_');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
/node_modules
|
||||
/package-lock.json
|
||||
npm-debug.log
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch-poll": "cross-env npm run watch -- --watch-poll --progress",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^6.0.3",
|
||||
"laravel-mix": "^5.0.0",
|
||||
"laravel-mix-merge-manifest": "^0.1.2",
|
||||
"sass": "^1.25.0",
|
||||
"sass-loader": "^8.0.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
.social-login-links .icon{width:18px;height:18px;vertical-align:middle;margin-bottom:3px;margin-right:3px;display:inline-block;background-size:cover}.social-login-links .icon.icon-facebook-login{background-image:url(../images/facebook-login.svg)}.social-login-links .icon.icon-twitter-login{background-image:url(../images/twitter-login.svg)}.social-login-links .icon.icon-google-login{background-image:url(../images/google-login.svg)}.social-login-links .icon.icon-linkedin-login{background-image:url(../images/linkedin-login.svg)}.social-login-links .icon.icon-github-login{background-image:url(../images/github-login.svg)}.social-login-links .icon.icon-instagram-login{background-image:url(../images/instagram-login.svg)}.auth-content .login-form .social-login-links .control-group,.auth-content .social-login-links .control-group{float:left;width:100%;margin-bottom:10px!important}.social-login-links .link{min-width:220px;max-width:100%;margin:0;cursor:pointer;padding:10px 15px;border-radius:3px;color:#fff;text-decoration:none;float:left}.social-login-links .link.facebook-link{background-color:#5272b3}.social-login-links .link.twitter-link{background-color:#0597e6}.social-login-links .link.google-link{background-color:#e45e52}.social-login-links .link.linkedin-link{background-color:#007bb6}.social-login-links .link.github-link{background-color:#24292e}.social-link-seperator{position:relative;border-top:1px solid #d3d3d3;margin:30px 0 25px;display:inline-block;width:100%}.social-link-seperator span{background-color:#fff;position:absolute;left:20px;top:-12px;padding:0 15px;text-align:center}.rtl{direction:rtl}.rtl .social-login-links .link{float:right}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 9.05477C18 4.05274 13.9718 0 9 0C4.02823 0 0 4.05274 0 9.05477C0 13.5821 3.26613 17.3428 7.58468 18V11.6836H5.29839V9.05477H7.58468V7.08316C7.58468 4.81947 8.92742 3.54158 10.9597 3.54158C11.9758 3.54158 12.9919 3.72414 12.9919 3.72414V5.95132H11.8669C10.7419 5.95132 10.379 6.64503 10.379 7.37525V9.05477H12.8831L12.4839 11.6836H10.379V18C14.6976 17.3428 18 13.5821 18 9.05477Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 511 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 9.05477C18 4.05274 13.9718 0 9 0C4.02823 0 0 4.05274 0 9.05477C0 13.5821 3.26613 17.3428 7.58468 18V11.6836H5.29839V9.05477H7.58468V7.08316C7.58468 4.81947 8.92742 3.54158 10.9597 3.54158C11.9758 3.54158 12.9919 3.72414 12.9919 3.72414V5.95132H11.8669C10.7419 5.95132 10.379 6.64503 10.379 7.37525V9.05477H12.8831L12.4839 11.6836H10.379V18C14.6976 17.3428 18 13.5821 18 9.05477Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 511 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.9879 14.4948C5.9879 14.4204 5.91532 14.3461 5.80645 14.3461C5.69758 14.3461 5.625 14.4204 5.625 14.4948C5.625 14.5691 5.69758 14.6434 5.80645 14.6063C5.91532 14.6063 5.9879 14.5691 5.9879 14.4948ZM4.8629 14.3089C4.8629 14.3833 4.93548 14.4948 5.04435 14.4948C5.11694 14.5319 5.22581 14.4948 5.2621 14.4204C5.2621 14.3461 5.22581 14.2718 5.11694 14.2346C5.00806 14.1974 4.89919 14.2346 4.8629 14.3089ZM6.49597 14.2718C6.3871 14.2718 6.31452 14.3461 6.31452 14.4576C6.31452 14.5319 6.42339 14.5691 6.53226 14.5319C6.64113 14.4948 6.71371 14.4576 6.67742 14.3833C6.67742 14.3089 6.56855 14.2346 6.49597 14.2718ZM8.85484 0C3.84677 0 0 3.9396 0 9.06851C0 13.1939 2.50403 16.7247 6.13306 17.9884C6.60484 18.0627 6.75 17.7654 6.75 17.5424C6.75 17.2822 6.75 16.0186 6.75 15.2381C6.75 15.2381 4.20968 15.7956 3.66532 14.1231C3.66532 14.1231 3.26613 13.0453 2.68548 12.7851C2.68548 12.7851 1.85081 12.1905 2.72177 12.1905C2.72177 12.1905 3.62903 12.2648 4.1371 13.1568C4.93548 14.6063 6.24194 14.1974 6.78629 13.9373C6.85887 13.3426 7.07661 12.9338 7.36694 12.6736C5.33468 12.4506 3.26613 12.1533 3.26613 8.58535C3.26613 7.5447 3.55645 7.06155 4.1371 6.39256C4.02823 6.1324 3.7379 5.16608 4.24597 3.86527C4.97177 3.64227 6.75 4.86875 6.75 4.86875C7.47581 4.64575 8.2379 4.57142 9 4.57142C9.79839 4.57142 10.5605 4.64575 11.2863 4.86875C11.2863 4.86875 13.0282 3.60511 13.7903 3.86527C14.2984 5.16608 13.9718 6.1324 13.8992 6.39256C14.4798 7.06155 14.8427 7.5447 14.8427 8.58535C14.8427 12.1533 12.7016 12.4506 10.6694 12.6736C10.996 12.9709 11.2863 13.5284 11.2863 14.4204C11.2863 15.6469 11.25 17.2079 11.25 17.5052C11.25 17.7654 11.4315 18.0627 11.9032 17.9512C15.5323 16.7247 18 13.1939 18 9.06851C18 3.9396 13.8992 0 8.85484 0ZM3.52016 12.8223C3.44758 12.8594 3.48387 12.9709 3.52016 13.0453C3.59274 13.0824 3.66532 13.1196 3.7379 13.0824C3.77419 13.0453 3.77419 12.9338 3.70161 12.8594C3.62903 12.8223 3.55645 12.7851 3.52016 12.8223ZM3.12097 12.525C3.08468 12.5993 3.12097 12.6365 3.19355 12.6736C3.26613 12.7108 3.33871 12.7108 3.375 12.6365C3.375 12.5993 3.33871 12.5621 3.26613 12.525C3.19355 12.4878 3.15726 12.4878 3.12097 12.525ZM4.28226 13.8629C4.24597 13.9001 4.24597 14.0116 4.35484 14.0859C4.42742 14.1603 4.53629 14.1974 4.57258 14.1231C4.60887 14.0859 4.60887 13.9744 4.53629 13.9001C4.46371 13.8258 4.35484 13.7886 4.28226 13.8629ZM3.88306 13.3054C3.81048 13.3426 3.81048 13.4541 3.88306 13.5284C3.95565 13.6028 4.02823 13.6399 4.10081 13.6028C4.1371 13.5656 4.1371 13.4541 4.10081 13.3798C4.02823 13.3054 3.95565 13.2683 3.88306 13.3054Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.9879 14.4948C5.9879 14.4204 5.91532 14.3461 5.80645 14.3461C5.69758 14.3461 5.625 14.4204 5.625 14.4948C5.625 14.5691 5.69758 14.6434 5.80645 14.6063C5.91532 14.6063 5.9879 14.5691 5.9879 14.4948ZM4.8629 14.3089C4.8629 14.3833 4.93548 14.4948 5.04435 14.4948C5.11694 14.5319 5.22581 14.4948 5.2621 14.4204C5.2621 14.3461 5.22581 14.2718 5.11694 14.2346C5.00806 14.1974 4.89919 14.2346 4.8629 14.3089ZM6.49597 14.2718C6.3871 14.2718 6.31452 14.3461 6.31452 14.4576C6.31452 14.5319 6.42339 14.5691 6.53226 14.5319C6.64113 14.4948 6.71371 14.4576 6.67742 14.3833C6.67742 14.3089 6.56855 14.2346 6.49597 14.2718ZM8.85484 0C3.84677 0 0 3.9396 0 9.06851C0 13.1939 2.50403 16.7247 6.13306 17.9884C6.60484 18.0627 6.75 17.7654 6.75 17.5424C6.75 17.2822 6.75 16.0186 6.75 15.2381C6.75 15.2381 4.20968 15.7956 3.66532 14.1231C3.66532 14.1231 3.26613 13.0453 2.68548 12.7851C2.68548 12.7851 1.85081 12.1905 2.72177 12.1905C2.72177 12.1905 3.62903 12.2648 4.1371 13.1568C4.93548 14.6063 6.24194 14.1974 6.78629 13.9373C6.85887 13.3426 7.07661 12.9338 7.36694 12.6736C5.33468 12.4506 3.26613 12.1533 3.26613 8.58535C3.26613 7.5447 3.55645 7.06155 4.1371 6.39256C4.02823 6.1324 3.7379 5.16608 4.24597 3.86527C4.97177 3.64227 6.75 4.86875 6.75 4.86875C7.47581 4.64575 8.2379 4.57142 9 4.57142C9.79839 4.57142 10.5605 4.64575 11.2863 4.86875C11.2863 4.86875 13.0282 3.60511 13.7903 3.86527C14.2984 5.16608 13.9718 6.1324 13.8992 6.39256C14.4798 7.06155 14.8427 7.5447 14.8427 8.58535C14.8427 12.1533 12.7016 12.4506 10.6694 12.6736C10.996 12.9709 11.2863 13.5284 11.2863 14.4204C11.2863 15.6469 11.25 17.2079 11.25 17.5052C11.25 17.7654 11.4315 18.0627 11.9032 17.9512C15.5323 16.7247 18 13.1939 18 9.06851C18 3.9396 13.8992 0 8.85484 0ZM3.52016 12.8223C3.44758 12.8594 3.48387 12.9709 3.52016 13.0453C3.59274 13.0824 3.66532 13.1196 3.7379 13.0824C3.77419 13.0453 3.77419 12.9338 3.70161 12.8594C3.62903 12.8223 3.55645 12.7851 3.52016 12.8223ZM3.12097 12.525C3.08468 12.5993 3.12097 12.6365 3.19355 12.6736C3.26613 12.7108 3.33871 12.7108 3.375 12.6365C3.375 12.5993 3.33871 12.5621 3.26613 12.525C3.19355 12.4878 3.15726 12.4878 3.12097 12.525ZM4.28226 13.8629C4.24597 13.9001 4.24597 14.0116 4.35484 14.0859C4.42742 14.1603 4.53629 14.1974 4.57258 14.1231C4.60887 14.0859 4.60887 13.9744 4.53629 13.9001C4.46371 13.8258 4.35484 13.7886 4.28226 13.8629ZM3.88306 13.3054C3.81048 13.3426 3.81048 13.4541 3.88306 13.5284C3.95565 13.6028 4.02823 13.6399 4.10081 13.6028C4.1371 13.5656 4.1371 13.4541 4.10081 13.3798C4.02823 13.3054 3.95565 13.2683 3.88306 13.3054Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM14.9099 8.20562C14.9561 8.50041 15 8.77964 15 9.14516C15 12.5806 12.6148 15 9.09836 15C5.70492 15 3 12.3387 3 9C3 5.68548 5.70492 3 9.09836 3C10.7213 3 12.123 3.60484 13.1803 4.57258L11.5082 6.14516C9.34426 4.08871 5.31148 5.6371 5.31148 9C5.31148 11.1048 7.0082 12.7984 9.09836 12.7984C11.5082 12.7984 12.418 11.1048 12.541 10.2097H9.09836V8.15323H14.9016C14.9044 8.17076 14.9071 8.18821 14.9099 8.20562Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 683 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM14.9099 8.20562C14.9561 8.50041 15 8.77964 15 9.14516C15 12.5806 12.6148 15 9.09836 15C5.70492 15 3 12.3387 3 9C3 5.68548 5.70492 3 9.09836 3C10.7213 3 12.123 3.60484 13.1803 4.57258L11.5082 6.14516C9.34426 4.08871 5.31148 5.6371 5.31148 9C5.31148 11.1048 7.0082 12.7984 9.09836 12.7984C11.5082 12.7984 12.418 11.1048 12.541 10.2097H9.09836V8.15323H14.9016C14.9044 8.17076 14.9071 8.18821 14.9099 8.20562Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 683 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM13.9955 4.00447C14.692 4.70089 14.9062 5.55804 14.9598 6.52233C15.0134 7.5134 15.0134 10.4866 14.9598 11.4777C14.9062 12.442 14.692 13.2723 13.9955 13.9955C13.2991 14.692 12.442 14.9063 11.4777 14.9598C10.4866 15.0134 7.51339 15.0134 6.52232 14.9598C5.55804 14.9063 4.72768 14.692 4.00446 13.9955C3.30804 13.2723 3.09375 12.442 3.04018 11.4777C2.98661 10.4866 2.98661 7.5134 3.04018 6.52233C3.09375 5.55804 3.30804 4.70089 4.00446 4.00447C4.72768 3.30804 5.55804 3.09375 6.52232 3.04018C7.51339 2.98661 10.4866 2.98661 11.4777 3.04018C12.442 3.09375 13.2991 3.30804 13.9955 4.00447ZM12.8911 5.82322C12.8911 5.42143 12.5696 5.10001 12.1679 5.10001C11.7661 5.10001 11.4446 5.42143 11.4446 5.82322C11.4446 6.22501 11.7661 6.54643 12.1679 6.54643C12.5696 6.54643 12.8911 6.22501 12.8911 5.82322ZM8.98036 5.93036C7.26607 5.93036 5.9 7.32322 5.9 9.01072C5.9 10.725 7.26607 12.0911 8.98036 12.0911C10.6679 12.0911 12.0607 10.725 12.0607 9.01072C12.0607 7.32322 10.6679 5.93036 8.98036 5.93036ZM7 8.98658C7 10.1141 7.91275 11 9.01342 11C10.1141 11 11 10.1141 11 8.98658C11 7.88591 10.1141 7 9.01342 7C7.88591 7 7 7.88591 7 8.98658Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM13.9955 4.00447C14.692 4.70089 14.9062 5.55804 14.9598 6.52233C15.0134 7.5134 15.0134 10.4866 14.9598 11.4777C14.9062 12.442 14.692 13.2723 13.9955 13.9955C13.2991 14.692 12.442 14.9063 11.4777 14.9598C10.4866 15.0134 7.51339 15.0134 6.52232 14.9598C5.55804 14.9063 4.72768 14.692 4.00446 13.9955C3.30804 13.2723 3.09375 12.442 3.04018 11.4777C2.98661 10.4866 2.98661 7.5134 3.04018 6.52233C3.09375 5.55804 3.30804 4.70089 4.00446 4.00447C4.72768 3.30804 5.55804 3.09375 6.52232 3.04018C7.51339 2.98661 10.4866 2.98661 11.4777 3.04018C12.442 3.09375 13.2991 3.30804 13.9955 4.00447ZM12.8911 5.82322C12.8911 5.42143 12.5696 5.10001 12.1679 5.10001C11.7661 5.10001 11.4446 5.42143 11.4446 5.82322C11.4446 6.22501 11.7661 6.54643 12.1679 6.54643C12.5696 6.54643 12.8911 6.22501 12.8911 5.82322ZM8.98036 5.93036C7.26607 5.93036 5.9 7.32322 5.9 9.01072C5.9 10.725 7.26607 12.0911 8.98036 12.0911C10.6679 12.0911 12.0607 10.725 12.0607 9.01072C12.0607 7.32322 10.6679 5.93036 8.98036 5.93036ZM7 8.98658C7 10.1141 7.91275 11 9.01342 11C10.1141 11 11 10.1141 11 8.98658C11 7.88591 10.1141 7 9.01342 7C7.88591 7 7 7.88591 7 8.98658Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM4.15625 7.34375V14H6.21875V7.34375H4.15625ZM3.96875 5.21875C3.96875 5.875 4.5 6.40625 5.1875 6.40625C5.84375 6.40625 6.375 5.875 6.375 5.21875C6.375 4.5625 5.84375 4 5.1875 4C4.5 4 3.96875 4.5625 3.96875 5.21875ZM11.9062 14H14V10.3438C14 8.5625 13.5938 7.15625 11.5 7.15625C10.5 7.15625 9.8125 7.71875 9.53125 8.25H9.5V7.34375H7.53125V14H9.59375V10.7188C9.59375 9.84375 9.75 9 10.8438 9C11.9062 9 11.9062 10 11.9062 10.75V14Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 703 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM4.15625 7.34375V14H6.21875V7.34375H4.15625ZM3.96875 5.21875C3.96875 5.875 4.5 6.40625 5.1875 6.40625C5.84375 6.40625 6.375 5.875 6.375 5.21875C6.375 4.5625 5.84375 4 5.1875 4C4.5 4 3.96875 4.5625 3.96875 5.21875ZM11.9062 14H14V10.3438C14 8.5625 13.5938 7.15625 11.5 7.15625C10.5 7.15625 9.8125 7.71875 9.53125 8.25H9.5V7.34375H7.53125V14H9.59375V10.7188C9.59375 9.84375 9.75 9 10.8438 9C11.9062 9 11.9062 10 11.9062 10.75V14Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 703 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM16 5.2988C15.6164 5.85542 15.1233 6.33253 14.5753 6.73012V7.1012C14.5753 10.7855 11.6986 15 6.41096 15C4.76712 15 3.26027 14.5494 2 13.7542C2.21918 13.7807 2.43836 13.8072 2.68493 13.8072C4.0274 13.8072 5.26027 13.3566 6.24658 12.6145C4.9863 12.588 3.91781 11.7928 3.56164 10.6795C3.58322 10.6825 3.60445 10.6855 3.6254 10.6884C3.79076 10.7117 3.93938 10.7325 4.10959 10.7325C4.35616 10.7325 4.63014 10.6795 4.84932 10.6265C3.53425 10.3614 2.54795 9.24819 2.54795 7.89639V7.86988C2.93151 8.08193 3.39726 8.18795 3.86301 8.21446C3.06849 7.71084 2.57534 6.86265 2.57534 5.90843C2.57534 5.37831 2.71233 4.9012 2.9589 4.50361C4.38356 6.17349 6.52055 7.28675 8.90411 7.41928C8.84931 7.20723 8.82192 6.99518 8.82192 6.78313C8.82192 5.24578 10.1096 4 11.6986 4C12.5205 4 13.2603 4.31807 13.8082 4.8747C14.4384 4.74217 15.0685 4.50361 15.6164 4.18554C15.3973 4.84819 14.9589 5.37831 14.3562 5.72289C14.9315 5.66988 15.5068 5.51084 16 5.2988Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM16 5.2988C15.6164 5.85542 15.1233 6.33253 14.5753 6.73012V7.1012C14.5753 10.7855 11.6986 15 6.41096 15C4.76712 15 3.26027 14.5494 2 13.7542C2.21918 13.7807 2.43836 13.8072 2.68493 13.8072C4.0274 13.8072 5.26027 13.3566 6.24658 12.6145C4.9863 12.588 3.91781 11.7928 3.56164 10.6795C3.58322 10.6825 3.60445 10.6855 3.6254 10.6884C3.79076 10.7117 3.93938 10.7325 4.10959 10.7325C4.35616 10.7325 4.63014 10.6795 4.84932 10.6265C3.53425 10.3614 2.54795 9.24819 2.54795 7.89639V7.86988C2.93151 8.08193 3.39726 8.18795 3.86301 8.21446C3.06849 7.71084 2.57534 6.86265 2.57534 5.90843C2.57534 5.37831 2.71233 4.9012 2.9589 4.50361C4.38356 6.17349 6.52055 7.28675 8.90411 7.41928C8.84931 7.20723 8.82192 6.99518 8.82192 6.78313C8.82192 5.24578 10.1096 4 11.6986 4C12.5205 4 13.2603 4.31807 13.8082 4.8747C14.4384 4.74217 15.0685 4.50361 15.6164 4.18554C15.3973 4.84819 14.9589 5.37831 14.3562 5.72289C14.9315 5.66988 15.5068 5.51084 16 5.2988Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"/css/social-login.css": "/css/social-login.css?id=65d278094ee2727ac0d4"
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
'key' => 'customer.settings.social_login',
|
||||
'name' => 'sociallogin::app.admin.system.social-login',
|
||||
'sort' => 4,
|
||||
'fields' => [
|
||||
[
|
||||
'name' => 'enable_facebook',
|
||||
'title' => 'sociallogin::app.admin.system.enable-facebook',
|
||||
'type' => 'boolean',
|
||||
'channel_based' => true,
|
||||
], [
|
||||
'name' => 'enable_twitter',
|
||||
'title' => 'sociallogin::app.admin.system.enable-twitter',
|
||||
'type' => 'boolean',
|
||||
'channel_based' => true,
|
||||
], [
|
||||
'name' => 'enable_google',
|
||||
'title' => 'sociallogin::app.admin.system.enable-google',
|
||||
'type' => 'boolean',
|
||||
'channel_based' => true,
|
||||
], [
|
||||
'name' => 'enable_linkedin',
|
||||
'title' => 'sociallogin::app.admin.system.enable-linkedin',
|
||||
'type' => 'boolean',
|
||||
'channel_based' => true,
|
||||
], [
|
||||
'name' => 'enable_github',
|
||||
'title' => 'sociallogin::app.admin.system.enable-github',
|
||||
'type' => 'boolean',
|
||||
'channel_based' => true,
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Contracts;
|
||||
|
||||
interface CustomerSocialAccount
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateCustomerSocialAccountsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('customer_social_accounts', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('provider_name')->nullable();
|
||||
$table->string('provider_id')->unique()->nullable();
|
||||
|
||||
$table->integer('customer_id')->unsigned();
|
||||
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('customer_social_accounts');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class ChangeEmailPasswordColumnsInCustomersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
$table->string('email')->nullable()->change();
|
||||
$table->string('password')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('customers', function (Blueprint $table) {
|
||||
$table->string('email')->nullable(false)->change();
|
||||
$table->string('password')->nullable(false)->change();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Database\Seeders;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CustomerSocialAccountTableSeeder extends Seeder
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
DB::table('core_config')->insert(
|
||||
[
|
||||
'code' => 'customer.settings.social_login.enable_facebook',
|
||||
'value' => '1',
|
||||
'channel_code' => 'default',
|
||||
'locale_code' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]
|
||||
);
|
||||
|
||||
DB::table('core_config')->insert(
|
||||
[
|
||||
'code' => 'customer.settings.social_login.enable_twitter',
|
||||
'value' => '1',
|
||||
'channel_code' => 'default',
|
||||
'locale_code' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]
|
||||
);
|
||||
|
||||
DB::table('core_config')->insert(
|
||||
[
|
||||
'code' => 'customer.settings.social_login.enable_google',
|
||||
'value' => '1',
|
||||
'channel_code' => 'default',
|
||||
'locale_code' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]
|
||||
);
|
||||
|
||||
DB::table('core_config')->insert(
|
||||
[
|
||||
'code' => 'customer.settings.social_login.enable_linkedin',
|
||||
'value' => '1',
|
||||
'channel_code' => 'default',
|
||||
'locale_code' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]
|
||||
);
|
||||
|
||||
DB::table('core_config')->insert(
|
||||
[
|
||||
'code' => 'customer.settings.social_login.enable_github',
|
||||
'value' => '1',
|
||||
'channel_code' => 'default',
|
||||
'locale_code' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->call(CustomerSocialAccountTableSeeder::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Http\Controllers;
|
||||
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use Webkul\SocialLogin\Repositories\CustomerSocialAccountRepository;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use DispatchesJobs, ValidatesRequests;
|
||||
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* CustomerSocialAccountRepository
|
||||
*
|
||||
* @var \Webkul\SocialLogin\Repositories\CustomerSocialAccountRepository
|
||||
*/
|
||||
protected $customerSocialAccountRepository;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param \Webkul\SocialLogin\Repositories\CustomerSocialAccountRepository $customerSocialAccountRepository
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(CustomerSocialAccountRepository $customerSocialAccountRepository)
|
||||
{
|
||||
$this->customerSocialAccountRepository = $customerSocialAccountRepository;
|
||||
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to the social provider
|
||||
*
|
||||
* @param string $provider
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function redirectToProvider($provider)
|
||||
{
|
||||
try {
|
||||
return Socialite::driver($provider)->redirect();
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('error', $e->getMessage());
|
||||
|
||||
return redirect()->route('customer.session.index');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles callback
|
||||
*
|
||||
* @param string $provider
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handleProviderCallback($provider)
|
||||
{
|
||||
try {
|
||||
$user = Socialite::driver($provider)->user();
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('customer.session.index');
|
||||
}
|
||||
|
||||
$customer = $this->customerSocialAccountRepository->findOrCreateCustomer($user, $provider);
|
||||
|
||||
auth()->guard('customer')->login($customer, true);
|
||||
|
||||
return redirect()->intended(route($this->_config['redirect']));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function () {
|
||||
Route::prefix('customer')->group(function () {
|
||||
Route::get('social-login/{provider}', 'Webkul\SocialLogin\Http\Controllers\LoginController@redirectToProvider')->defaults('_config', [
|
||||
'redirect' => 'customer.profile.index'
|
||||
])->name('customer.social-login.index');
|
||||
|
||||
Route::get('social-login/{provider}/callback','Webkul\SocialLogin\Http\Controllers\LoginController@handleProviderCallback')->defaults('_config', [
|
||||
'redirect' => 'customer.profile.index'
|
||||
])->name('customer.social-login.callback');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Customer\Models\CustomerProxy;
|
||||
use Webkul\SocialLogin\Contracts\CustomerSocialAccount as CustomerSocialAccountContract;
|
||||
|
||||
class CustomerSocialAccount extends Model implements CustomerSocialAccountContract
|
||||
{
|
||||
protected $fillable = [
|
||||
'customer_id',
|
||||
'provider_name',
|
||||
'provider_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the customer that belongs to the social aoount.
|
||||
*/
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsTo(CustomerProxy::modelClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CustomerSocialAccountProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Event::listen('bagisto.shop.customers.login_form_controls.before', function($viewRenderEventManager) {
|
||||
$viewRenderEventManager->addTemplate('sociallogin::shop.customers.session.social-links');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Providers;
|
||||
|
||||
use Konekt\Concord\BaseModuleServiceProvider;
|
||||
|
||||
class ModuleServiceProvider extends BaseModuleServiceProvider
|
||||
{
|
||||
protected $models = [
|
||||
\Webkul\SocialLogin\Models\CustomerSocialAccount::class,
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace Webkul\SocialLogin\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class SocialLoginServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->loadRoutesFrom(__DIR__ . '/../Http/routes.php');
|
||||
|
||||
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
|
||||
|
||||
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'sociallogin');
|
||||
|
||||
$this->loadViewsFrom(__DIR__ . '/../Resources/views', 'sociallogin');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/../../publishable/assets' => public_path('themes/default/assets'),
|
||||
], 'public');
|
||||
|
||||
$this->app->register(EventServiceProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->registerConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register package config.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerConfig()
|
||||
{
|
||||
$this->mergeConfigFrom(
|
||||
dirname(__DIR__) . '/Config/system.php', 'core'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\SocialLogin\Repositories;
|
||||
|
||||
use Illuminate\Container\Container as App;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
use Webkul\Customer\Repositories\CustomerRepository;
|
||||
use Webkul\Customer\Repositories\CustomerGroupRepository;
|
||||
|
||||
class CustomerSocialAccountRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* CustomerRepository object
|
||||
*
|
||||
* @var \Webkul\Customer\Repositories\CustomerRepository
|
||||
*/
|
||||
protected $customerRepository;
|
||||
|
||||
/**
|
||||
* CustomerGroupRepository object
|
||||
*
|
||||
* @var \Webkul\Customer\Repositories\CustomerGroupRepository
|
||||
*/
|
||||
protected $customerGroupRepository;
|
||||
|
||||
/**
|
||||
* Create a new reposotory instance.
|
||||
*
|
||||
* @param \Webkul\Customer\Repositories\CustomerRepository $customerRepository
|
||||
* @param \Webkul\Customer\Repositories\CustomerGroupRepository $customerGroupRepository
|
||||
* @param \Illuminate\Container\Container $app
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
CustomerRepository $customerRepository,
|
||||
CustomerGroupRepository $customerGroupRepository,
|
||||
App $app
|
||||
)
|
||||
{
|
||||
$this->customerRepository = $customerRepository;
|
||||
|
||||
$this->customerGroupRepository = $customerGroupRepository;
|
||||
|
||||
$this->_config = request('_config');
|
||||
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify Model class name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function model()
|
||||
{
|
||||
return 'Webkul\SocialLogin\Contracts\CustomerSocialAccount';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $providerUser
|
||||
* @param string $provider
|
||||
* @return void
|
||||
*/
|
||||
public function findOrCreateCustomer($providerUser, $provider)
|
||||
{
|
||||
$account = $this->findOneWhere([
|
||||
'provider_name' => $provider,
|
||||
'provider_id' => $providerUser->getId(),
|
||||
]);
|
||||
|
||||
if ($account) {
|
||||
return $account->customer;
|
||||
} else {
|
||||
$customer = $this->customerRepository->findOneByField('email', $providerUser->getEmail());
|
||||
|
||||
if (! $customer) {
|
||||
$names = $this->getFirstLastName($providerUser->getName());
|
||||
|
||||
$customer = $this->customerRepository->create([
|
||||
'email' => $providerUser->getEmail(),
|
||||
'first_name' => $names['first_name'],
|
||||
'last_name' => $names['last_name'],
|
||||
'status' => 1,
|
||||
'is_verified' => core()->getConfigData('customer.settings.email.verification') ? 0 : 1,
|
||||
'customer_group_id' => $this->customerGroupRepository->findOneWhere(['code' => 'general'])->id
|
||||
]);
|
||||
}
|
||||
|
||||
$this->create([
|
||||
'customer_id' => $customer->id,
|
||||
'provider_id' => $providerUser->getId(),
|
||||
'provider_name' => $provider,
|
||||
]);
|
||||
|
||||
return $customer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first and last name from name
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstLastName($name)
|
||||
{
|
||||
$name = trim($name);
|
||||
|
||||
$lastName = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name);
|
||||
|
||||
$firstName = trim( preg_replace('#' . $lastName . '#', '', $name) );
|
||||
|
||||
return [
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 9.05477C18 4.05274 13.9718 0 9 0C4.02823 0 0 4.05274 0 9.05477C0 13.5821 3.26613 17.3428 7.58468 18V11.6836H5.29839V9.05477H7.58468V7.08316C7.58468 4.81947 8.92742 3.54158 10.9597 3.54158C11.9758 3.54158 12.9919 3.72414 12.9919 3.72414V5.95132H11.8669C10.7419 5.95132 10.379 6.64503 10.379 7.37525V9.05477H12.8831L12.4839 11.6836H10.379V18C14.6976 17.3428 18 13.5821 18 9.05477Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 511 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.9879 14.4948C5.9879 14.4204 5.91532 14.3461 5.80645 14.3461C5.69758 14.3461 5.625 14.4204 5.625 14.4948C5.625 14.5691 5.69758 14.6434 5.80645 14.6063C5.91532 14.6063 5.9879 14.5691 5.9879 14.4948ZM4.8629 14.3089C4.8629 14.3833 4.93548 14.4948 5.04435 14.4948C5.11694 14.5319 5.22581 14.4948 5.2621 14.4204C5.2621 14.3461 5.22581 14.2718 5.11694 14.2346C5.00806 14.1974 4.89919 14.2346 4.8629 14.3089ZM6.49597 14.2718C6.3871 14.2718 6.31452 14.3461 6.31452 14.4576C6.31452 14.5319 6.42339 14.5691 6.53226 14.5319C6.64113 14.4948 6.71371 14.4576 6.67742 14.3833C6.67742 14.3089 6.56855 14.2346 6.49597 14.2718ZM8.85484 0C3.84677 0 0 3.9396 0 9.06851C0 13.1939 2.50403 16.7247 6.13306 17.9884C6.60484 18.0627 6.75 17.7654 6.75 17.5424C6.75 17.2822 6.75 16.0186 6.75 15.2381C6.75 15.2381 4.20968 15.7956 3.66532 14.1231C3.66532 14.1231 3.26613 13.0453 2.68548 12.7851C2.68548 12.7851 1.85081 12.1905 2.72177 12.1905C2.72177 12.1905 3.62903 12.2648 4.1371 13.1568C4.93548 14.6063 6.24194 14.1974 6.78629 13.9373C6.85887 13.3426 7.07661 12.9338 7.36694 12.6736C5.33468 12.4506 3.26613 12.1533 3.26613 8.58535C3.26613 7.5447 3.55645 7.06155 4.1371 6.39256C4.02823 6.1324 3.7379 5.16608 4.24597 3.86527C4.97177 3.64227 6.75 4.86875 6.75 4.86875C7.47581 4.64575 8.2379 4.57142 9 4.57142C9.79839 4.57142 10.5605 4.64575 11.2863 4.86875C11.2863 4.86875 13.0282 3.60511 13.7903 3.86527C14.2984 5.16608 13.9718 6.1324 13.8992 6.39256C14.4798 7.06155 14.8427 7.5447 14.8427 8.58535C14.8427 12.1533 12.7016 12.4506 10.6694 12.6736C10.996 12.9709 11.2863 13.5284 11.2863 14.4204C11.2863 15.6469 11.25 17.2079 11.25 17.5052C11.25 17.7654 11.4315 18.0627 11.9032 17.9512C15.5323 16.7247 18 13.1939 18 9.06851C18 3.9396 13.8992 0 8.85484 0ZM3.52016 12.8223C3.44758 12.8594 3.48387 12.9709 3.52016 13.0453C3.59274 13.0824 3.66532 13.1196 3.7379 13.0824C3.77419 13.0453 3.77419 12.9338 3.70161 12.8594C3.62903 12.8223 3.55645 12.7851 3.52016 12.8223ZM3.12097 12.525C3.08468 12.5993 3.12097 12.6365 3.19355 12.6736C3.26613 12.7108 3.33871 12.7108 3.375 12.6365C3.375 12.5993 3.33871 12.5621 3.26613 12.525C3.19355 12.4878 3.15726 12.4878 3.12097 12.525ZM4.28226 13.8629C4.24597 13.9001 4.24597 14.0116 4.35484 14.0859C4.42742 14.1603 4.53629 14.1974 4.57258 14.1231C4.60887 14.0859 4.60887 13.9744 4.53629 13.9001C4.46371 13.8258 4.35484 13.7886 4.28226 13.8629ZM3.88306 13.3054C3.81048 13.3426 3.81048 13.4541 3.88306 13.5284C3.95565 13.6028 4.02823 13.6399 4.10081 13.6028C4.1371 13.5656 4.1371 13.4541 4.10081 13.3798C4.02823 13.3054 3.95565 13.2683 3.88306 13.3054Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM14.9099 8.20562C14.9561 8.50041 15 8.77964 15 9.14516C15 12.5806 12.6148 15 9.09836 15C5.70492 15 3 12.3387 3 9C3 5.68548 5.70492 3 9.09836 3C10.7213 3 12.123 3.60484 13.1803 4.57258L11.5082 6.14516C9.34426 4.08871 5.31148 5.6371 5.31148 9C5.31148 11.1048 7.0082 12.7984 9.09836 12.7984C11.5082 12.7984 12.418 11.1048 12.541 10.2097H9.09836V8.15323H14.9016C14.9044 8.17076 14.9071 8.18821 14.9099 8.20562Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 683 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM13.9955 4.00447C14.692 4.70089 14.9062 5.55804 14.9598 6.52233C15.0134 7.5134 15.0134 10.4866 14.9598 11.4777C14.9062 12.442 14.692 13.2723 13.9955 13.9955C13.2991 14.692 12.442 14.9063 11.4777 14.9598C10.4866 15.0134 7.51339 15.0134 6.52232 14.9598C5.55804 14.9063 4.72768 14.692 4.00446 13.9955C3.30804 13.2723 3.09375 12.442 3.04018 11.4777C2.98661 10.4866 2.98661 7.5134 3.04018 6.52233C3.09375 5.55804 3.30804 4.70089 4.00446 4.00447C4.72768 3.30804 5.55804 3.09375 6.52232 3.04018C7.51339 2.98661 10.4866 2.98661 11.4777 3.04018C12.442 3.09375 13.2991 3.30804 13.9955 4.00447ZM12.8911 5.82322C12.8911 5.42143 12.5696 5.10001 12.1679 5.10001C11.7661 5.10001 11.4446 5.42143 11.4446 5.82322C11.4446 6.22501 11.7661 6.54643 12.1679 6.54643C12.5696 6.54643 12.8911 6.22501 12.8911 5.82322ZM8.98036 5.93036C7.26607 5.93036 5.9 7.32322 5.9 9.01072C5.9 10.725 7.26607 12.0911 8.98036 12.0911C10.6679 12.0911 12.0607 10.725 12.0607 9.01072C12.0607 7.32322 10.6679 5.93036 8.98036 5.93036ZM7 8.98658C7 10.1141 7.91275 11 9.01342 11C10.1141 11 11 10.1141 11 8.98658C11 7.88591 10.1141 7 9.01342 7C7.88591 7 7 7.88591 7 8.98658Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18ZM4.15625 7.34375V14H6.21875V7.34375H4.15625ZM3.96875 5.21875C3.96875 5.875 4.5 6.40625 5.1875 6.40625C5.84375 6.40625 6.375 5.875 6.375 5.21875C6.375 4.5625 5.84375 4 5.1875 4C4.5 4 3.96875 4.5625 3.96875 5.21875ZM11.9062 14H14V10.3438C14 8.5625 13.5938 7.15625 11.5 7.15625C10.5 7.15625 9.8125 7.71875 9.53125 8.25H9.5V7.34375H7.53125V14H9.59375V10.7188C9.59375 9.84375 9.75 9 10.8438 9C11.9062 9 11.9062 10 11.9062 10.75V14Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 703 B |