update cart button is not shown, when only products without quantity box are in cart, tests added

This commit is contained in:
Steffen Mahler 2020-01-28 15:38:07 +01:00
commit 14c0276fce
165 changed files with 10728 additions and 548 deletions

View File

@ -1,7 +1,7 @@
APP_NAME=Bagisto APP_NAME=Laravel
APP_ENV=local APP_ENV=local
APP_VERSION=0.1.8 APP_VERSION=0.1.5
APP_KEY=base64:NFtGjjFAqET6RlX3PVC/gFpzHb4jK1OxDc3cuU5Asz4= APP_KEY=base64:G4KY3tUsTaY9ONo1n/QyJvVLQZdJDgbIkSJswFK01HE=
APP_DEBUG=true APP_DEBUG=true
APP_URL=http://localhost APP_URL=http://localhost
@ -10,14 +10,14 @@ LOG_CHANNEL=stack
DB_CONNECTION=mysql DB_CONNECTION=mysql
DB_HOST=mysql DB_HOST=mysql
DB_PORT=3306 DB_PORT=3306
DB_DATABASE=bagisto_test DB_DATABASE=bagisto_testing
DB_USERNAME=root DB_USERNAME=bagisto
DB_PASSWORD=root DB_PASSWORD=secret
BROADCAST_DRIVER=log BROADCAST_DRIVER=log
CACHE_DRIVER=file CACHE_DRIVER=file
SESSION_DRIVER=file SESSION_DRIVER=file
SESSION_LIFETIME=20 SESSION_LIFETIME=120
QUEUE_DRIVER=sync QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1 REDIS_HOST=127.0.0.1
@ -31,10 +31,6 @@ MAIL_USERNAME=
MAIL_PASSWORD= MAIL_PASSWORD=
MAIL_ENCRYPTION=tls MAIL_ENCRYPTION=tls
SHOP_MAIL_FROM=
ADMIN_MAIL_TO=
fixer_api_key=
PUSHER_APP_ID= PUSHER_APP_ID=
PUSHER_APP_KEY= PUSHER_APP_KEY=
@ -43,3 +39,6 @@ PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
SHOP_MAIL_FROM=test@example.com
ADMIN_MAIL_TO=test@example.com

63
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,63 @@
name: CI
on: [push, pull_request]
jobs:
tests:
name: Run tests
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: bagisto_testing
MYSQL_USER: bagisto
MYSQL_PASSWORD: secret
ports:
- 3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup php
uses: shivammathur/setup-php@v1
with:
php-version: '7.3'
extensions: intl, curl, mbstring, openssl, pdo, pdo_mysql, tokenizer
- name: Set environment
run: |
set -e
sed -i "s|^\(DB_HOST=\s*\).*$|\1127.0.0.1|" .env.testing
sed -i "s|^\(DB_PORT=\s*\).*$|\1${{ job.services.mysql.ports['3306'] }}|" .env.testing
printf "the complete .env.testing ...\n\n"
cat .env.testing
- name: Composer install
run: |
set -e
composer global require hirak/prestissimo
composer install --no-interaction --ansi --no-progress --no-suggest --optimize-autoloader
- name: Migrate database
run: set -e && php artisan migrate --env=testing
- name: Execute unit tests
run: set -e && vendor/bin/codecept run unit
- name: Execute functional tests
run: set -e && vendor/bin/codecept run functional
- name: Execute trigger tests
run: set -e && vendor/bin/codecept run trigger
- name: Persist test artifacts
uses: actions/upload-artifact@v1
if: always()
with:
name: test_artifacts
path: tests/_output

3
.gitignore vendored
View File

@ -1,3 +1,5 @@
/docker-compose-collection
/bin
/node_modules /node_modules
/public/hot /public/hot
/public/storage /public/storage
@ -15,7 +17,6 @@ npm-debug.log
yarn-error.log yarn-error.log
.env .env
/ignorables/* /ignorables/*
composer.lock
yarn.lock yarn.lock
package-lock.json package-lock.json
yarn.lock yarn.lock

View File

@ -64,7 +64,7 @@ Take advantage of two of the hottest frameworks used in this project -- Laravel
* **OS**: Ubuntu 16.04 LTS or higher / Windows 7 or Higher (WampServer / XAMPP). * **OS**: Ubuntu 16.04 LTS or higher / Windows 7 or Higher (WampServer / XAMPP).
* **SERVER**: Apache 2 or NGINX. * **SERVER**: Apache 2 or NGINX.
* **RAM**: 3 GB or higher. * **RAM**: 3 GB or higher.
* **PHP**: 7.1.3 or higher. * **PHP**: 7.2.0 or higher.
* **Processor**: Clock Cycle 1 Ghz or higher. * **Processor**: Clock Cycle 1 Ghz or higher.
* **For MySQL users**: 5.7.23 or higher. * **For MySQL users**: 5.7.23 or higher.
* **For MariaDB users**: 10.2.7 or Higher. * **For MariaDB users**: 10.2.7 or Higher.

View File

@ -9,7 +9,7 @@
"license": "MIT", "license": "MIT",
"type": "project", "type": "project",
"require": { "require": {
"php": "^7.1.3", "php": "^7.2.0",
"ext-curl": "*", "ext-curl": "*",
"ext-intl": "*", "ext-intl": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
@ -18,28 +18,33 @@
"ext-pdo_mysql": "*", "ext-pdo_mysql": "*",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"astrotomic/laravel-translatable": "^11.0.0", "astrotomic/laravel-translatable": "^11.0.0",
"barryvdh/laravel-dompdf": "0.8.3", "barryvdh/laravel-dompdf": "0.8.5",
"doctrine/dbal": "2.9.2", "doctrine/dbal": "2.9.2",
"fideloper/proxy": "^4.0", "fideloper/proxy": "^4.0",
"flynsarmy/db-blade-compiler": "*", "flynsarmy/db-blade-compiler": "*",
"guzzlehttp/guzzle": "~6.0", "guzzlehttp/guzzle": "~6.0",
"intervention/image": "^2.4", "intervention/image": "^2.4",
"intervention/imagecache": "^2.3", "intervention/imagecache": "^2.3",
"kalnoy/nestedset": "^4.3", "kalnoy/nestedset": "5.0.0",
"konekt/concord": "^1.2", "konekt/concord": "^1.2",
"laravel/framework": "5.6.*", "laravel/framework": "^6.0",
"laravel/helpers": "^1.1",
"laravel/tinker": "^1.0", "laravel/tinker": "^1.0",
"maatwebsite/excel": "3.1.11", "maatwebsite/excel": "3.1.18",
"prettus/l5-repository": "2.6.32", "nwidart/laravel-modules": "^3.2",
"tymon/jwt-auth": "1.0.0-rc.4" "prettus/l5-repository": "^2.6",
"tymon/jwt-auth": "^1.0.0"
}, },
"require-dev": { "require-dev": {
"codeception/codeception": "3.1.*",
"barryvdh/laravel-debugbar": "^3.1", "barryvdh/laravel-debugbar": "^3.1",
"codeception/codeception": "^4.0",
"codeception/module-asserts": "^1.1",
"codeception/module-filesystem": "^1.0",
"codeception/module-laravel5": "^1.0",
"filp/whoops": "^2.0", "filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4", "fzaninotto/faker": "^1.4",
"laravel/dusk": "^4.0", "laravel/dusk": "^5.7.0",
"mockery/mockery": "^1.0", "mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0", "nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0" "phpunit/phpunit": "^7.0"

7837
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -93,6 +93,19 @@ return [
'fallback_locale' => 'en', 'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Default Country
|--------------------------------------------------------------------------
|
| Here you may specify the default country by country code.
| Ensure it is uppercase and reflects the 'code' column of the
| countries table.
|
*/
'default_country' => null,
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Base Currency Code | Base Currency Code

View File

@ -100,7 +100,7 @@ return [
'prefix' => env( 'prefix' => env(
'CACHE_PREFIX', 'CACHE_PREFIX',
str_slug(env('APP_NAME', 'laravel'), '_').'_cache' \Illuminate\Support\Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'
), ),
]; ];

View File

@ -124,7 +124,7 @@ return [
'cookie' => env( 'cookie' => env(
'SESSION_COOKIE', 'SESSION_COOKIE',
str_slug(env('APP_NAME', 'laravel'), '_').'_session' \Illuminate\Support\Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
), ),
/* /*

View File

@ -19,7 +19,7 @@
"lodash": "^4.17.4", "lodash": "^4.17.4",
"popper.js": "^1.12", "popper.js": "^1.12",
"resolve-url-loader": "^3.1.0", "resolve-url-loader": "^3.1.0",
"sass": "^1.24.4", "sass": "^1.24.5",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"vue": "^2.5.7", "vue": "^2.5.7",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11"

View File

@ -98,7 +98,7 @@ class CartController extends Controller
*/ */
public function store($id) public function store($id)
{ {
Event::fire('checkout.cart.item.add.before', $id); Event::dispatch('checkout.cart.item.add.before', $id);
$result = Cart::addProduct($id, request()->except('_token')); $result = Cart::addProduct($id, request()->except('_token'));
@ -113,7 +113,7 @@ class CartController extends Controller
if ($customer = auth($this->guard)->user()) if ($customer = auth($this->guard)->user())
$this->wishlistRepository->deleteWhere(['product_id' => $id, 'customer_id' => $customer->id]); $this->wishlistRepository->deleteWhere(['product_id' => $id, 'customer_id' => $customer->id]);
Event::fire('checkout.cart.item.add.after', $result); Event::dispatch('checkout.cart.item.add.after', $result);
Cart::collectTotals(); Cart::collectTotals();
@ -143,11 +143,11 @@ class CartController extends Controller
foreach (request()->get('qty') as $itemId => $qty) { foreach (request()->get('qty') as $itemId => $qty) {
$item = $this->cartItemRepository->findOneByField('id', $itemId); $item = $this->cartItemRepository->findOneByField('id', $itemId);
Event::fire('checkout.cart.item.update.before', $itemId); Event::dispatch('checkout.cart.item.update.before', $itemId);
Cart::updateItems(request()->all()); Cart::updateItems(request()->all());
Event::fire('checkout.cart.item.update.after', $item); Event::dispatch('checkout.cart.item.update.after', $item);
} }
Cart::collectTotals(); Cart::collectTotals();
@ -167,11 +167,11 @@ class CartController extends Controller
*/ */
public function destroy() public function destroy()
{ {
Event::fire('checkout.cart.delete.before'); Event::dispatch('checkout.cart.delete.before');
Cart::deActivateCart(); Cart::deActivateCart();
Event::fire('checkout.cart.delete.after'); Event::dispatch('checkout.cart.delete.after');
$cart = Cart::getCart(); $cart = Cart::getCart();
@ -189,11 +189,11 @@ class CartController extends Controller
*/ */
public function destroyItem($id) public function destroyItem($id)
{ {
Event::fire('checkout.cart.item.delete.before', $id); Event::dispatch('checkout.cart.item.delete.before', $id);
Cart::removeItem($id); Cart::removeItem($id);
Event::fire('checkout.cart.item.delete.after', $id); Event::dispatch('checkout.cart.item.delete.after', $id);
Cart::collectTotals(); Cart::collectTotals();
@ -213,11 +213,11 @@ class CartController extends Controller
*/ */
public function moveToWishlist($id) public function moveToWishlist($id)
{ {
Event::fire('checkout.cart.item.move-to-wishlist.before', $id); Event::dispatch('checkout.cart.item.move-to-wishlist.before', $id);
Cart::moveToWishlist($id); Cart::moveToWishlist($id);
Event::fire('checkout.cart.item.move-to-wishlist.after', $id); Event::dispatch('checkout.cart.item.move-to-wishlist.after', $id);
Cart::collectTotals(); Cart::collectTotals();

View File

@ -12,6 +12,7 @@ use Webkul\API\Http\Resources\Checkout\CartShippingRate as CartShippingRateResou
use Webkul\API\Http\Resources\Sales\Order as OrderResource; use Webkul\API\Http\Resources\Sales\Order as OrderResource;
use Webkul\Checkout\Http\Requests\CustomerAddressForm; use Webkul\Checkout\Http\Requests\CustomerAddressForm;
use Webkul\Sales\Repositories\OrderRepository; use Webkul\Sales\Repositories\OrderRepository;
use Illuminate\Support\Str;
use Cart; use Cart;
/** /**
@ -90,7 +91,7 @@ class CheckoutController extends Controller
unset($data['billing']['address_id']); unset($data['billing']['address_id']);
} }
if (isset($data['shipping']['id']) && str_contains($data['shipping']['id'], 'address_')) { if (isset($data['shipping']['id']) && Str::contains($data['shipping']['id'], 'address_')) {
unset($data['shipping']['id']); unset($data['shipping']['id']);
unset($data['shipping']['address_id']); unset($data['shipping']['address_id']);
} }

View File

@ -60,11 +60,11 @@ class CustomerController extends Controller
'customer_group_id' => 1 'customer_group_id' => 1
]); ]);
Event::fire('customer.registration.before'); Event::dispatch('customer.registration.before');
$customer = $this->customerRepository->create($data); $customer = $this->customerRepository->create($data);
Event::fire('customer.registration.after', $customer); Event::dispatch('customer.registration.after', $customer);
return response()->json([ return response()->json([
'message' => 'Your account has been created successfully.' 'message' => 'Your account has been created successfully.'

View File

@ -66,7 +66,7 @@ class SessionController extends Controller
], 401); ], 401);
} }
Event::fire('customer.after.login', request('email')); Event::dispatch('customer.after.login', request('email'));
$customer = auth($this->guard)->user(); $customer = auth($this->guard)->user();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,39 @@
/*!
* jQuery JavaScript Library v3.4.1
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2019-05-01T21:04Z
*/
/*!
* Sizzle CSS Selector Engine v2.3.4
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2019-04-08
*/
/*!
* Vue.js v2.6.11
* (c) 2014-2019 Evan You
* Released under the MIT License.
*/
/**
* @license
* Lodash <https://lodash.com/>
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/

View File

@ -1,4 +1,4 @@
{ {
"/js/admin.js": "/js/admin.js?id=d1daece26673ab30942b", "/js/admin.js": "/js/admin.js?id=8c0724bfd64081ee94bf",
"/css/admin.css": "/css/admin.css?id=c845e7c275d4df7fa03f" "/css/admin.css": "/css/admin.css?id=9a8c6ebe5e08965b7ae6"
} }

View File

@ -182,12 +182,6 @@ return [
'sort' => 2, 'sort' => 2,
'icon-class' => '' 'icon-class' => ''
], [ ], [
'key' => 'settings.development',
'name' => 'admin::app.settings.development.title',
'route' => 'admin.development.index',
'sort' => 8,
'icon-class' => ''
],[
'key' => 'promotions', 'key' => 'promotions',
'name' => 'admin::app.layouts.promotions', 'name' => 'admin::app.layouts.promotions',
'route' => 'admin.catalog-rules.index', 'route' => 'admin.catalog-rules.index',

View File

@ -87,10 +87,21 @@ return [
'key' => 'catalog.products', 'key' => 'catalog.products',
'name' => 'admin::app.admin.system.products', 'name' => 'admin::app.admin.system.products',
'sort' => 2 'sort' => 2
], [
'key' => 'catalog.products.guest-checkout',
'name' => 'admin::app.admin.system.guest-checkout',
'sort' => 1,
'fields' => [
[
'name' => 'allow-guest-checkout',
'title' => 'admin::app.admin.system.allow-guest-checkout',
'type' => 'boolean'
]
]
], [ ], [
'key' => 'catalog.products.review', 'key' => 'catalog.products.review',
'name' => 'admin::app.admin.system.review', 'name' => 'admin::app.admin.system.review',
'sort' => 1, 'sort' => 2,
'fields' => [ 'fields' => [
[ [
'name' => 'guest_review', 'name' => 'guest_review',

View File

@ -118,7 +118,7 @@ class ConfigurationController extends Controller
*/ */
public function store() public function store()
{ {
Event::fire('core.configuration.save.before'); Event::dispatch('core.configuration.save.before');
if (request()->has('general.design.admin_logo.logo_image') && ! request()->input('general.design.admin_logo.logo_image.delete')) { if (request()->has('general.design.admin_logo.logo_image') && ! request()->input('general.design.admin_logo.logo_image.delete')) {
$this->validate(request(), [ $this->validate(request(), [
@ -128,7 +128,7 @@ class ConfigurationController extends Controller
$this->coreConfigRepository->create(request()->all()); $this->coreConfigRepository->create(request()->all());
Event::fire('core.configuration.save.after'); Event::dispatch('core.configuration.save.after');
session()->flash('success', trans('admin::app.configuration.save-message')); session()->flash('success', trans('admin::app.configuration.save-message'));

View File

@ -755,12 +755,6 @@ Route::group(['middleware' => ['web']], function () {
// 'redirect' => 'admin.cms.index' // 'redirect' => 'admin.cms.index'
// ])->name('admin.cms.delete'); // ])->name('admin.cms.delete');
}); });
// Development settings
Route::prefix('development')->group(function () {
Route::get('/', 'Webkul\Admin\Http\Controllers\Development\DashboardController@index')
->name('admin.development.index');
});
}); });
}); });
}); });

View File

@ -45,7 +45,6 @@ class NewInvoiceNotification extends Mailable
$order = $this->invoice->order; $order = $this->invoice->order;
return $this->to($order->customer_email, $order->customer_full_name) return $this->to($order->customer_email, $order->customer_full_name)
->from(config('mail.from'))
->subject(trans('shop::app.mail.invoice.subject', ['order_id' => $order->increment_id])) ->subject(trans('shop::app.mail.invoice.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-invoice'); ->view('shop::emails.sales.new-invoice');
} }

View File

@ -42,7 +42,6 @@ class NewOrderNotification extends Mailable
public function build() public function build()
{ {
return $this->to($this->order->customer_email, $this->order->customer_full_name) return $this->to($this->order->customer_email, $this->order->customer_full_name)
->from(config('mail.from'))
->subject(trans('shop::app.mail.order.subject')) ->subject(trans('shop::app.mail.order.subject'))
->view('shop::emails.sales.new-order'); ->view('shop::emails.sales.new-order');
} }

View File

@ -45,7 +45,6 @@ class NewRefundNotification extends Mailable
$order = $this->refund->order; $order = $this->refund->order;
return $this->to($order->customer_email, $order->customer_full_name) return $this->to($order->customer_email, $order->customer_full_name)
->from(config('mail.from'))
->subject(trans('shop::app.mail.refund.subject', ['order_id' => $order->increment_id])) ->subject(trans('shop::app.mail.refund.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-refund'); ->view('shop::emails.sales.new-refund');
} }

View File

@ -45,7 +45,6 @@ class NewShipmentNotification extends Mailable
$order = $this->shipment->order; $order = $this->shipment->order;
return $this->to($order->customer_email, $order->customer_full_name) return $this->to($order->customer_email, $order->customer_full_name)
->from(config('mail.from'))
->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->increment_id])) ->subject(trans('shop::app.mail.shipment.subject', ['order_id' => $order->increment_id]))
->view('shop::emails.sales.new-shipment'); ->view('shop::emails.sales.new-shipment');
} }

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
<title>Angle-Right</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Angle-Right" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<polyline id="Path-3" stroke="#A2A2A2" stroke-width="3" points="7 3 14 10.058476 7.11598308 17"></polyline>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 618 B

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
<title>Icon-Graph-Green</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Icon-Graph-Green" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g transform="translate(8.000000, 5.000000)" stroke="#00C357" stroke-width="2">
<path d="M4,0 L4,14" id="Path-2"></path>
<path d="M4,0 L0,4" id="Path-3"></path>
<path d="M7.92330631,0 L3.92330631,4" id="Path-3-Copy" transform="translate(5.961653, 2.000000) scale(-1, 1) translate(-5.961653, -2.000000) "></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 881 B

