commit
0867d34eb2
|
|
@ -61,6 +61,10 @@ Route::group(['middleware' => ['web']], function () {
|
|||
'view' => 'admin::catalog.products.edit'
|
||||
])->name('admin.catalog.products.edit');
|
||||
|
||||
Route::put('/products/edit/{id}', 'Webkul\Product\Http\Controllers\ProductController@update')->defaults('_config', [
|
||||
'redirect' => 'admin.catalog.products.index'
|
||||
])->name('admin.catalog.products.update');
|
||||
|
||||
|
||||
// Catalog Category Routes
|
||||
Route::get('/categories', 'Webkul\Category\Http\Controllers\CategoryController@index')->defaults('_config', [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin;
|
||||
|
||||
class ProductFormAccordian {
|
||||
|
||||
public $items = [];
|
||||
|
||||
/**
|
||||
* Shortcut method for create a Product Form Accordian with a callback.
|
||||
* This will allow you to do things like fire an event on creation.
|
||||
*
|
||||
* @param callable $callback Callback to use after the accordian creation
|
||||
* @return object
|
||||
*/
|
||||
public static function create($callback) {
|
||||
$accordian = new ProductFormAccordian();
|
||||
$callback($accordian);
|
||||
$accordian->items = $accordian->sortItems($accordian->items);
|
||||
|
||||
return $accordian;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a accordian item to the item stack
|
||||
*
|
||||
* @param string $key Dot seperated heirarchy
|
||||
* @param string $name Text for the anchor
|
||||
* @param string $view Blade file for accordian
|
||||
* @param integer $sort Sorting index for the items
|
||||
*/
|
||||
public function add($key, $name, $view, $sort = 0)
|
||||
{
|
||||
array_push($this->items, [
|
||||
'key' => $key,
|
||||
'name' => $name,
|
||||
'view' => $view,
|
||||
'sort' => $sort
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to sort through the acl items and put them in order
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sortItems($items) {
|
||||
usort($items, function($a, $b) {
|
||||
if ($a['sort'] == $b['sort']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($a['sort'] < $b['sort']) ? -1 : 1;
|
||||
});
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,12 @@ class AdminServiceProvider extends ServiceProvider
|
|||
*/
|
||||
protected function composeView()
|
||||
{
|
||||
view()->composer(['admin::catalog.products.create', 'admin::catalog.products.edit'], function ($view) {
|
||||
$accordians = current(Event::fire('admin.catalog.products.accordian.create'));
|
||||
|
||||
$view->with('form_accordians', $accordians);
|
||||
});
|
||||
|
||||
view()->composer(['admin::layouts.nav-left', 'admin::layouts.nav-aside', 'admin::layouts.tabs'], function ($view) {
|
||||
$menu = current(Event::fire('admin.menu.create'));
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Illuminate\Support\ServiceProvider;
|
|||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Webkul\Ui\Menu;
|
||||
use Webkul\Admin\ProductFormAccordian;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -21,6 +22,8 @@ class EventServiceProvider extends ServiceProvider
|
|||
$this->buildACL();
|
||||
|
||||
$this->registerACL();
|
||||
|
||||
$this->createProductFormAccordian();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,4 +113,22 @@ class EventServiceProvider extends ServiceProvider
|
|||
|
||||
View::share('acl', app('acl'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method fires an event for accordian creation, any package can add their accordian item by listening to the admin.catalog.products.accordian.build event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function createProductFormAccordian()
|
||||
{
|
||||
Event::listen('admin.catalog.products.accordian.create', function() {
|
||||
return ProductFormAccordian::create(function($accordian) {
|
||||
Event::fire('admin.catalog.products.accordian.build', $accordian);
|
||||
});
|
||||
});
|
||||
|
||||
Event::listen('admin.catalog.products.accordian.build', function($accordian) {
|
||||
$accordian->add('categories', 'Categories', 'admin::catalog.products.accordians.categories', 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<accordian :title="'{{ __($accordian['name']) }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<div class="control-group">
|
||||
<label for="sku">{{ $attribute->admin_name }}</label>
|
||||
<input type="text" class="control" id="sku" name="sku"/>
|
||||
</div>
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
@csrf()
|
||||
|
||||
<?php $familyId = app('request')->input('family') ?>
|
||||
<?php $sku = app('request')->input('sku') ?>
|
||||
|
||||
<accordian :title="'{{ __('admin::app.catalog.products.general') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
|
@ -57,7 +58,7 @@
|
|||
<select class="control" v-validate="'required'" id="attribute_family_id" name="attribute_family_id" {{ $familyId ? 'disabled' : '' }}>
|
||||
<option value=""></option>
|
||||
@foreach($families as $family)
|
||||
<option value="{{ $family->id }}" {{ $familyId == $family->id ? 'selected' : '' }}>{{ $family->name }}</option>
|
||||
<option value="{{ $family->id }}" {{ ($familyId == $family->id || old('attribute_family_id') == $family->id) ? 'selected' : '' }}>{{ $family->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
|
|
@ -67,13 +68,11 @@
|
|||
<span class="control-error" v-if="errors.has('attribute_family_id')">@{{ errors.first('attribute_family_id') }}</span>
|
||||
</div>
|
||||
|
||||
@if($familyId)
|
||||
<div class="control-group" :class="[errors.has('sku') ? 'has-error' : '']">
|
||||
<label for="sku">{{ __('admin::app.catalog.products.sku') }}</label>
|
||||
<input type="text" v-validate="'required'" class="control" id="sku" name="sku" value="{{ old('sku') }}"/>
|
||||
<span class="control-error" v-if="errors.has('sku')">@{{ errors.first('sku') }}</span>
|
||||
</div>
|
||||
@endif
|
||||
<div class="control-group" :class="[errors.has('sku') ? 'has-error' : '']">
|
||||
<label for="sku">{{ __('admin::app.catalog.products.sku') }}</label>
|
||||
<input type="text" v-validate="'required'" class="control" id="sku" name="sku" value="{{ $sku ?: old('sku') }}"/>
|
||||
<span class="control-error" v-if="errors.has('sku')">@{{ errors.first('sku') }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
|
@ -130,8 +129,14 @@
|
|||
|
||||
@section('javascript')
|
||||
<script>
|
||||
(function() {
|
||||
$(document).ready(function () {
|
||||
$('.label .cross-icon').on('click', function(e) {
|
||||
$(e.target).parent().remove();
|
||||
})
|
||||
|
||||
})();
|
||||
$('.actions .trash-icon').on('click', function(e) {
|
||||
$(e.target).parents('tr').remove();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
@stop
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<form method="POST" action="{{ route('admin.catalog.products.store') }}" @submit.prevent="onSubmit">
|
||||
<form method="POST" action="{{ route('admin.catalog.products.update', $product->id) }}" @submit.prevent="onSubmit">
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>{{ __('admin::app.catalog.products.add-title') }}</h1>
|
||||
<h1>{{ __('admin::app.catalog.products.edit-title') }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
|
|
@ -19,7 +19,31 @@
|
|||
<div class="page-content">
|
||||
@csrf()
|
||||
|
||||
@foreach($product->attribute_family->attribute_groups as $attributeGroup)
|
||||
@if(count($attributeGroup->attributes))
|
||||
<accordian :title="'{{ __($attributeGroup->name) }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
@foreach($attributeGroup->attributes as $attribute)
|
||||
|
||||
@if(view()->exists($typeView = 'admin::catalog.products.attribute-types.' . $attribute->type))
|
||||
|
||||
@include ($typeView)
|
||||
|
||||
@endif
|
||||
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@foreach($form_accordians->items as $accordian)
|
||||
|
||||
@include ($accordian['view'])
|
||||
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ class CreateProductAttributeValueTable extends Migration
|
|||
$table->json('json_value')->nullable();
|
||||
$table->integer('product_id')->unsigned();
|
||||
$table->integer('attribute_id')->unsigned();
|
||||
$table->integer('channel_id')->unsigned();
|
||||
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
|
||||
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
|
||||
$table->unique(['locale', 'attribute_id', 'product_id']);
|
||||
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
|
||||
$table->unique(['channel_id', 'locale', 'attribute_id', 'product_id'], 'chanel_locale_attribute_value_index_unique');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,15 +85,20 @@ class ProductController extends Controller
|
|||
*/
|
||||
public function store()
|
||||
{
|
||||
if(!request()->get('family') && request()->input('type') == 'configurable') {
|
||||
return redirect(url()->current() . '?family=' . request()->input('attribute_family_id'));
|
||||
if(!request()->get('family') && request()->input('type') == 'configurable' && request()->input('sku') != '') {
|
||||
return redirect(url()->current() . '?family=' . request()->input('attribute_family_id') . '&sku=' . request()->input('sku'));
|
||||
}
|
||||
|
||||
if(request()->input('type') == 'configurable' && (!request()->has('super_attributes') || !count(request()->get('super_attributes')))) {
|
||||
session()->flash('error', 'Please select atleast one configurable attribute.');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
$this->validate(request(), [
|
||||
'type' => 'required',
|
||||
'attribute_family_id' => 'required',
|
||||
'sku' => ['required', 'unique:products,sku', new \Webkul\Core\Contracts\Validations\Slug],
|
||||
'super_attributes' => 'required|array|min:1'
|
||||
'sku' => ['required', 'unique:products,sku', new \Webkul\Core\Contracts\Validations\Slug]
|
||||
]);
|
||||
|
||||
$product = $this->product->create(request()->all());
|
||||
|
|
@ -113,6 +118,8 @@ class ProductController extends Controller
|
|||
{
|
||||
$product = $this->product->findOrFail($id);
|
||||
|
||||
dd($product);
|
||||
|
||||
return view($this->_config['view'], compact('product'));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,22 @@ use Illuminate\Database\Eloquent\Model;
|
|||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Category\Models\Category;
|
||||
use Webkul\Inventory\Models\InventorySource;
|
||||
use Webkul\Attribute\Models\AttributeFamily;
|
||||
|
||||
class Product extends Model
|
||||
{
|
||||
protected $fillable = ['type', 'attribute_family_id', 'sku'];
|
||||
|
||||
protected $with = ['super_attributes'];
|
||||
|
||||
/**
|
||||
* Get the product attribute family that owns the product.
|
||||
*/
|
||||
public function attribute_family()
|
||||
{
|
||||
return $this->belongsTo(AttributeFamily::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The categories that belong to the product.
|
||||
*/
|
||||
|
|
@ -58,4 +69,12 @@ class Product extends Model
|
|||
{
|
||||
return $this->belongsToMany(self::class, 'product_cross_sells');
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
// if(array_key_exists($name, $this->data)) {
|
||||
// return $this->data[$name];
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Observers;
|
||||
|
||||
use Webkul\Product\Models\Product;
|
||||
|
||||
class ProductObserver
|
||||
{
|
||||
/**
|
||||
* Handle to the product "created" event.
|
||||
*
|
||||
* @param \App\Product $product
|
||||
* @return void
|
||||
*/
|
||||
public function created(Product $product)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the product "updated" event.
|
||||
*
|
||||
* @param \App\Product $product
|
||||
* @return void
|
||||
*/
|
||||
public function updated(Product $product)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the product "deleted" event.
|
||||
*
|
||||
* @param \App\Product $product
|
||||
* @return void
|
||||
*/
|
||||
public function deleted(Product $product)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ namespace Webkul\Product\Providers;
|
|||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Routing\Router;
|
||||
use Webkul\Product\Models\Product;
|
||||
use Webkul\Product\Observers\ProductObserver;
|
||||
|
||||
class ProductServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -15,6 +17,8 @@ class ProductServiceProvider extends ServiceProvider
|
|||
public function boot(Router $router)
|
||||
{
|
||||
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
|
||||
|
||||
Product::observe(ProductObserver::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@ class ProductRepository extends Repository
|
|||
{
|
||||
$product = $this->model->create($data);
|
||||
|
||||
foreach ($data['super_attributes'] as $attributeId => $attribute) {
|
||||
$product->super_attributes()->attach($attributeId);
|
||||
if(isset($data['super_attributes'])) {
|
||||
foreach ($data['super_attributes'] as $attributeId => $attribute) {
|
||||
$product->super_attributes()->attach($attributeId);
|
||||
}
|
||||
}
|
||||
|
||||
return $product;
|
||||
|
|
|
|||
Loading…
Reference in New Issue