View File

@ -87,7 +87,7 @@ $(document).ready(function () {
}, },
addFlashMessages() { addFlashMessages() {
if (typeof flashMessages !== 'undefined') { if (typeof flashMessages == 'undefined') {
return; return;
}; };

View File

@ -1202,6 +1202,9 @@ return [
'system' => [ 'system' => [
'catalog' => 'Catalog', 'catalog' => 'Catalog',
'products' => 'Products', 'products' => 'Products',
'guest-checkout' => 'Guest Checkout',
'allow-guest-checkout' => 'Allow Guest Checkout',
'allow-guest-checkout-hint' => 'Hint: If turned on, this option can be configured for each product specifically.',
'review' => 'Review', 'review' => 'Review',
'allow-guest-review' => 'Allow Guest Review', 'allow-guest-review' => 'Allow Guest Review',
'inventory' => 'Inventory', 'inventory' => 'Inventory',

View File

@ -48,7 +48,7 @@
<div slot="body"> <div slot="body">
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']"> <div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('admin::app.account.password') }}</label> <label for="password">{{ __('admin::app.account.password') }}</label>
<input type="password" v-validate="'min:6'" class="control" id="password" name="password" data-vv-as="&quot;{{ __('admin::app.account.password') }}&quot;"/> <input type="password" v-validate="'min:6'" class="control" id="password" name="password" ref="password" data-vv-as="&quot;{{ __('admin::app.account.password') }}&quot;"/>
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span> <span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div> </div>

View File

@ -108,7 +108,7 @@
<div class="control-group"> <div class="control-group">
<label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label> <label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label>
<input type="text" class="control" id="locale-{{ $locale->code }}" name="<?php echo $locale->code; ?>[name]" value="{{ old($locale->code)['name'] ?? $attribute->translate($locale->code)['name'] }}"/> <input type="text" class="control" id="locale-{{ $locale->code }}" name="<?php echo $locale->code; ?>[name]" value="{{ old($locale->code)['name'] ?? ($attribute->translate($locale->code)->name ?? '') }}"/>
</div> </div>
@endforeach @endforeach
@ -432,7 +432,7 @@
@endif @endif
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale) @foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
row['{{ $locale->code }}'] = "{{ $option->translate($locale->code)['label'] }}"; row['{{ $locale->code }}'] = "{{ $option->translate($locale->code)['label'] ?? '' }}";
@endforeach @endforeach
this.optionRows.push(row); this.optionRows.push(row);

View File

@ -77,6 +77,10 @@
@foreach ($customAttributes as $attribute) @foreach ($customAttributes as $attribute)
<?php <?php
if ($attribute->code == 'guest_checkout' && ! core()->getConfigData('catalog.products.guest-checkout.allow-guest-checkout')) {
continue;
}
$validations = []; $validations = [];
if ($attribute->is_required) { if ($attribute->is_required) {

View File

@ -58,7 +58,7 @@
<div class="control-group" :class="[errors.has('html_content') ? 'has-error' : '']"> <div class="control-group" :class="[errors.has('html_content') ? 'has-error' : '']">
<label for="html_content" class="required">{{ __('admin::app.cms.pages.content') }}</label> <label for="html_content" class="required">{{ __('admin::app.cms.pages.content') }}</label>
<textarea type="text" class="control" id="content" name="html_content" v-validate="'required'" value="{{ old('html_content') }}" data-vv-as="&quot;{{ __('admin::app.cms.pages.content') }}&quot;"></textarea> <textarea type="text" class="control" id="content" name="html_content" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.cms.pages.content') }}&quot;">{{ old('html_content') }}</textarea>
<span class="control-error" v-if="errors.has('html_content')">@{{ errors.first('html_content') }}</span> <span class="control-error" v-if="errors.has('html_content')">@{{ errors.first('html_content') }}</span>
</div> </div>
@ -89,13 +89,14 @@
<div class="control-group"> <div class="control-group">
<label for="meta_keywords">{{ __('admin::app.cms.pages.meta_keywords') }}</label> <label for="meta_keywords">{{ __('admin::app.cms.pages.meta_keywords') }}</label>
<textarea type="text" class="control" name="meta_keywords" value="{{ old('meta_keywords') }}"></textarea> <textarea type="text" class="control" name="meta_keywords">{{ old('meta_keywords') }}</textarea>
</div> </div>
<div class="control-group"> <div class="control-group">
<label for="meta_description">{{ __('admin::app.cms.pages.meta_description') }}</label> <label for="meta_description">{{ __('admin::app.cms.pages.meta_description') }}</label>
<textarea type="text" class="control" name="meta_description" value="{{ old('meta_description') }}"></textarea> <textarea type="text" class="control" name="meta_description">{{ old('meta_description') }}</textarea>
</div> </div>
</div> </div>
</accordian> </accordian>

View File

@ -77,9 +77,7 @@
<div class="control-group" :class="[errors.has('{{$locale}}[html_content]') ? 'has-error' : '']"> <div class="control-group" :class="[errors.has('{{$locale}}[html_content]') ? 'has-error' : '']">
<label for="html_content" class="required">{{ __('admin::app.cms.pages.content') }}</label> <label for="html_content" class="required">{{ __('admin::app.cms.pages.content') }}</label>
<textarea type="text" class="control" id="content" name="{{$locale}}[html_content]" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.cms.pages.content') }}&quot;"> <textarea type="text" class="control" id="content" name="{{$locale}}[html_content]" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.cms.pages.content') }}&quot;">{{ old($locale)['html_content'] ?? ($page->translate($locale)['html_content'] ?? '') }}</textarea>
{{ old($locale)['html_content'] ?? ($page->translate($locale)['html_content'] ?? '') }}
</textarea>
<span class="control-error" v-if="errors.has('{{$locale}}[html_content]')">@{{ errors.first('{!!$locale!!}[html_content]') }}</span> <span class="control-error" v-if="errors.has('{{$locale}}[html_content]')">@{{ errors.first('{!!$locale!!}[html_content]') }}</span>
</div> </div>
@ -105,17 +103,15 @@
<div class="control-group"> <div class="control-group">
<label for="meta_keywords">{{ __('admin::app.cms.pages.meta_keywords') }}</label> <label for="meta_keywords">{{ __('admin::app.cms.pages.meta_keywords') }}</label>
<textarea type="text" class="control" name="{{$locale}}[meta_keywords]"> <textarea type="text" class="control" name="{{$locale}}[meta_keywords]">{{ old($locale)['meta_keywords'] ?? ($page->translate($locale)['meta_keywords'] ?? '') }}</textarea>
{{ old($locale)['meta_keywords'] ?? ($page->translate($locale)['meta_keywords'] ?? '') }}
</textarea>
</div> </div>
<div class="control-group"> <div class="control-group">
<label for="meta_description">{{ __('admin::app.cms.pages.meta_description') }}</label> <label for="meta_description">{{ __('admin::app.cms.pages.meta_description') }}</label>
<textarea type="text" class="control" name="{{$locale}}[meta_description]"> <textarea type="text" class="control" name="{{$locale}}[meta_description]">{{ old($locale)['meta_description'] ?? ($page->translate($locale)['meta_description'] ?? '') }}</textarea>
{{ old($locale)['meta_description'] ?? ($page->translate($locale)['meta_description'] ?? '') }}
</textarea>
</div> </div>
</div> </div>
</accordian> </accordian>

View File

@ -54,7 +54,7 @@
<div class="form-container"> <div class="form-container">
@csrf() @csrf()
@if ($groups = array_get($config->items, request()->route('slug') . '.children.' . request()->route('slug2') . '.children')) @if ($groups = \Illuminate\Support\Arr::get($config->items, request()->route('slug') . '.children.' . request()->route('slug2') . '.children'))
@foreach ($groups as $key => $item) @foreach ($groups as $key => $item)
@ -65,6 +65,11 @@
@include ('admin::configuration.field-type', ['field' => $field]) @include ('admin::configuration.field-type', ['field' => $field])
@php ($hint = $field['title'] . '-hint')
@if ($hint !== __($hint))
{{ __($hint) }}
@endif
@endforeach @endforeach
</div> </div>

View File

@ -4,7 +4,7 @@
<?php $keys = explode('.', $menu->currentKey); ?> <?php $keys = explode('.', $menu->currentKey); ?>
@if(isset($keys) && strlen($keys[0])) @if(isset($keys) && strlen($keys[0]))
@foreach (array_get($menu->items, current($keys) . '.children') as $item) @foreach (\Illuminate\Support\Arr::get($menu->items, current($keys) . '.children') as $item)
<li class="{{ $menu->getActive($item) }}"> <li class="{{ $menu->getActive($item) }}">
<a href="{{ $item['url'] }}"> <a href="{{ $item['url'] }}">
{{ trans($item['name']) }} {{ trans($item['name']) }}

View File

@ -4,11 +4,11 @@
<?php $keys = explode('.', $menu->currentKey); ?> <?php $keys = explode('.', $menu->currentKey); ?>
@if ($items = array_get($menu->items, implode('.children.', array_slice($keys, 0, 2)) . '.children')) @if ($items = \Illuminate\Support\Arr::get($menu->items, implode('.children.', array_slice($keys, 0, 2)) . '.children'))
<ul> <ul>
@foreach (array_get($menu->items, implode('.children.', array_slice($keys, 0, 2)) . '.children') as $item) @foreach (\Illuminate\Support\Arr::get($menu->items, implode('.children.', array_slice($keys, 0, 2)) . '.children') as $item)
<li class="{{ $menu->getActive($item) }}"> <li class="{{ $menu->getActive($item) }}">
<a href="{{ $item['url'] }}"> <a href="{{ $item['url'] }}">
@ -24,7 +24,7 @@
@else @else
@if ($items = array_get($config->items, request()->route('slug') . '.children')) @if ($items = \Illuminate\Support\Arr::get($config->items, request()->route('slug') . '.children'))
<ul> <ul>

View File

@ -45,7 +45,7 @@
padding: 5px 10px; padding: 5px 10px;
border-bottom: solid 1px #d3d3d3; border-bottom: solid 1px #d3d3d3;
border-left: solid 1px #d3d3d3; border-left: solid 1px #d3d3d3;
color: $font-color; color: #3A3A3A;
vertical-align: middle; vertical-align: middle;
} }

View File

@ -28,7 +28,7 @@
<div class="form-container"> <div class="form-container">
@csrf() @csrf()
{!! view_render_event('bagisto.admin.settings.locale.edit.before') !!} {!! view_render_event('bagisto.admin.settings.locale.edit.before', ['locale' => $locale]) !!}
<input name="_method" type="hidden" value="PUT"> <input name="_method" type="hidden" value="PUT">
@ -60,7 +60,7 @@
</div> </div>
</accordian> </accordian>
{!! view_render_event('bagisto.admin.settings.locale.edit.after') !!} {!! view_render_event('bagisto.admin.settings.locale.edit.after', ['locale' => $locale]) !!}
</div> </div>
</div> </div>
</form> </form>

View File

@ -38,7 +38,7 @@
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']"> <div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('admin::app.users.reset-password.password') }}</label> <label for="password">{{ __('admin::app.users.reset-password.password') }}</label>
<input type="password" v-validate="'required|min:6'" class="control" id="password" name="password" data-vv-as="&quot;{{ __('admin::app.users.reset-password.password') }}&quot;"/> <input type="password" v-validate="'required|min:6'" class="control" id="password" name="password" ref="password" data-vv-as="&quot;{{ __('admin::app.users.reset-password.password') }}&quot;"/>
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span> <span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div> </div>

View File

@ -47,7 +47,7 @@
<div slot="body"> <div slot="body">
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']"> <div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('admin::app.users.users.password') }}</label> <label for="password">{{ __('admin::app.users.users.password') }}</label>
<input type="password" v-validate="'min:6|max:18'" class="control" id="password" name="password" data-vv-as="&quot;{{ __('admin::app.users.users.password') }}&quot;"/> <input type="password" v-validate="'min:6|max:18'" class="control" id="password" name="password" ref="password" data-vv-as="&quot;{{ __('admin::app.users.users.password') }}&quot;"/>
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span> <span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div> </div>

View File

@ -48,7 +48,7 @@
<div slot="body"> <div slot="body">
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']"> <div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('admin::app.users.users.password') }}</label> <label for="password">{{ __('admin::app.users.users.password') }}</label>
<input type="password" v-validate="'min:6|max:18'" class="control" id="password" name="password" data-vv-as="&quot;{{ __('admin::app.users.users.password') }}&quot;"/> <input type="password" v-validate="'min:6|max:18'" class="control" id="password" name="password" ref="password" data-vv-as="&quot;{{ __('admin::app.users.users.password') }}&quot;"/>
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span> <span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div> </div>

View File

@ -16,7 +16,6 @@ mix.setPublicPath(publicPath).mergeManifest();
mix.disableNotifications(); mix.disableNotifications();
mix.js(__dirname + "/src/Resources/assets/js/app.js", "js/admin.js") mix.js(__dirname + "/src/Resources/assets/js/app.js", "js/admin.js")
.copyDirectory( __dirname + '/src/Resources/assets/images', publicPath + '/images')
.sass(__dirname + "/src/Resources/assets/sass/app.scss", "css/admin.css") .sass(__dirname + "/src/Resources/assets/sass/app.scss", "css/admin.css")
.options({ .options({
processCssUrls: false processCssUrls: false

View File

@ -3,16 +3,20 @@
namespace Webkul\Attribute\Database\Seeders; namespace Webkul\Attribute\Database\Seeders;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use DB; use Illuminate\Support\Facades\DB;
class AttributeFamilyTableSeeder extends Seeder class AttributeFamilyTableSeeder extends Seeder
{ {
public function run() public function run()
{ {
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
DB::table('attribute_families')->delete(); DB::table('attribute_families')->delete();
DB::table('attribute_families')->insert([ DB::table('attribute_families')->insert([
['id' => '1','code' => 'default','name' => 'Default','status' => '0','is_user_defined' => '1'] ['id' => '1','code' => 'default','name' => 'Default','status' => '0','is_user_defined' => '1']
]); ]);
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
} }
} }

View File

@ -3,12 +3,17 @@
namespace Webkul\Attribute\Database\Seeders; namespace Webkul\Attribute\Database\Seeders;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use DB; use Illuminate\Support\Facades\DB;
class AttributeGroupTableSeeder extends Seeder class AttributeGroupTableSeeder extends Seeder
{ {
public function run() public function run()
{ {
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
DB::table('attribute_groups')->delete();
DB::table('attribute_group_mappings')->delete();
DB::table('attribute_groups')->delete(); DB::table('attribute_groups')->delete();
DB::table('attribute_groups')->insert([ DB::table('attribute_groups')->insert([
@ -42,9 +47,12 @@ class AttributeGroupTableSeeder extends Seeder
['attribute_id' => '20','attribute_group_id' => '5','position' => '2'], ['attribute_id' => '20','attribute_group_id' => '5','position' => '2'],
['attribute_id' => '21','attribute_group_id' => '5','position' => '3'], ['attribute_id' => '21','attribute_group_id' => '5','position' => '3'],
['attribute_id' => '22','attribute_group_id' => '5','position' => '4'], ['attribute_id' => '22','attribute_group_id' => '5','position' => '4'],
['attribute_id' => '23','attribute_group_id' => '1','position' => '9'], ['attribute_id' => '23','attribute_group_id' => '1','position' => '10'],
['attribute_id' => '24','attribute_group_id' => '1','position' => '10'], ['attribute_id' => '24','attribute_group_id' => '1','position' => '11'],
['attribute_id' => '25','attribute_group_id' => '1','position' => '11'] ['attribute_id' => '25','attribute_group_id' => '1','position' => '12'],
['attribute_id' => '26','attribute_group_id' => '1','position' => '9']
]); ]);
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
} }
} }

View File

@ -3,7 +3,7 @@
namespace Webkul\Attribute\Database\Seeders; namespace Webkul\Attribute\Database\Seeders;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use DB; use Illuminate\Support\Facades\DB;
class AttributeOptionTableSeeder extends Seeder class AttributeOptionTableSeeder extends Seeder
{ {
@ -11,6 +11,7 @@ class AttributeOptionTableSeeder extends Seeder
public function run() public function run()
{ {
DB::table('attribute_options')->delete(); DB::table('attribute_options')->delete();
DB::table('attribute_option_translations')->delete();
DB::table('attribute_options')->insert([ DB::table('attribute_options')->insert([
['id' => '1', 'admin_name' => 'Red', 'sort_order' => '1', 'attribute_id' => '23'], ['id' => '1', 'admin_name' => 'Red', 'sort_order' => '1', 'attribute_id' => '23'],

View File

@ -2,9 +2,9 @@
namespace Webkul\Attribute\Database\Seeders; namespace Webkul\Attribute\Database\Seeders;
use Illuminate\Database\Seeder;
use DB;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class AttributeTableSeeder extends Seeder class AttributeTableSeeder extends Seeder
{ {
@ -12,6 +12,7 @@ class AttributeTableSeeder extends Seeder
public function run() public function run()
{ {
DB::table('attributes')->delete(); DB::table('attributes')->delete();
DB::table('attribute_translations')->delete();
$now = Carbon::now(); $now = Carbon::now();
@ -59,9 +60,11 @@ class AttributeTableSeeder extends Seeder
['id' => '23','code' => 'color','admin_name' => 'Color','type' => 'select','validation' => NULL,'position' => '23','is_required' => '0','is_unique' => '0','value_per_locale' => '0','value_per_channel' => '0','is_filterable' => '1','is_configurable' => '1','is_user_defined' => '1','is_visible_on_front' => '0', ['id' => '23','code' => 'color','admin_name' => 'Color','type' => 'select','validation' => NULL,'position' => '23','is_required' => '0','is_unique' => '0','value_per_locale' => '0','value_per_channel' => '0','is_filterable' => '1','is_configurable' => '1','is_user_defined' => '1','is_visible_on_front' => '0',
'use_in_flat' => '1','created_at' => $now,'updated_at' => $now], 'use_in_flat' => '1','created_at' => $now,'updated_at' => $now],
['id' => '24','code' => 'size','admin_name' => 'Size','type' => 'select','validation' => NULL,'position' => '24','is_required' => '0','is_unique' => '0','value_per_locale' => '0','value_per_channel' => '0','is_filterable' => '1','is_configurable' => '1','is_user_defined' => '1','is_visible_on_front' => '0', ['id' => '24','code' => 'size','admin_name' => 'Size','type' => 'select','validation' => NULL,'position' => '24','is_required' => '0','is_unique' => '0','value_per_locale' => '0','value_per_channel' => '0','is_filterable' => '1','is_configurable' => '1','is_user_defined' => '1','is_visible_on_front' => '0',
'use_in_flat' => '1','created_at' => $now,'updated_at' => $now], 'use_in_flat' => '1','created_at' => $now,'updated_at' => $now],
['id' => '25','code' => 'brand','admin_name' => 'Brand','type' => 'select','validation' => NULL,'position' => '25','is_required' => '0','is_unique' => '0','value_per_locale' => '0','value_per_channel' => '0','is_filterable' => '1','is_configurable' => '0','is_user_defined' => '0','is_visible_on_front' => '1', ['id' => '25','code' => 'brand','admin_name' => 'Brand','type' => 'select','validation' => NULL,'position' => '25','is_required' => '0','is_unique' => '0','value_per_locale' => '0','value_per_channel' => '0','is_filterable' => '1','is_configurable' => '0','is_user_defined' => '0','is_visible_on_front' => '1',
'use_in_flat' => '1','created_at' => $now,'updated_at' => $now] 'use_in_flat' => '1','created_at' => $now,'updated_at' => $now],
['id' => '26','code' => 'guest_checkout','admin_name' => 'Guest Checkout','type' => 'boolean','validation' => NULL,'position' => '8','is_required' => '1','is_unique' => '0','value_per_locale' => '0','value_per_channel' => '0','is_filterable' => '0','is_configurable' => '0','is_user_defined' => '0','is_visible_on_front' => '0',
'use_in_flat' => '1','created_at' => $now,'updated_at' => $now],
]); ]);
@ -90,7 +93,8 @@ class AttributeTableSeeder extends Seeder
['id' => '22','locale' => 'en','name' => 'Weight','attribute_id' => '22'], ['id' => '22','locale' => 'en','name' => 'Weight','attribute_id' => '22'],
['id' => '23','locale' => 'en','name' => 'Color','attribute_id' => '23'], ['id' => '23','locale' => 'en','name' => 'Color','attribute_id' => '23'],
['id' => '24','locale' => 'en','name' => 'Size','attribute_id' => '24'], ['id' => '24','locale' => 'en','name' => 'Size','attribute_id' => '24'],
['id' => '25','locale' => 'en','name' => 'Brand','attribute_id' => '25'] ['id' => '25','locale' => 'en','name' => 'Brand','attribute_id' => '25'],
['id' => '26','locale' => 'en','name' => 'Allow Guest Checkout','attribute_id' => '26']
]); ]);
} }
} }

View File

@ -13,9 +13,9 @@ class DatabaseSeeder extends Seeder
*/ */
public function run() public function run()
{ {
$this->call(AttributeTableSeeder::class);
$this->call(AttributeOptionTableSeeder::class);
$this->call(AttributeFamilyTableSeeder::class); $this->call(AttributeFamilyTableSeeder::class);
$this->call(AttributeGroupTableSeeder::class); $this->call(AttributeGroupTableSeeder::class);
$this->call(AttributeTableSeeder::class);
$this->call(AttributeOptionTableSeeder::class);
} }
} }

View File

@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Event;
use Webkul\Attribute\Repositories\AttributeRepository; use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Attribute\Repositories\AttributeGroupRepository; use Webkul\Attribute\Repositories\AttributeGroupRepository;
use Illuminate\Container\Container as App; use Illuminate\Container\Container as App;
use Illuminate\Support\Str;
/** /**
* Attribute Reposotory * Attribute Reposotory
@ -66,7 +67,7 @@ class AttributeFamilyRepository extends Repository
*/ */
public function create(array $data) public function create(array $data)
{ {
Event::fire('catalog.attribute_family.create.before'); Event::dispatch('catalog.attribute_family.create.before');
$attributeGroups = isset($data['attribute_groups']) ? $data['attribute_groups'] : []; $attributeGroups = isset($data['attribute_groups']) ? $data['attribute_groups'] : [];
unset($data['attribute_groups']); unset($data['attribute_groups']);
@ -88,7 +89,7 @@ class AttributeFamilyRepository extends Repository
} }
} }
Event::fire('catalog.attribute_family.create.after', $family); Event::dispatch('catalog.attribute_family.create.after', $family);
return $family; return $family;
} }
@ -103,7 +104,7 @@ class AttributeFamilyRepository extends Repository
{ {
$family = $this->find($id); $family = $this->find($id);
Event::fire('catalog.attribute_family.update.before', $id); Event::dispatch('catalog.attribute_family.update.before', $id);
$family->update($data); $family->update($data);
@ -111,7 +112,7 @@ class AttributeFamilyRepository extends Repository
if (isset($data['attribute_groups'])) { if (isset($data['attribute_groups'])) {
foreach ($data['attribute_groups'] as $attributeGroupId => $attributeGroupInputs) { foreach ($data['attribute_groups'] as $attributeGroupId => $attributeGroupInputs) {
if (str_contains($attributeGroupId, 'group_')) { if (Str::contains($attributeGroupId, 'group_')) {
$attributeGroup = $family->attribute_groups()->create($attributeGroupInputs); $attributeGroup = $family->attribute_groups()->create($attributeGroupInputs);
if (isset($attributeGroupInputs['custom_attributes'])) { if (isset($attributeGroupInputs['custom_attributes'])) {
@ -152,7 +153,7 @@ class AttributeFamilyRepository extends Repository
$this->attributeGroupRepository->delete($attributeGroupId); $this->attributeGroupRepository->delete($attributeGroupId);
} }
Event::fire('catalog.attribute_family.update.after', $family); Event::dispatch('catalog.attribute_family.update.after', $family);
return $family; return $family;
} }
@ -181,10 +182,10 @@ class AttributeFamilyRepository extends Repository
*/ */
public function delete($id) public function delete($id)
{ {
Event::fire('catalog.attribute_family.delete.before', $id); Event::dispatch('catalog.attribute_family.delete.before', $id);
parent::delete($id); parent::delete($id);
Event::fire('catalog.attribute_family.delete.after', $id); Event::dispatch('catalog.attribute_family.delete.after', $id);
} }
} }

View File

@ -6,6 +6,7 @@ use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Webkul\Attribute\Repositories\AttributeOptionRepository; use Webkul\Attribute\Repositories\AttributeOptionRepository;
use Illuminate\Container\Container as App; use Illuminate\Container\Container as App;
use Illuminate\Support\Str;
/** /**
* Attribute Reposotory * Attribute Reposotory
@ -54,7 +55,7 @@ class AttributeRepository extends Repository
*/ */
public function create(array $data) public function create(array $data)
{ {
Event::fire('catalog.attribute.create.before'); Event::dispatch('catalog.attribute.create.before');
$data = $this->validateUserInput($data); $data = $this->validateUserInput($data);
@ -70,7 +71,7 @@ class AttributeRepository extends Repository
} }
} }
Event::fire('catalog.attribute.create.after', $attribute); Event::dispatch('catalog.attribute.create.after', $attribute);
return $attribute; return $attribute;
} }
@ -87,7 +88,7 @@ class AttributeRepository extends Repository
$attribute = $this->find($id); $attribute = $this->find($id);
Event::fire('catalog.attribute.update.before', $id); Event::dispatch('catalog.attribute.update.before', $id);
$attribute->update($data); $attribute->update($data);
@ -96,7 +97,7 @@ class AttributeRepository extends Repository
if (in_array($attribute->type, ['select', 'multiselect', 'checkbox'])) { if (in_array($attribute->type, ['select', 'multiselect', 'checkbox'])) {
if (isset($data['options'])) { if (isset($data['options'])) {
foreach ($data['options'] as $optionId => $optionInputs) { foreach ($data['options'] as $optionId => $optionInputs) {
if (str_contains($optionId, 'option_')) { if (Str::contains($optionId, 'option_')) {
$this->attributeOptionRepository->create(array_merge([ $this->attributeOptionRepository->create(array_merge([
'attribute_id' => $attribute->id, 'attribute_id' => $attribute->id,
], $optionInputs)); ], $optionInputs));
@ -115,7 +116,7 @@ class AttributeRepository extends Repository
$this->attributeOptionRepository->delete($optionId); $this->attributeOptionRepository->delete($optionId);
} }
Event::fire('catalog.attribute.update.after', $attribute); Event::dispatch('catalog.attribute.update.after', $attribute);
return $attribute; return $attribute;
} }
@ -126,11 +127,11 @@ class AttributeRepository extends Repository
*/ */
public function delete($id) public function delete($id)
{ {
Event::fire('catalog.attribute.delete.before', $id); Event::dispatch('catalog.attribute.delete.before', $id);
parent::delete($id); parent::delete($id);
Event::fire('catalog.attribute.delete.after', $id); Event::dispatch('catalog.attribute.delete.after', $id);
} }
/** /**

View File

@ -2,15 +2,16 @@
namespace Webkul\CMS\Database\Seeders; namespace Webkul\CMS\Database\Seeders;
use Illuminate\Database\Seeder;
use DB;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class CMSPagesTableSeeder extends Seeder class CMSPagesTableSeeder extends Seeder
{ {
public function run() public function run()
{ {
DB::table('cms_pages')->delete(); DB::table('cms_pages')->delete();
DB::table('cms_page_translations')->delete();
DB::table('cms_pages')->insert([ DB::table('cms_pages')->insert([
[ [

View File

@ -31,7 +31,7 @@ class CmsRepository extends Repository
*/ */
public function create(array $data) public function create(array $data)
{ {
Event::fire('cms.pages.create.before'); Event::dispatch('cms.pages.create.before');
$model = $this->getModel(); $model = $this->getModel();
@ -46,7 +46,7 @@ class CmsRepository extends Repository
$page->channels()->sync($data['channels']); $page->channels()->sync($data['channels']);
Event::fire('cms.pages.create.after', $page); Event::dispatch('cms.pages.create.after', $page);
return $page; return $page;
} }
@ -61,13 +61,13 @@ class CmsRepository extends Repository
{ {
$page = $this->find($id); $page = $this->find($id);
Event::fire('cms.pages.update.before', $id); Event::dispatch('cms.pages.update.before', $id);
parent::update($data, $id, $attribute); parent::update($data, $id, $attribute);
$page->channels()->sync($data['channels']); $page->channels()->sync($data['channels']);
Event::fire('cms.pages.update.after', $id); Event::dispatch('cms.pages.update.after', $id);
return $page; return $page;
} }

View File

@ -97,11 +97,11 @@ class CartRuleController extends Controller
$data = request()->all(); $data = request()->all();
Event::fire('promotions.cart_rule.create.before'); Event::dispatch('promotions.cart_rule.create.before');
$cartRule = $this->cartRuleRepository->create($data); $cartRule = $this->cartRuleRepository->create($data);
Event::fire('promotions.cart_rule.create.after', $cartRule); Event::dispatch('promotions.cart_rule.create.after', $cartRule);
session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Cart Rule'])); session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Cart Rule']));
@ -145,11 +145,11 @@ class CartRuleController extends Controller
$cartRule = $this->cartRuleRepository->findOrFail($id); $cartRule = $this->cartRuleRepository->findOrFail($id);
Event::fire('promotions.cart_rule.update.before', $cartRule); Event::dispatch('promotions.cart_rule.update.before', $cartRule);
$cartRule = $this->cartRuleRepository->update(request()->all(), $id); $cartRule = $this->cartRuleRepository->update(request()->all(), $id);
Event::fire('promotions.cart_rule.update.after', $cartRule); Event::dispatch('promotions.cart_rule.update.after', $cartRule);
session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Cart Rule'])); session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Cart Rule']));
@ -167,11 +167,11 @@ class CartRuleController extends Controller
$cartRule = $this->cartRuleRepository->findOrFail($id); $cartRule = $this->cartRuleRepository->findOrFail($id);
try { try {
Event::fire('promotions.cart_rule.delete.before', $id); Event::dispatch('promotions.cart_rule.delete.before', $id);
$this->cartRuleRepository->delete($id); $this->cartRuleRepository->delete($id);
Event::fire('promotions.cart_rule.delete.after', $id); Event::dispatch('promotions.cart_rule.delete.after', $id);
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Cart Rule'])); session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Cart Rule']));

View File

@ -94,11 +94,11 @@ class CatalogRuleController extends Controller
$data = request()->all(); $data = request()->all();
Event::fire('promotions.catalog_rule.create.before'); Event::dispatch('promotions.catalog_rule.create.before');
$catalogRule = $this->catalogRuleRepository->create($data); $catalogRule = $this->catalogRuleRepository->create($data);
Event::fire('promotions.catalog_rule.create.after', $catalogRule); Event::dispatch('promotions.catalog_rule.create.after', $catalogRule);
$this->catalogRuleIndexHelper->reindexComplete(); $this->catalogRuleIndexHelper->reindexComplete();
@ -141,11 +141,11 @@ class CatalogRuleController extends Controller
$catalogRule = $this->catalogRuleRepository->findOrFail($id); $catalogRule = $this->catalogRuleRepository->findOrFail($id);
Event::fire('promotions.catalog_rule.update.before', $catalogRule); Event::dispatch('promotions.catalog_rule.update.before', $catalogRule);
$catalogRule = $this->catalogRuleRepository->update(request()->all(), $id); $catalogRule = $this->catalogRuleRepository->update(request()->all(), $id);
Event::fire('promotions.catalog_rule.update.after', $catalogRule); Event::dispatch('promotions.catalog_rule.update.after', $catalogRule);
$this->catalogRuleIndexHelper->reindexComplete(); $this->catalogRuleIndexHelper->reindexComplete();
@ -165,11 +165,11 @@ class CatalogRuleController extends Controller
$catalogRule = $this->catalogRuleRepository->findOrFail($id); $catalogRule = $this->catalogRuleRepository->findOrFail($id);
try { try {
Event::fire('promotions.catalog_rule.delete.before', $id); Event::dispatch('promotions.catalog_rule.delete.before', $id);
$this->catalogRuleRepository->delete($id); $this->catalogRuleRepository->delete($id);
Event::fire('promotions.catalog_rule.delete.after', $id); Event::dispatch('promotions.catalog_rule.delete.after', $id);
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Catalog Rule'])); session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Catalog Rule']));

View File

@ -1,10 +1,9 @@
<?php <?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker; use Faker\Generator as Faker;
use Webkul\Category\Models\Category; use Webkul\Category\Models\Category;
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(Category::class, function (Faker $faker, array $attributes) { $factory->define(Category::class, function (Faker $faker, array $attributes) {
return [ return [

View File

@ -115,15 +115,15 @@ class CategoryController extends Controller
/** /**
* Show the form for editing the specified resource. * Show the form for editing the specified resource.
* *
* @param int $id * @param int $id
* @return \Illuminate\View\View * @return \Illuminate\View\View
*/ */
public function edit($id) public function edit($id)
{ {
$categories = $this->categoryRepository->getCategoryTree($id);
$category = $this->categoryRepository->findOrFail($id); $category = $this->categoryRepository->findOrFail($id);
$categories = $this->categoryRepository->getCategoryTreeWithoutDescendant($id);
$attributes = $this->attributeRepository->findWhere(['is_filterable' => 1]); $attributes = $this->attributeRepository->findWhere(['is_filterable' => 1]);
return view($this->_config['view'], compact('category', 'categories', 'attributes')); return view($this->_config['view'], compact('category', 'categories', 'attributes'));
@ -174,7 +174,7 @@ class CategoryController extends Controller
$this->categoryRepository->delete($id); $this->categoryRepository->delete($id);
Event::fire('catalog.category.delete.after', $id); Event::dispatch('catalog.category.delete.after', $id);
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Category'])); session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Category']));
@ -200,11 +200,11 @@ class CategoryController extends Controller
foreach ($indexes as $key => $value) { foreach ($indexes as $key => $value) {
try { try {
Event::fire('catalog.category.delete.before', $value); Event::dispatch('catalog.category.delete.before', $value);
$this->categoryRepository->delete($value); $this->categoryRepository->delete($value);
Event::fire('catalog.category.delete.after', $value); Event::dispatch('catalog.category.delete.after', $value);
} catch(\Exception $e) { } catch(\Exception $e) {
$suppressFlash = true; $suppressFlash = true;

View File

@ -5,8 +5,10 @@ namespace Webkul\Category\Models;
use Webkul\Core\Eloquent\TranslatableModel; use Webkul\Core\Eloquent\TranslatableModel;
use Kalnoy\Nestedset\NodeTrait; use Kalnoy\Nestedset\NodeTrait;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Webkul\Category\Contracts\Category as CategoryContract; use Webkul\Category\Contracts\Category as CategoryContract;
use Webkul\Attribute\Models\AttributeProxy; use Webkul\Attribute\Models\AttributeProxy;
use Webkul\Category\Repositories\CategoryRepository;
/** /**
* Class Category * Class Category
@ -19,7 +21,7 @@ class Category extends TranslatableModel implements CategoryContract
{ {
use NodeTrait; use NodeTrait;
public $translatedAttributes = ['name', 'description', 'slug', 'meta_title', 'meta_description', 'meta_keywords']; public $translatedAttributes = ['name', 'description', 'slug', 'url_path', 'meta_title', 'meta_description', 'meta_keywords'];
protected $fillable = ['position', 'status', 'display_mode', 'parent_id']; protected $fillable = ['position', 'status', 'display_mode', 'parent_id'];
@ -51,4 +53,63 @@ class Category extends TranslatableModel implements CategoryContract
{ {
return $this->belongsToMany(AttributeProxy::modelClass(), 'category_filterable_attributes')->with('options'); return $this->belongsToMany(AttributeProxy::modelClass(), 'category_filterable_attributes')->with('options');
} }
/**
* Getting the root category of a category
*
* @return Category
*/
public function getRootCategory(): Category
{
return Category::where([
['parent_id', '=', null],
['_lft', '<=', $this->_lft],
['_rgt', '>=', $this->_rgt],
])->first();
}
/**
* Returns all categories within the category's path
*
* @return Category[]
*/
public function getPathCategories(): array
{
$category = $this->findInTree();
$categories = [$category];
while (isset($category->parent)) {
$category = $category->parent;
$categories[] = $category;
}
return array_reverse($categories);
}
/**
* Finds and returns the category within a nested category tree
* will search in root category by default
* is used to minimize the numbers of sql queries for it only uses the already cached tree
*
* @param Category[] $categoryTree
* @return Category
*/
public function findInTree($categoryTree = null): Category
{
if (! $categoryTree) {
$categoryTree = app(CategoryRepository::class)->getVisibleCategoryTree($this->getRootCategory()->id);
}
$category = $categoryTree->first();
if (! $category) {
throw new NotFoundHttpException('category not found in tree');
}
if ($category->id === $this->id) {
return $category;
}
return $this->findInTree($category->children);
}
} }

View File

@ -9,6 +9,7 @@ use Webkul\Core\Eloquent\Repository;
use Webkul\Category\Models\Category; use Webkul\Category\Models\Category;
use Webkul\Category\Models\CategoryTranslation; use Webkul\Category\Models\CategoryTranslation;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\DB;
/** /**
* Category Reposotory * Category Reposotory
@ -34,7 +35,7 @@ class CategoryRepository extends Repository
*/ */
public function create(array $data) public function create(array $data)
{ {
Event::fire('catalog.category.create.before'); Event::dispatch('catalog.category.create.before');
if (isset($data['locale']) && $data['locale'] == 'all') { if (isset($data['locale']) && $data['locale'] == 'all') {
$model = app()->make($this->model()); $model = app()->make($this->model());
@ -57,7 +58,7 @@ class CategoryRepository extends Repository
$category->filterableAttributes()->sync($data['attributes']); $category->filterableAttributes()->sync($data['attributes']);
} }
Event::fire('catalog.category.create.after', $category); Event::dispatch('catalog.category.create.after', $category);
return $category; return $category;
} }
@ -75,6 +76,18 @@ class CategoryRepository extends Repository
: $this->model::orderBy('position', 'ASC')->get()->toTree(); : $this->model::orderBy('position', 'ASC')->get()->toTree();
} }
/**
* Specify category tree
*
* @param integer $id
* @return mixed
*/
public function getCategoryTreeWithoutDescendant($id = null)
{
return $id
? $this->model::orderBy('position', 'ASC')->where('id', '!=', $id)->whereNotDescendantOf($id)->get()->toTree()
: $this->model::orderBy('position', 'ASC')->get()->toTree();
}
/** /**
* Get root categories * Get root categories
@ -116,7 +129,7 @@ class CategoryRepository extends Repository
$exists = CategoryTranslation::where('category_id', '<>', $id) $exists = CategoryTranslation::where('category_id', '<>', $id)
->where('slug', $slug) ->where('slug', $slug)
->limit(1) ->limit(1)
->select(\DB::raw(1)) ->select(DB::raw(1))
->exists(); ->exists();
return $exists ? false : true; return $exists ? false : true;
@ -161,7 +174,7 @@ class CategoryRepository extends Repository
{ {
$category = $this->find($id); $category = $this->find($id);
Event::fire('catalog.category.update.before', $id); Event::dispatch('catalog.category.update.before', $id);
$category->update($data); $category->update($data);
@ -171,7 +184,7 @@ class CategoryRepository extends Repository
$category->filterableAttributes()->sync($data['attributes']); $category->filterableAttributes()->sync($data['attributes']);
} }
Event::fire('catalog.category.update.after', $id); Event::dispatch('catalog.category.update.after', $id);
return $category; return $category;
} }
@ -182,11 +195,11 @@ class CategoryRepository extends Repository
*/ */
public function delete($id) public function delete($id)
{ {
Event::fire('catalog.category.delete.before', $id); Event::dispatch('catalog.category.delete.before', $id);
parent::delete($id); parent::delete($id);
Event::fire('catalog.category.delete.after', $id); Event::dispatch('catalog.category.delete.after', $id);
} }
/** /**

View File

@ -12,6 +12,7 @@ use Webkul\Checkout\Models\CartPayment;
use Webkul\Customer\Repositories\WishlistRepository; use Webkul\Customer\Repositories\WishlistRepository;
use Webkul\Customer\Repositories\CustomerAddressRepository; use Webkul\Customer\Repositories\CustomerAddressRepository;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Arr;
/** /**
* Facades handler for all the methods to be implemented in Cart. * Facades handler for all the methods to be implemented in Cart.
@ -131,7 +132,7 @@ class Cart {
*/ */
public function addProduct($productId, $data) public function addProduct($productId, $data)
{ {
Event::fire('checkout.cart.add.before', $productId); Event::dispatch('checkout.cart.add.before', $productId);
$cart = $this->getCart(); $cart = $this->getCart();
@ -146,6 +147,10 @@ class Cart {
if (is_string($cartProducts)) { if (is_string($cartProducts)) {
$this->collectTotals(); $this->collectTotals();
if (! count($cart->all_items) > 0) {
session()->forget('cart');
}
throw new \Exception($cartProducts); throw new \Exception($cartProducts);
} else { } else {
$parentCartItem = null; $parentCartItem = null;
@ -175,7 +180,7 @@ class Cart {
} }
} }
Event::fire('checkout.cart.add.after', $cart); Event::dispatch('checkout.cart.add.after', $cart);
$this->collectTotals(); $this->collectTotals();
@ -249,7 +254,7 @@ class Cart {
if (! $this->isItemHaveQuantity($item)) if (! $this->isItemHaveQuantity($item))
throw new \Exception(trans('shop::app.checkout.cart.quantity.inventory_warning')); throw new \Exception(trans('shop::app.checkout.cart.quantity.inventory_warning'));
Event::fire('checkout.cart.update.before', $item); Event::dispatch('checkout.cart.update.before', $item);
$this->cartItemRepository->update([ $this->cartItemRepository->update([
'quantity' => $quantity, 'quantity' => $quantity,
@ -259,7 +264,7 @@ class Cart {
'base_total_weight' => $item->weight * $quantity 'base_total_weight' => $item->weight * $quantity
], $itemId); ], $itemId);
Event::fire('checkout.cart.update.after', $item); Event::dispatch('checkout.cart.update.after', $item);
} }
$this->collectTotals(); $this->collectTotals();
@ -297,7 +302,7 @@ class Cart {
*/ */
public function removeItem($itemId) public function removeItem($itemId)
{ {
Event::fire('checkout.cart.delete.before', $itemId); Event::dispatch('checkout.cart.delete.before', $itemId);
if (! $cart = $this->getCart()) if (! $cart = $this->getCart())
return false; return false;
@ -313,32 +318,13 @@ class Cart {
} }
} }
Event::fire('checkout.cart.delete.after', $itemId); Event::dispatch('checkout.cart.delete.after', $itemId);
$this->collectTotals(); $this->collectTotals();
return true; return true;
} }
/**
* Clear cart
* @return bool
*/
public function clear(): bool
{
if (! $cart = $this->getCart()) {
return false;
}
$this->cartRepository->delete($cart->id);
if (session()->has('cart')) {
session()->forget('cart');
}
return true;
}
/** /**
* This function handles when guest has some of cart products and then logs in. * This function handles when guest has some of cart products and then logs in.
* *
@ -638,7 +624,7 @@ class Cart {
if (! $cart = $this->getCart()) if (! $cart = $this->getCart())
return false; return false;
Event::fire('checkout.cart.collect.totals.before', $cart); Event::dispatch('checkout.cart.collect.totals.before', $cart);
$this->calculateItemsTax(); $this->calculateItemsTax();
@ -681,7 +667,7 @@ class Cart {
$cart->save(); $cart->save();
Event::fire('checkout.cart.collect.totals.after', $cart); Event::dispatch('checkout.cart.collect.totals.after', $cart);
} }
/** /**
@ -871,8 +857,8 @@ class Cart {
'applied_cart_rule_ids' => $data['applied_cart_rule_ids'], 'applied_cart_rule_ids' => $data['applied_cart_rule_ids'],
'discount_amount' => $data['discount_amount'], 'discount_amount' => $data['discount_amount'],
'base_discount_amount' => $data['base_discount_amount'], 'base_discount_amount' => $data['base_discount_amount'],
'billing_address' => array_except($data['billing_address'], ['id', 'cart_id']), 'billing_address' => Arr::except($data['billing_address'], ['id', 'cart_id']),
'payment' => array_except($data['payment'], ['id', 'cart_id']), 'payment' => Arr::except($data['payment'], ['id', 'cart_id']),
'channel' => core()->getCurrentChannel(), 'channel' => core()->getCurrentChannel(),
]; ];
@ -883,9 +869,9 @@ class Cart {
'shipping_description' => $data['selected_shipping_rate']['method_description'], 'shipping_description' => $data['selected_shipping_rate']['method_description'],
'shipping_amount' => $data['selected_shipping_rate']['price'], 'shipping_amount' => $data['selected_shipping_rate']['price'],
'base_shipping_amount' => $data['selected_shipping_rate']['base_price'], 'base_shipping_amount' => $data['selected_shipping_rate']['base_price'],
'shipping_address' => Arr::except($data['shipping_address'], ['id', 'cart_id']),
'shipping_discount_amount' => $data['selected_shipping_rate']['discount_amount'], 'shipping_discount_amount' => $data['selected_shipping_rate']['discount_amount'],
'base_shipping_discount_amount' => $data['selected_shipping_rate']['base_discount_amount'], 'base_shipping_discount_amount' => $data['selected_shipping_rate']['base_discount_amount'],
'shipping_address' => array_except($data['shipping_address'], ['id', 'cart_id']),
]); ]);
} }

View File

@ -138,12 +138,27 @@ class Cart extends Model implements CartContract
*/ */
public function hasProductsWithQuantityBox(): bool public function hasProductsWithQuantityBox(): bool
{ {
$result = true;
foreach ($this->items as $item) { foreach ($this->items as $item) {
if ($item->product->getTypeInstance()->showQuantityBox() === true) { if ($item->product->getTypeInstance()->showQuantityBox() === true) {
$result = false; return true;
} }
} }
return $result; return false;
}
/**
* Checks if cart has items that allow guest checkout
*
* @return boolean
*/
public function hasGuestCheckoutItems()
{
foreach ($this->items as $item) {
if ($item->product->getAttribute('guest_checkout') === 0) {
return false;
}
}
return true;
} }
} }

View File

@ -0,0 +1,27 @@
<?php
namespace Webkul\Core\Database\Seeders;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class ConfigTableSeeder extends Seeder
{
public function run()
{
DB::table('core_config')->delete();
$now = Carbon::now();
DB::table('core_config')->insert([
'id' => 1,
'code' => 'catalog.products.guest-checkout.allow-guest-checkout',
'value' => '1',
'channel_code' => null,
'locale_code' => null,
'created_at' => $now,
'updated_at' => $now
]);
}
}

View File

@ -18,5 +18,6 @@ class DatabaseSeeder extends Seeder
$this->call(CountriesTableSeeder::class); $this->call(CountriesTableSeeder::class);
$this->call(StatesTableSeeder::class); $this->call(StatesTableSeeder::class);
$this->call(ChannelTableSeeder::class); $this->call(ChannelTableSeeder::class);
$this->call(ConfigTableSeeder::class);
} }
} }

View File

@ -82,18 +82,28 @@ abstract class Repository extends BaseRepository {
return $this->parserResult($model); return $this->parserResult($model);
} }
/** /**
* @return mixed * Count results of repository
*
* @param array $where
* @param string $columns
*
* @return int
*/ */
public function count() public function count(array $where = [], $columns = '*')
{ {
$this->applyCriteria(); $this->applyCriteria();
$this->applyScope(); $this->applyScope();
$total = $this->model->count(); if ($where) {
$this->resetModel(); $this->applyConditions($where);
}
return $total; $result = $this->model->count($columns);
$this->resetModel();
$this->resetScope();
return $result;
} }
/** /**

View File

@ -0,0 +1,248 @@
<?php
namespace Webkul\Core\Helpers;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
use Codeception\Module\Laravel5;
use Illuminate\Support\Facades\Event;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductInventory;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductDownloadableLink;
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
class Laravel5Helper extends Laravel5
{
public const SIMPLE_PRODUCT = 1;
public const VIRTUAL_PRODUCT = 2;
public const DOWNLOADABLE_PRODUCT = 3;
/**
* Returns field name of given attribute.
*
* @param string $attribute
*
* @return string|null
* @part ORM
*/
public static function getAttributeFieldName(string $attribute): ?string
{
$attributes = [
'product_id' => 'integer_value',
'sku' => 'text_value',
'name' => 'text_value',
'url_key' => 'text_value',
'tax_category_id' => 'integer_value',
'new' => 'boolean_value',
'featured' => 'boolean_value',
'visible_individually' => 'boolean_value',
'status' => 'boolean_value',
'short_description' => 'text_value',
'description' => 'text_value',
'price' => 'float_value',
'cost' => 'float_value',
'special_price' => 'float_value',
'special_price_from' => 'date_value',
'special_price_to' => 'date_value',
'meta_title' => 'text_value',
'meta_keywords' => 'text_value',
'meta_description' => 'text_value',
'width' => 'integer_value',
'height' => 'integer_value',
'depth' => 'integer_value',
'weight' => 'integer_value',
'color' => 'integer_value',
'size' => 'integer_value',
'brand' => 'text_value',
'guest_checkout' => 'boolean_value',
];
if (!array_key_exists($attribute, $attributes)) {
return null;
}
return $attributes[$attribute];
}
/**
* Helper function to generate products for testing
*
* @param int $productType
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Models\Product
*/
public function haveProduct(int $productType, array $configs = [], array $productStates = []): Product
{
$I = $this;
switch ($productType) {
case self::DOWNLOADABLE_PRODUCT:
$product = $I->haveDownloadableProduct($configs, $productStates);
break;
case self::VIRTUAL_PRODUCT:
$product = $I->haveVirtualProduct($configs, $productStates);
break;
case self::SIMPLE_PRODUCT:
default:
$product = $I->haveSimpleProduct($configs, $productStates);
}
if ($product !== null) {
Event::dispatch('catalog.product.create.after', $product);
}
return $product;
}
/**
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Models\Product
*/
private function haveSimpleProduct(array $configs = [], array $productStates = []): Product
{
$I = $this;
if (!in_array('simple', $productStates)) {
$productStates = array_merge($productStates, ['simple']);
}
/** @var Product $product */
$product = $I->createProduct($configs['productAttributes'] ?? [], $productStates);
$I->createAttributeValues($product->id, $configs['attributeValues'] ?? []);
$I->createInventory($product->id, $configs['productInventory'] ?? []);
return $product->refresh();
}
/**
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Models\Product
*/
private function haveVirtualProduct(array $configs = [], array $productStates = []): Product
{
$I = $this;
if (!in_array('simple', $productStates)) {
$productStates = array_merge($productStates, ['virtual']);
}
/** @var Product $product */
$product = $I->createProduct($configs['productAttributes'] ?? [], $productStates);
$I->createAttributeValues($product->id, $configs['attributeValues'] ?? []);
$I->createInventory($product->id, $configs['productInventory'] ?? []);
return $product->refresh();
}
/**
* @param array $configs
* @param array $productStates
*
* @return \Webkul\Product\Models\Product
*/
private function haveDownloadableProduct(array $configs = [], array $productStates = []): Product
{
$I = $this;
if (!in_array('downloadable', $productStates)) {
$productStates = array_merge($productStates, ['downloadable']);
}
/** @var Product $product */
$product = $I->createProduct($configs['productAttributes'] ?? [], $productStates);
$I->createAttributeValues($product->id, $configs['attributeValues'] ?? []);
$I->createDownloadableLink($product->id);
return $product->refresh();
}
/**
* @param array $attributes
* @param array $states
*
* @return \Webkul\Product\Models\Product
*/
private function createProduct(array $attributes = [], array $states = []): Product
{
return factory(Product::class)->states($states)->create($attributes);
}
/**
* @param int $productId
* @param array $inventoryConfig
*/
private function createInventory(int $productId, array $inventoryConfig = []): void
{
$I = $this;
$I->have(ProductInventory::class, array_merge($inventoryConfig, [
'product_id' => $productId,
'inventory_source_id' => 1,
]));
}
/**
* @param int $productId
*/
private function createDownloadableLink(int $productId): void
{
$I = $this;
$link = $I->have(ProductDownloadableLink::class, [
'product_id' => $productId,
]);
$I->have(ProductDownloadableLinkTranslation::class, [
'product_downloadable_link_id' => $link->id,
]);
}
/**
* @param int $productId
* @param array $attributeValues
*/
private function createAttributeValues(int $productId, array $attributeValues = []): void
{
$I = $this;
$productAttributeValues = [
'sku',
'url_key',
'tax_category_id',
'price',
'cost',
'name',
'new',
'visible_individually',
'featured',
'status',
'guest_checkout',
'short_description',
'description',
'meta_title',
'meta_keywords',
'meta_description',
'weight',
];
foreach ($productAttributeValues as $attribute) {
$data = ['product_id' => $productId];
if (array_key_exists($attribute, $attributeValues)) {
$fieldName = self::getAttributeFieldName($attribute);
if (!array_key_exists($fieldName, $data)) {
$data[$fieldName] = $attributeValues[$attribute];
} else {
$data = [$fieldName => $attributeValues[$attribute]];
}
}
$I->have(ProductAttributeValue::class, $data, $attribute);
}
}
}

View File

@ -96,11 +96,11 @@ class ChannelController extends Controller
unset($data['seo']); unset($data['seo']);
Event::fire('core.channel.create.before'); Event::dispatch('core.channel.create.before');
$channel = $this->channelRepository->create($data); $channel = $this->channelRepository->create($data);
Event::fire('core.channel.create.after', $channel); Event::dispatch('core.channel.create.after', $channel);
session()->flash('success', trans('admin::app.settings.channels.create-success')); session()->flash('success', trans('admin::app.settings.channels.create-success'));
@ -153,11 +153,11 @@ class ChannelController extends Controller
$data['home_seo'] = json_encode($data['seo']); $data['home_seo'] = json_encode($data['seo']);
Event::fire('core.channel.update.before', $id); Event::dispatch('core.channel.update.before', $id);
$channel = $this->channelRepository->update($data, $id); $channel = $this->channelRepository->update($data, $id);
Event::fire('core.channel.update.after', $channel); Event::dispatch('core.channel.update.after', $channel);
session()->flash('success', trans('admin::app.settings.channels.update-success')); session()->flash('success', trans('admin::app.settings.channels.update-success'));
@ -178,11 +178,11 @@ class ChannelController extends Controller
session()->flash('error', trans('admin::app.settings.channels.last-delete-error')); session()->flash('error', trans('admin::app.settings.channels.last-delete-error'));
} else { } else {
try { try {
Event::fire('core.channel.delete.before', $id); Event::dispatch('core.channel.delete.before', $id);
$this->channelRepository->delete($id); $this->channelRepository->delete($id);
Event::fire('core.channel.delete.after', $id); Event::dispatch('core.channel.delete.after', $id);
session()->flash('success', trans('admin::app.settings.channels.delete-success')); session()->flash('success', trans('admin::app.settings.channels.delete-success'));

View File

@ -72,11 +72,11 @@ class CurrencyController extends Controller
'name' => 'required' 'name' => 'required'
]); ]);
Event::fire('core.channel.create.before'); Event::dispatch('core.channel.create.before');
$currency = $this->currencyRepository->create(request()->all()); $currency = $this->currencyRepository->create(request()->all());
Event::fire('core.currency.create.after', $currency); Event::dispatch('core.currency.create.after', $currency);
session()->flash('success', trans('admin::app.settings.currencies.create-success')); session()->flash('success', trans('admin::app.settings.currencies.create-success'));
@ -109,11 +109,11 @@ class CurrencyController extends Controller
'name' => 'required' 'name' => 'required'
]); ]);
Event::fire('core.currency.update.before', $id); Event::dispatch('core.currency.update.before', $id);
$currency = $this->currencyRepository->update(request()->all(), $id); $currency = $this->currencyRepository->update(request()->all(), $id);
Event::fire('core.currency.update.after', $currency); Event::dispatch('core.currency.update.after', $currency);
session()->flash('success', trans('admin::app.settings.currencies.update-success')); session()->flash('success', trans('admin::app.settings.currencies.update-success'));
@ -134,11 +134,11 @@ class CurrencyController extends Controller
session()->flash('warning', trans('admin::app.settings.currencies.last-delete-error')); session()->flash('warning', trans('admin::app.settings.currencies.last-delete-error'));
} else { } else {
try { try {
Event::fire('core.currency.delete.before', $id); Event::dispatch('core.currency.delete.before', $id);
$this->currencyRepository->delete($id); $this->currencyRepository->delete($id);
Event::fire('core.currency.delete.after', $id); Event::dispatch('core.currency.delete.after', $id);
session()->flash('success', trans('admin::app.settings.currencies.delete-success')); session()->flash('success', trans('admin::app.settings.currencies.delete-success'));
@ -164,11 +164,11 @@ class CurrencyController extends Controller
foreach ($indexes as $key => $value) { foreach ($indexes as $key => $value) {
try { try {
Event::fire('core.currency.delete.before', $value); Event::dispatch('core.currency.delete.before', $value);
$this->currencyRepository->delete($value); $this->currencyRepository->delete($value);
Event::fire('core.currency.delete.after', $value); Event::dispatch('core.currency.delete.after', $value);
} catch(\Exception $e) { } catch(\Exception $e) {
$suppressFlash = true; $suppressFlash = true;

View File

@ -90,11 +90,11 @@ class ExchangeRateController extends Controller
'rate' => 'required|numeric' 'rate' => 'required|numeric'
]); ]);
Event::fire('core.exchange_rate.create.before'); Event::dispatch('core.exchange_rate.create.before');
$exchangeRate = $this->exchangeRateRepository->create(request()->all()); $exchangeRate = $this->exchangeRateRepository->create(request()->all());
Event::fire('core.exchange_rate.create.after', $exchangeRate); Event::dispatch('core.exchange_rate.create.after', $exchangeRate);
session()->flash('success', trans('admin::app.settings.exchange_rates.create-success')); session()->flash('success', trans('admin::app.settings.exchange_rates.create-success'));
@ -129,11 +129,11 @@ class ExchangeRateController extends Controller
'rate' => 'required|numeric' 'rate' => 'required|numeric'
]); ]);
Event::fire('core.exchange_rate.update.before', $id); Event::dispatch('core.exchange_rate.update.before', $id);
$exchangeRate = $this->exchangeRateRepository->update(request()->all(), $id); $exchangeRate = $this->exchangeRateRepository->update(request()->all(), $id);
Event::fire('core.exchange_rate.update.after', $exchangeRate); Event::dispatch('core.exchange_rate.update.after', $exchangeRate);
session()->flash('success', trans('admin::app.settings.exchange_rates.update-success')); session()->flash('success', trans('admin::app.settings.exchange_rates.update-success'));
@ -190,13 +190,13 @@ class ExchangeRateController extends Controller
session()->flash('error', trans('admin::app.settings.exchange_rates.last-delete-error')); session()->flash('error', trans('admin::app.settings.exchange_rates.last-delete-error'));
} else { } else {
try { try {
Event::fire('core.exchange_rate.delete.before', $id); Event::dispatch('core.exchange_rate.delete.before', $id);
$this->exchangeRateRepository->delete($id); $this->exchangeRateRepository->delete($id);
session()->flash('success', trans('admin::app.settings.exchange_rates.delete-success')); session()->flash('success', trans('admin::app.settings.exchange_rates.delete-success'));
Event::fire('core.exchange_rate.delete.after', $id); Event::dispatch('core.exchange_rate.delete.after', $id);
return response()->json(['message' => true], 200); return response()->json(['message' => true], 200);
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@ -73,11 +73,11 @@ class LocaleController extends Controller
'direction' => 'in:ltr,rtl' 'direction' => 'in:ltr,rtl'
]); ]);
Event::fire('core.locale.create.before'); Event::dispatch('core.locale.create.before');
$locale = $this->localeRepository->create(request()->all()); $locale = $this->localeRepository->create(request()->all());
Event::fire('core.locale.create.after', $locale); Event::dispatch('core.locale.create.after', $locale);
session()->flash('success', trans('admin::app.settings.locales.create-success')); session()->flash('success', trans('admin::app.settings.locales.create-success'));
@ -111,11 +111,11 @@ class LocaleController extends Controller
'direction' => 'in:ltr,rtl' 'direction' => 'in:ltr,rtl'
]); ]);
Event::fire('core.locale.update.before', $id); Event::dispatch('core.locale.update.before', $id);
$locale = $this->localeRepository->update(request()->all(), $id); $locale = $this->localeRepository->update(request()->all(), $id);
Event::fire('core.locale.update.after', $locale); Event::dispatch('core.locale.update.after', $locale);
session()->flash('success', trans('admin::app.settings.locales.update-success')); session()->flash('success', trans('admin::app.settings.locales.update-success'));
@ -136,11 +136,11 @@ class LocaleController extends Controller
session()->flash('error', trans('admin::app.settings.locales.last-delete-error')); session()->flash('error', trans('admin::app.settings.locales.last-delete-error'));
} else { } else {
try { try {
Event::fire('core.locale.delete.before', $id); Event::dispatch('core.locale.delete.before', $id);
$this->localeRepository->delete($id); $this->localeRepository->delete($id);
Event::fire('core.locale.delete.after', $id); Event::dispatch('core.locale.delete.after', $id);
session()->flash('success', trans('admin::app.settings.locales.delete-success')); session()->flash('success', trans('admin::app.settings.locales.delete-success'));

View File

@ -7,6 +7,7 @@ use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Container\Container as App; use Illuminate\Container\Container as App;
use Webkul\Core\Repositories\ChannelRepository; use Webkul\Core\Repositories\ChannelRepository;
use Illuminate\Support\Arr;
/** /**
* Slider Repository * Slider Repository
@ -55,7 +56,7 @@ class SliderRepository extends Repository
*/ */
public function save(array $data) public function save(array $data)
{ {
Event::fire('core.settings.slider.create.before', $id); Event::dispatch('core.settings.slider.create.before', $data);
$channelName = $this->channelRepository->find($data['channel_id'])->name; $channelName = $this->channelRepository->find($data['channel_id'])->name;
@ -65,7 +66,7 @@ class SliderRepository extends Repository
$image = false; $image = false;
if (isset($data['image'])) { if (isset($data['image'])) {
$image = $first = array_first($data['image'], function ($value, $key) { $image = $first = Arr::first($data['image'], function ($value, $key) {
if ($value) if ($value)
return $value; return $value;
else else
@ -87,7 +88,7 @@ class SliderRepository extends Repository
$slider = $this->create($data); $slider = $this->create($data);
Event::fire('core.settings.slider.create.after', $slider); Event::dispatch('core.settings.slider.create.after', $slider);
return true; return true;
} }
@ -98,7 +99,7 @@ class SliderRepository extends Repository
*/ */
public function updateItem(array $data, $id) public function updateItem(array $data, $id)
{ {
Event::fire('core.settings.slider.update.before', $id); Event::dispatch('core.settings.slider.update.before', $id);
$channelName = $this->channelRepository->find($data['channel_id'])->name; $channelName = $this->channelRepository->find($data['channel_id'])->name;
@ -107,7 +108,7 @@ class SliderRepository extends Repository
$uploaded = $image = false; $uploaded = $image = false;
if (isset($data['image'])) { if (isset($data['image'])) {
$image = $first = array_first($data['image'], function ($value, $key) { $image = $first = Arr::first($data['image'], function ($value, $key) {
return $value ? $value : false; return $value ? $value : false;
}); });
} }
@ -130,7 +131,7 @@ class SliderRepository extends Repository
$slider = $this->update($data, $id); $slider = $this->update($data, $id);
Event::fire('core.settings.slider.update.after', $slider); Event::dispatch('core.settings.slider.update.after', $slider);
return true; return true;
} }

View File

@ -26,7 +26,8 @@ class AddressController extends Controller
/** /**
* CustomerAddressRepository object * CustomerAddressRepository object
* *
* @param \Webkul\Customer\Repositories\CustomerAddressRepository $customerAddressRepository * @param \Webkul\Customer\Repositories\CustomerAddressRepository $customerAddressRepository
*
* @var Object * @var Object
*/ */
protected $customerAddressRepository; protected $customerAddressRepository;
@ -59,7 +60,9 @@ class AddressController extends Controller
*/ */
public function create() public function create()
{ {
return view($this->_config['view']); return view($this->_config['view'], [
'defaultCountry' => config('app.default_country'),
]);
} }
/** /**
@ -75,11 +78,11 @@ class AddressController extends Controller
$this->validate(request(), [ $this->validate(request(), [
'address1' => 'string|required', 'address1' => 'string|required',
'country' => 'string|required', 'country' => 'string|required',
'state' => 'string|required', 'state' => 'string|required',
'city' => 'string|required', 'city' => 'string|required',
'postcode' => 'required', 'postcode' => 'required',
'phone' => 'required' 'phone' => 'required',
]); ]);
$cust_id['customer_id'] = $this->customer->id; $cust_id['customer_id'] = $this->customer->id;
@ -108,14 +111,18 @@ class AddressController extends Controller
public function edit($id) public function edit($id)
{ {
$address = $this->customerAddressRepository->findOneWhere([ $address = $this->customerAddressRepository->findOneWhere([
'id' => $id, 'id' => $id,
'customer_id' => auth()->guard('customer')->user()->id 'customer_id' => auth()->guard('customer')->user()->id,
]); ]);
if (! $address) if (! $address) {
abort(404); abort(404);
}
return view($this->_config['view'], compact('address')); return view($this->_config['view'], array_merge(
compact('address'),
['defaultCountry' => config('app.default_country')]
));
} }
/** /**
@ -130,18 +137,18 @@ class AddressController extends Controller
$this->validate(request(), [ $this->validate(request(), [
'address1' => 'string|required', 'address1' => 'string|required',
'country' => 'string|required', 'country' => 'string|required',
'state' => 'string|required', 'state' => 'string|required',
'city' => 'string|required', 'city' => 'string|required',
'postcode' => 'required', 'postcode' => 'required',
'phone' => 'required' 'phone' => 'required',
]); ]);
$data = collect(request()->input())->except('_token')->toArray(); $data = collect(request()->input())->except('_token')->toArray();
$addresses = $this->customer->addresses; $addresses = $this->customer->addresses;
foreach($addresses as $address) { foreach ($addresses as $address) {
if ($id == $address->id) { if ($id == $address->id) {
session()->flash('success', trans('shop::app.customer.account.address.edit.success')); session()->flash('success', trans('shop::app.customer.account.address.edit.success'));
@ -157,7 +164,8 @@ class AddressController extends Controller
} }
/** /**
* To change the default address or make the default address, by default when first address is created will be the default address * To change the default address or make the default address, by default when first address is
* created will be the default address
* *
* @return Response * @return Response
*/ */
@ -185,8 +193,8 @@ class AddressController extends Controller
public function destroy($id) public function destroy($id)
{ {
$address = $this->customerAddressRepository->findOneWhere([ $address = $this->customerAddressRepository->findOneWhere([
'id' => $id, 'id' => $id,
'customer_id' => auth()->guard('customer')->user()->id 'customer_id' => auth()->guard('customer')->user()->id,
]); ]);
if (! $address) if (! $address)

View File

@ -98,11 +98,11 @@ class RegistrationController extends Controller
$verificationData['token'] = md5(uniqid(rand(), true)); $verificationData['token'] = md5(uniqid(rand(), true));
$data['token'] = $verificationData['token']; $data['token'] = $verificationData['token'];
Event::fire('customer.registration.before'); Event::dispatch('customer.registration.before');
$customer = $this->customerRepository->create($data); $customer = $this->customerRepository->create($data);
Event::fire('customer.registration.after', $customer); Event::dispatch('customer.registration.after', $customer);
if ($customer) { if ($customer) {
if (core()->getConfigData('customer.settings.email.verification')) { if (core()->getConfigData('customer.settings.email.verification')) {

View File

@ -57,27 +57,33 @@ class ResetPasswordController extends Controller
*/ */
public function store() public function store()
{ {
$this->validate(request(), [ try {
'token' => 'required', $this->validate(request(), [
'email' => 'required|email', 'token' => 'required',
'password' => 'required|confirmed|min:6', 'email' => 'required|email',
]); 'password' => 'required|confirmed|min:6',
$response = $this->broker()->reset(
request(['email', 'password', 'password_confirmation', 'token']), function ($customer, $password) {
$this->resetPassword($customer, $password);
}
);
if ($response == Password::PASSWORD_RESET) {
return redirect()->route($this->_config['redirect']);
}
return back()
->withInput(request(['email']))
->withErrors([
'email' => trans($response)
]); ]);
$response = $this->broker()->reset(
request(['email', 'password', 'password_confirmation', 'token']), function ($customer, $password) {
$this->resetPassword($customer, $password);
}
);
if ($response == Password::PASSWORD_RESET) {
return redirect()->route($this->_config['redirect']);
}
return back()
->withInput(request(['email']))
->withErrors([
'email' => trans($response)
]);
} catch(\Exception $e) {
session()->flash('error', trans($e->getMessage()));
return redirect()->back();
}
} }
/** /**

View File

@ -85,7 +85,7 @@ class SessionController extends Controller
} }
//Event passed to prepare cart after login //Event passed to prepare cart after login
Event::fire('customer.after.login', request('email')); Event::dispatch('customer.after.login', request('email'));
return redirect()->intended(route($this->_config['redirect'])); return redirect()->intended(route($this->_config['redirect']));
} }
@ -100,7 +100,7 @@ class SessionController extends Controller
{ {
auth()->guard('customer')->logout(); auth()->guard('customer')->logout();
Event::fire('customer.after.logout', $id); Event::dispatch('customer.after.logout', $id);
return redirect()->route($this->_config['redirect']); return redirect()->route($this->_config['redirect']);
} }

View File

@ -110,7 +110,11 @@ class WishlistController extends Controller
return redirect()->back(); return redirect()->back();
} }
} else { } else {
session()->flash('warning', trans('customer::app.wishlist.already')); $this->wishlistRepository->findOneWhere([
'product_id' => $data['product_id']
])->delete();
session()->flash('success', trans('customer::app.wishlist.removed'));
return redirect()->back(); return redirect()->back();
} }
@ -170,7 +174,7 @@ class WishlistController extends Controller
} catch (\Exception $e) { } catch (\Exception $e) {
session()->flash('warning', $e->getMessage()); session()->flash('warning', $e->getMessage());
return redirect()->route('shop.productOrCategory.index', ['slug' => $wishlistItem->product->url_key]); return redirect()->route('shop.productOrCategory.index', $wishlistItem->product->url_key);
} }
} }

View File

@ -31,7 +31,6 @@ class RegistrationEmail extends Mailable
public function build() public function build()
{ {
return $this->to($this->data['email']) return $this->to($this->data['email'])
->from(config('mail.from'))
->subject(trans('shop::app.mail.customer.registration.customer-registration')) ->subject(trans('shop::app.mail.customer.registration.customer-registration'))
->view('shop::emails.customer.registration')->with('data', $this->data); ->view('shop::emails.customer.registration')->with('data', $this->data);
} }

View File

@ -31,7 +31,6 @@ class VerificationEmail extends Mailable
public function build() public function build()
{ {
return $this->to($this->verificationData['email']) return $this->to($this->verificationData['email'])
->from(config('mail.from'))
->subject(trans('shop::app.mail.customer.verification.subject')) ->subject(trans('shop::app.mail.customer.verification.subject'))
->view('shop::emails.customer.verification-email')->with('data', ['email' => $this->verificationData['email'], 'token' => $this->verificationData['token']]); ->view('shop::emails.customer.verification-email')->with('data', ['email' => $this->verificationData['email'], 'token' => $this->verificationData['token']]);
} }

View File

@ -21,7 +21,6 @@ class CustomerResetPassword extends ResetPassword
} }
return (new MailMessage) return (new MailMessage)
->from(config('mail.from'))
->subject(__('shop::app.mail.forget-password.subject') ) ->subject(__('shop::app.mail.forget-password.subject') )
->view('shop::emails.customer.forget-password', [ ->view('shop::emails.customer.forget-password', [
'user_name' => $notifiable->name, 'user_name' => $notifiable->name,

View File

@ -31,7 +31,7 @@ class CustomerAddressRepository extends Repository
*/ */
public function create(array $data) public function create(array $data)
{ {
Event::fire('customer.addresses.create.before'); Event::dispatch('customer.addresses.create.before');
if ( isset($data['default_address']) ) { if ( isset($data['default_address']) ) {
$data['default_address'] = 1; $data['default_address'] = 1;
@ -47,7 +47,7 @@ class CustomerAddressRepository extends Repository
$address = $this->model->create($data); $address = $this->model->create($data);
Event::fire('customer.addresses.create.after', $address); Event::dispatch('customer.addresses.create.after', $address);
return $address; return $address;
} }
@ -61,7 +61,7 @@ class CustomerAddressRepository extends Repository
{ {
$address = $this->find($id); $address = $this->find($id);
Event::fire('customer.addresses.update.before', $id); Event::dispatch('customer.addresses.update.before', $id);
if (isset($data['default_address']) ) { if (isset($data['default_address']) ) {
$data['default_address'] = 1; $data['default_address'] = 1;
@ -80,7 +80,7 @@ class CustomerAddressRepository extends Repository
$address->update($data); $address->update($data);
} }
Event::fire('customer.addresses.update.after', $id); Event::dispatch('customer.addresses.update.after', $id);
return $address; return $address;
} }

View File

@ -0,0 +1,27 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
$factory->define(InventorySource::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
$code = $faker->unique()->word;
return [
'code' => $faker->unique()->word,
'name' => $code,
'description' => $faker->sentence,
'contact_name' => $faker->name,
'contact_email' => $faker->safeEmail,
'contact_number' => $faker->phoneNumber,
'country' => $faker->countryCode,
'state' => $faker->state,
'city' => $faker->city,
'street' => $faker->streetAddress,
'postcode' => $faker->postcode,
'priority' => 0,
'status' => 1,
'created_at' => $now,
'updated_at' => $now,
];
});

View File

@ -84,11 +84,11 @@ class InventorySourceController extends Controller
$data['status'] = !isset($data['status']) ? 0 : 1; $data['status'] = !isset($data['status']) ? 0 : 1;
Event::fire('inventory.inventory_source.create.before'); Event::dispatch('inventory.inventory_source.create.before');
$inventorySource = $this->inventorySourceRepository->create($data); $inventorySource = $this->inventorySourceRepository->create($data);
Event::fire('inventory.inventory_source.create.after', $inventorySource); Event::dispatch('inventory.inventory_source.create.after', $inventorySource);
session()->flash('success', trans('admin::app.settings.inventory_sources.create-success')); session()->flash('success', trans('admin::app.settings.inventory_sources.create-success'));
@ -133,11 +133,11 @@ class InventorySourceController extends Controller
$data['status'] = !isset($data['status']) ? 0 : 1; $data['status'] = !isset($data['status']) ? 0 : 1;
Event::fire('inventory.inventory_source.update.before', $id); Event::dispatch('inventory.inventory_source.update.before', $id);
$inventorySource = $this->inventorySourceRepository->update($data, $id); $inventorySource = $this->inventorySourceRepository->update($data, $id);
Event::fire('inventory.inventory_source.update.after', $inventorySource); Event::dispatch('inventory.inventory_source.update.after', $inventorySource);
session()->flash('success', trans('admin::app.settings.inventory_sources.update-success')); session()->flash('success', trans('admin::app.settings.inventory_sources.update-success'));
@ -158,11 +158,11 @@ class InventorySourceController extends Controller
session()->flash('error', trans('admin::app.settings.inventory_sources.last-delete-error')); session()->flash('error', trans('admin::app.settings.inventory_sources.last-delete-error'));
} else { } else {
try { try {
Event::fire('inventory.inventory_source.delete.before', $id); Event::dispatch('inventory.inventory_source.delete.before', $id);
$this->inventorySourceRepository->delete($id); $this->inventorySourceRepository->delete($id);
Event::fire('inventory.inventory_source.delete.after', $id); Event::dispatch('inventory.inventory_source.delete.after', $id);
session()->flash('success', trans('admin::app.settings.inventory_sources.delete-success')); session()->flash('success', trans('admin::app.settings.inventory_sources.delete-success'));

View File

@ -0,0 +1,261 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Attribute\Models\AttributeOption;
$factory->defineAs(ProductAttributeValue::class, 'sku', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'text_value' => $faker->uuid,
'attribute_id' => 1,
];
});
$factory->defineAs(ProductAttributeValue::class, 'name', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'locale' => 'en', //$faker->languageCode,
'channel' => 'default',
'text_value' => $faker->words(2, true),
'attribute_id' => 2,
];
});
$factory->defineAs(ProductAttributeValue::class, 'url_key', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'text_value' => $faker->unique()->slug,
'attribute_id' => 3,
];
});
$factory->defineAs(ProductAttributeValue::class, 'tax_category_id', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'channel' => 'default',
'integer_value' => null, // ToDo
'attribute_id' => 4,
];
});
$factory->defineAs(ProductAttributeValue::class, 'new', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'boolean_value' => 1,
'attribute_id' => 5,
];
});
$factory->defineAs(ProductAttributeValue::class, 'featured', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'boolean_value' => 1,
'attribute_id' => 6,
];
});
$factory->defineAs(ProductAttributeValue::class, 'visible_individually', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'boolean_value' => 1,
'attribute_id' => 7,
];
});
$factory->defineAs(ProductAttributeValue::class, 'status', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'boolean_value' => 1,
'attribute_id' => 8,
];
});
$factory->defineAs(ProductAttributeValue::class, 'short_description', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'locale' => 'en', //$faker->languageCode,
'channel' => 'default',
'text_value' => $faker->sentence,
'attribute_id' => 9,
];
});
$factory->defineAs(ProductAttributeValue::class, 'description', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'locale' => 'en', //$faker->languageCode,
'channel' => 'default',
'text_value' => $faker->sentences(3, true),
'attribute_id' => 10,
];
});
$factory->defineAs(ProductAttributeValue::class, 'price', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'float_value' => $faker->randomFloat(4, 0, 1000),
'attribute_id' => 11,
];
});
$factory->defineAs(ProductAttributeValue::class, 'cost', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'channel' => 'default',
'float_value' => $faker->randomFloat(4, 0, 10),
'attribute_id' => 12,
];
});
$factory->defineAs(ProductAttributeValue::class, 'special_price', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'float_value' => $faker->randomFloat(4, 0, 100),
'attribute_id' => 13,
];
});
$factory->defineAs(ProductAttributeValue::class, 'special_price_from', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'channel' => 'default',
'date_value' => $faker->dateTimeBetween('-5 days', 'now', 'Europe/Berlin'),
'attribute_id' => 14,
];
});
$factory->defineAs(ProductAttributeValue::class, 'special_price_to', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'channel' => 'default',
'date_value' => $faker->dateTimeBetween('now', '+ 5 days', 'Europe/Berlin'),
'attribute_id' => 15,
];
});
$factory->defineAs(ProductAttributeValue::class, 'meta_title', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'locale' => 'en', //$faker->languageCode,
'channel' => 'default',
'text_value' => $faker->words(2, true),
'attribute_id' => 16,
];
});
$factory->defineAs(ProductAttributeValue::class, 'meta_keywords', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'locale' => 'en', //$faker->languageCode,
'channel' => 'default',
'text_value' => $faker->words(5, true),
'attribute_id' => 17,
];
});
$factory->defineAs(ProductAttributeValue::class, 'meta_description', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'locale' => 'en', //$faker->languageCode,
'channel' => 'default',
'text_value' => $faker->sentence,
'attribute_id' => 18,
];
});
$factory->defineAs(ProductAttributeValue::class, 'width', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'integer_value' => $faker->numberBetween(1, 50),
'attribute_id' => 19,
];
});
$factory->defineAs(ProductAttributeValue::class, 'height', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'integer_value' => $faker->numberBetween(1, 50),
'attribute_id' => 20,
];
});
$factory->defineAs(ProductAttributeValue::class, 'depth', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'integer_value' => $faker->numberBetween(1, 50),
'attribute_id' => 21,
];
});
$factory->defineAs(ProductAttributeValue::class, 'weight', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'integer_value' => $faker->numberBetween(1, 50),
'attribute_id' => 22,
];
});
$factory->defineAs(ProductAttributeValue::class, 'color', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'integer_value' => $faker->numberBetween(1, 5),
'attribute_id' => 23,
];
});
$factory->defineAs(ProductAttributeValue::class, 'size', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'integer_value' => $faker->numberBetween(1, 5),
'attribute_id' => 24,
];
});
$factory->defineAs(ProductAttributeValue::class, 'brand', function (Faker $faker) {
return [
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'attribute_id' => 25,
'integer_value' => function () {
return factory(AttributeOption::class)->create()->id;
},
];
});
$factory->defineAs(ProductAttributeValue::class, 'guest_checkout', function ( Faker $faker) {
return [
'product_id' => function() {
return factory(Product::class)->create()->id;
},
'boolean_value' => 1,
'attribute_id' => 26,
];
});

View File

@ -0,0 +1,24 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductDownloadableLink;
$factory->define(ProductDownloadableLink::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
$filename = 'ProductImageExampleForUpload.jpg';
$filepath = '/tests/_data/';
return [
'url' => '',
'file' => $filepath . $filename,
'file_name' => $filename,
'type' => 'file',
'price' => 0.0000,
'downloads' => $faker->randomNumber(1),
'product_id' => function () {
return factory(Product::class)->create()->id;
},
];
});

View File

@ -0,0 +1,17 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Product\Models\ProductDownloadableLink;
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
$factory->define(ProductDownloadableLinkTranslation::class, function (Faker $faker) {
return [
'locale' => 'en',
'title' => $faker->word,
'product_downloadable_link_id' => function () {
return factory(ProductDownloadableLink::class)->create()->id;
},
];
});

View File

@ -0,0 +1,28 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Product\Models\Product;
$factory->define(Product::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
return [
'sku' => $faker->uuid,
'created_at' => $now,
'updated_at' => $now,
'attribute_family_id' => 1,
];
});
$factory->state(Product::class, 'simple', [
'type' => 'simple',
]);
$factory->state(Product::class, 'virtual', [
'type' => 'virtual',
]);
$factory->state(Product::class, 'downloadable', [
'type' => 'downloadable',
]);

View File

@ -0,0 +1,20 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductInventory;
$factory->define(ProductInventory::class, function (Faker $faker) {
return [
'qty' => $faker->numberBetween(1, 20),
'product_id' => function () {
return factory(Product::class)->create()->id;
},
'inventory_source_id' => function () {
return factory(InventorySource::class)->create()->id;
},
];
});

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Helpers;
use Webkul\Product\Repositories\ProductRepository as Product; use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Attribute\Repositories\AttributeFamilyRepository as AttributeFamily; use Webkul\Attribute\Repositories\AttributeFamilyRepository as AttributeFamily;
use Illuminate\Support\Str;
class GenerateProduct class GenerateProduct
{ {
@ -41,7 +42,7 @@ class GenerateProduct
'code' => 'default' 'code' => 'default'
]); ]);
$sku = str_random(10); $sku = Str::random(10);
$data['sku'] = strtolower($sku); $data['sku'] = strtolower($sku);
$data['attribute_family_id'] = $attributeFamily->first()->id; $data['attribute_family_id'] = $attributeFamily->first()->id;
$data['type'] = 'simple'; $data['type'] = 'simple';
@ -51,7 +52,6 @@ class GenerateProduct
unset($data); unset($data);
$faker = \Faker\Factory::create(); $faker = \Faker\Factory::create();
$date = date('Y-m-d'); $date = date('Y-m-d');
$date = \Carbon\Carbon::parse($date); $date = \Carbon\Carbon::parse($date);
$specialFrom = $date->toDateString(); $specialFrom = $date->toDateString();

View File

@ -310,7 +310,7 @@ class ProductController extends Controller
*/ */
public function sync() public function sync()
{ {
Event::fire('products.datagrid.sync', true); Event::dispatch('products.datagrid.sync', true);
return redirect()->route('admin.catalog.products.index'); return redirect()->route('admin.catalog.products.index');
} }

View File

@ -73,11 +73,11 @@ class ReviewController extends Controller
*/ */
public function update($id) public function update($id)
{ {
Event::fire('customer.review.update.before', $id); Event::dispatch('customer.review.update.before', $id);
$this->productReviewRepository->update(request()->all(), $id); $this->productReviewRepository->update(request()->all(), $id);
Event::fire('customer.review.update.after', $id); Event::dispatch('customer.review.update.after', $id);
session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Review'])); session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Review']));
@ -95,11 +95,11 @@ class ReviewController extends Controller
$productReview = $this->productReviewRepository->findOrFail($id); $productReview = $this->productReviewRepository->findOrFail($id);
try { try {
Event::fire('customer.review.delete.before', $id); Event::dispatch('customer.review.delete.before', $id);
$this->productReviewRepository->delete($id); $this->productReviewRepository->delete($id);
Event::fire('customer.review.delete.after', $id); Event::dispatch('customer.review.delete.after', $id);
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Review'])); session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Review']));
@ -127,11 +127,11 @@ class ReviewController extends Controller
foreach ($indexes as $key => $value) { foreach ($indexes as $key => $value) {
try { try {
Event::fire('customer.review.delete.before', $value); Event::dispatch('customer.review.delete.before', $value);
$this->productReviewRepository->delete($value); $this->productReviewRepository->delete($value);
Event::fire('customer.review.delete.after', $value); Event::dispatch('customer.review.delete.after', $value);
} catch(\Exception $e) { } catch(\Exception $e) {
$suppressFlash = true; $suppressFlash = true;
@ -173,11 +173,11 @@ class ReviewController extends Controller
try { try {
if ($data['massaction-type'] == 'update') { if ($data['massaction-type'] == 'update') {
if ($data['update-options'] == 1) { if ($data['update-options'] == 1) {
Event::fire('customer.review.update.before', $value); Event::dispatch('customer.review.update.before', $value);
$review->update(['status' => 'approved']); $review->update(['status' => 'approved']);
Event::fire('customer.review.update.after', $review); Event::dispatch('customer.review.update.after', $review);
} else if ($data['update-options'] == 0) { } else if ($data['update-options'] == 0) {
$review->update(['status' => 'pending']); $review->update(['status' => 'pending']);
} else if ($data['update-options'] == 2) { } else if ($data['update-options'] == 2) {

View File

@ -2,6 +2,7 @@
namespace Webkul\Product\Providers; namespace Webkul\Product\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Webkul\Product\Models\ProductProxy; use Webkul\Product\Models\ProductProxy;
use Webkul\Product\Observers\ProductObserver; use Webkul\Product\Observers\ProductObserver;
@ -32,14 +33,21 @@ class ProductServiceProvider extends ServiceProvider
* *
* @return void * @return void
*/ */
public function register() public function register(): void
{ {
$this->registerConfig(); $this->registerConfig();
$this->registerCommands(); $this->registerCommands();
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
} }
public function registerConfig() { /**
* Register Configuration
*
* @return void
*/
public function registerConfig(): void {
$this->mergeConfigFrom( $this->mergeConfigFrom(
dirname(__DIR__) . '/Config/product_types.php', 'product_types' dirname(__DIR__) . '/Config/product_types.php', 'product_types'
); );
@ -47,10 +55,24 @@ class ProductServiceProvider extends ServiceProvider
/** /**
* Register the console commands of this package * Register the console commands of this package
*
* @return void
*/ */
protected function registerCommands() protected function registerCommands(): void
{ {
if ($this->app->runningInConsole()) if ($this->app->runningInConsole()) {
$this->commands([PriceUpdate::class,]); $this->commands([PriceUpdate::class,]);
}
}
/**
* Register factories.
*
* @param string $path
* @return void
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
} }
} }

View File

@ -3,6 +3,7 @@
namespace Webkul\Product\Repositories; namespace Webkul\Product\Repositories;
use Webkul\Core\Eloquent\Repository; use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Str;
/** /**
* ProductBundleOptionProduct Repository * ProductBundleOptionProduct Repository
@ -30,7 +31,7 @@ class ProductBundleOptionProductRepository extends Repository
$this->setIsDefaultFlag($data); $this->setIsDefaultFlag($data);
foreach ($data['products'] as $bundleOptionProductId => $bundleOptionProductInputs) { foreach ($data['products'] as $bundleOptionProductId => $bundleOptionProductInputs) {
if (str_contains($bundleOptionProductId, 'product_')) { if (Str::contains($bundleOptionProductId, 'product_')) {
$this->create(array_merge([ $this->create(array_merge([
'product_bundle_option_id' => $productBundleOption->id, 'product_bundle_option_id' => $productBundleOption->id,
], $bundleOptionProductInputs)); ], $bundleOptionProductInputs));

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Repositories;
use Illuminate\Container\Container as App; use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository; use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Str;
/** /**
* ProductBundleOption Repository * ProductBundleOption Repository
@ -52,7 +53,7 @@ class ProductBundleOptionRepository extends Repository
if (isset($data['bundle_options'])) { if (isset($data['bundle_options'])) {
foreach ($data['bundle_options'] as $bundleOptionId => $bundleOptionInputs) { foreach ($data['bundle_options'] as $bundleOptionId => $bundleOptionInputs) {
if (str_contains($bundleOptionId, 'option_')) { if (Str::contains($bundleOptionId, 'option_')) {
$productBundleOption = $this->create(array_merge([ $productBundleOption = $this->create(array_merge([
'product_id' => $product->id, 'product_id' => $product->id,
], $bundleOptionInputs)); ], $bundleOptionInputs));

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Repositories;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Webkul\Core\Eloquent\Repository; use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Str;
/** /**
* Product Downloadable Link Reposotory * Product Downloadable Link Reposotory
@ -54,7 +55,7 @@ class ProductDownloadableLinkRepository extends Repository
if (isset($data['downloadable_links'])) { if (isset($data['downloadable_links'])) {
foreach ($data['downloadable_links'] as $linkId => $data) { foreach ($data['downloadable_links'] as $linkId => $data) {
if (str_contains($linkId, 'link_')) { if (Str::contains($linkId, 'link_')) {
$this->create(array_merge([ $this->create(array_merge([
'product_id' => $product->id, 'product_id' => $product->id,
], $data)); ], $data));

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Repositories;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Webkul\Core\Eloquent\Repository; use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Str;
/** /**
* Product Downloadable Sample Reposotory * Product Downloadable Sample Reposotory
@ -52,7 +53,7 @@ class ProductDownloadableSampleRepository extends Repository
if (isset($data['downloadable_samples'])) { if (isset($data['downloadable_samples'])) {
foreach ($data['downloadable_samples'] as $sampleId => $data) { foreach ($data['downloadable_samples'] as $sampleId => $data) {
if (str_contains($sampleId, 'sample_')) { if (Str::contains($sampleId, 'sample_')) {
$this->create(array_merge([ $this->create(array_merge([
'product_id' => $product->id, 'product_id' => $product->id,
], $data)); ], $data));

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Repositories;
use Webkul\Core\Eloquent\Repository; use Webkul\Core\Eloquent\Repository;
use Webkul\Product\Repositories\ProductRepository; use Webkul\Product\Repositories\ProductRepository;
use Illuminate\Support\Str;
/** /**
* Product Grouped Product Repository * Product Grouped Product Repository
@ -29,7 +30,7 @@ class ProductGroupedProductRepository extends Repository
if (isset($data['links'])) { if (isset($data['links'])) {
foreach ($data['links'] as $linkId => $linkInputs) { foreach ($data['links'] as $linkId => $linkInputs) {
if (str_contains($linkId, 'link_')) { if (Str::contains($linkId, 'link_')) {
$this->create(array_merge([ $this->create(array_merge([
'product_id' => $product->id, 'product_id' => $product->id,
], $linkInputs)); ], $linkInputs));

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Repositories;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Webkul\Core\Eloquent\Repository; use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Str;
/** /**
* Product Image Reposotory * Product Image Reposotory
@ -37,7 +38,7 @@ class ProductImageRepository extends Repository
$file = 'images.' . $imageId; $file = 'images.' . $imageId;
$dir = 'product/' . $product->id; $dir = 'product/' . $product->id;
if (str_contains($imageId, 'image_')) { if (Str::contains($imageId, 'image_')) {
if (request()->hasFile($file)) { if (request()->hasFile($file)) {
$this->create([ $this->create([
'path' => request()->file($file)->store($dir), 'path' => request()->file($file)->store($dir),

View File

@ -58,13 +58,13 @@ class ProductRepository extends Repository
*/ */
public function create(array $data) public function create(array $data)
{ {
Event::fire('catalog.product.create.before'); Event::dispatch('catalog.product.create.before');
$typeInstance = app(config('product_types.' . $data['type'] . '.class')); $typeInstance = app(config('product_types.' . $data['type'] . '.class'));
$product = $typeInstance->create($data); $product = $typeInstance->create($data);
Event::fire('catalog.product.create.after', $product); Event::dispatch('catalog.product.create.after', $product);
return $product; return $product;
} }
@ -77,7 +77,7 @@ class ProductRepository extends Repository
*/ */
public function update(array $data, $id, $attribute = "id") public function update(array $data, $id, $attribute = "id")
{ {
Event::fire('catalog.product.update.before', $id); Event::dispatch('catalog.product.update.before', $id);
$product = $this->find($id); $product = $this->find($id);
@ -86,7 +86,7 @@ class ProductRepository extends Repository
if (isset($data['channels'])) if (isset($data['channels']))
$product['channels'] = $data['channels']; $product['channels'] = $data['channels'];
Event::fire('catalog.product.update.after', $product); Event::dispatch('catalog.product.update.after', $product);
return $product; return $product;
} }
@ -97,11 +97,11 @@ class ProductRepository extends Repository
*/ */
public function delete($id) public function delete($id)
{ {
Event::fire('catalog.product.delete.before', $id); Event::dispatch('catalog.product.delete.before', $id);
parent::delete($id); parent::delete($id);
Event::fire('catalog.product.delete.after', $id); Event::dispatch('catalog.product.delete.after', $id);
} }
/** /**

View File

@ -181,7 +181,7 @@ class Bundle extends AbstractType
} }
if (! $haveRequiredOptions) if (! $haveRequiredOptions)
$minPrice = min($minPrices); $minPrice = count($minPrices) ? min($minPrices) : 0;
return $minPrice; return $minPrice;
} }
@ -405,7 +405,9 @@ class Bundle extends AbstractType
*/ */
public function prepareForCart($data) public function prepareForCart($data)
{ {
$data['bundle_options'] = array_filter($this->validateBundleOptionForCart($data['bundle_options']));
if (isset($data['bundle_options']))
$data['bundle_options'] = array_filter($this->validateBundleOptionForCart($data['bundle_options']));
if (! isset($data['bundle_options']) || ! count($data['bundle_options'])) if (! isset($data['bundle_options']) || ! count($data['bundle_options']))
return trans('shop::app.checkout.cart.integrity.missing_options'); return trans('shop::app.checkout.cart.integrity.missing_options');

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Type;
use Webkul\Product\Models\ProductAttributeValue; use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductFlat; use Webkul\Product\Models\ProductFlat;
use Illuminate\Support\Str;
/** /**
* Class Configurable. * Class Configurable.
@ -96,7 +97,7 @@ class Configurable extends AbstractType
if (isset($data['variants'])) { if (isset($data['variants'])) {
foreach ($data['variants'] as $variantId => $variantData) { foreach ($data['variants'] as $variantId => $variantData) {
if (str_contains($variantId, 'variant_')) { if (Str::contains($variantId, 'variant_')) {
$permutation = []; $permutation = [];
foreach ($product->super_attributes as $superAttribute) { foreach ($product->super_attributes as $superAttribute) {

View File

@ -39,7 +39,7 @@ class Downloadable extends AbstractType
* *
* @var array * @var array
*/ */
protected $skipAttributes = ['width', 'height', 'depth', 'weight']; protected $skipAttributes = ['width', 'height', 'depth', 'weight', 'guest_checkout'];
/** /**
* These blade files will be included in product edit page * These blade files will be included in product edit page

Some files were not shown because too many files have changed in this diff Show More