Enhancement #3477, images for variant product

This commit is contained in:
rahul shukla 2021-03-09 15:14:27 +05:30
parent 4451465938
commit 2897d0238d
2 changed files with 180 additions and 3 deletions

View File

@ -19,6 +19,16 @@
</style>
@stop
@php
$variantImages = [];
foreach ($product->variants as $variant) {
foreach ($variant->images as $image) {
$variantImages[$variant->id] = $image;
}
}
@endphp
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.before', ['product' => $product]) !!}
<accordian :title="'{{ __('admin::app.catalog.products.variations') }}'" :active="true">
@ -96,6 +106,7 @@
<tr>
<th class="sku">{{ __('admin::app.catalog.products.sku') }}</th>
<th>{{ __('admin::app.catalog.products.name') }}</th>
<th>{{ __('admin::app.catalog.products.images') }}</th>
@foreach ($product->super_attributes as $attribute)
<th class="{{ $attribute->code }}"
@ -145,6 +156,29 @@
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[images]') ? 'has-error' : '']">
<div v-for='(image, index) in items' class="image-wrapper">
<label class="image-item" v-bind:class="{ 'has-image': imageData[index] }">
<input type="hidden" :name="[variantInputName + '[images][' + image.id + ']']" v-if="! new_image[index]"/>
<input type="file" v-validate="'mimes:image/*'" :name="[variantInputName + '[images][' + index + ']']" v-model="images[index]" accept="image/*" ref="imageInput" multiple="multiple" @change="addImageView($event, index)" :id="image.id"/>
<img class="preview" :src="imageData[index]" v-if="imageData[index]">
<label class="remove-image" @click="removeImage(image)">
{{ __('admin::app.catalog.products.remove-image-btn-title') }}
</label>
</label>
</div>
<label class="btn btn-lg btn-primary" style="display: inline-block; width: auto" @click="createFileType">
{{ __('admin::app.catalog.products.add-image-btn-title') }}
</label>
</div>
</td>
<td v-for='(attribute, index) in superAttributes'>
<div class="control-group">
<input type="hidden" :name="[variantInputName + '[' + attribute.code + ']']"
@ -388,7 +422,13 @@
inventorySources: @json($inventorySources),
inventories: {},
totalQty: 0,
superAttributes: super_attributes
superAttributes: super_attributes,
items: [],
imageCount: 0,
images: {},
imageData: [],
new_image: [],
}
},
@ -401,6 +441,21 @@
})
},
mounted () {
var this_this = this;
this_this.variant.images.forEach(function(image) {
this_this.items.push(image)
this_this.imageCount++;
if (image.id && image.url) {
this_this.imageData.push(image.url);
} else if (image.id && image.file) {
this_this.readFile(image.file);
}
});
},
computed: {
variantInputName: function () {
if (this.variant.id)
@ -449,9 +504,61 @@
for (var key in this.inventories) {
this.totalQty += parseInt(this.inventories[key]);
}
}
}
},
createFileType: function() {
var this_this = this;
this.imageCount++;
this.items.push({'id': 'image_' + this.imageCount});
},
removeImage (image) {
let index = this.items.indexOf(image);
Vue.delete(this.items, index);
},
addImageView: function($event, index) {
var imageInput = this.$refs.imageInput;
var imageInput = imageInput[imageInput.length - 1];
if (imageInput.files && imageInput.files[0]) {
if (imageInput.files[0].type.includes('image/')) {
this.readFile(imageInput.files[0], index)
if (imageInput.files.length > 1) {
this.$emit('onImageSelected', imageInput)
}
} else {
imageInput.value = "";
alert('Only images (.jpeg, .jpg, .png, ..) are allowed.');
}
}
},
readFile: function(image, index) {
var imageInput = this.$refs.imageInput;
var reader = new FileReader();
reader.onload = (e) => {
var dataIndex = this.imageData.indexOf(this.imageData[index]);
if (dataIndex >= 0) {
this.imageData.splice(dataIndex, 1, e.target.result);
} else {
this.imageData.push(e.target.result);
}
}
reader.readAsDataURL(image);
this.new_image[imageInput.length-1] = 1;
},
}
});
</script>
@endpush

View File

@ -6,9 +6,35 @@ use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Http\UploadedFile;
use Webkul\Core\Eloquent\Repository;
use Illuminate\Container\Container as App;
use Webkul\Product\Repositories\ProductRepository;
class ProductImageRepository extends Repository
{
/**
* ProductRepository object
*
* @return Object
*/
protected $productRepository;
/**
* Create a new repository instance.
*
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Illuminate\Container\Container $app
*
* @return void
*/
public function __construct(
ProductRepository $productRepository,
App $app
) {
parent::__construct($app);
$this->productRepository = $productRepository;
}
/**
* Specify Model class name
*
@ -48,6 +74,10 @@ class ProductImageRepository extends Repository
}
}
if (isset($data['variants'])) {
$this->uploadVariantImages($data['variants']);
}
foreach ($previousImageIds as $imageId) {
if ($imageModel = $this->find($imageId)) {
Storage::delete($imageModel->path);
@ -56,4 +86,44 @@ class ProductImageRepository extends Repository
}
}
}
/**
* @param array $variants
* @return void
*/
public function uploadVariantImages($variants)
{
foreach ($variants as $variantsId => $variant) {
$product = $this->productRepository->findOrFail($variantsId);
$previousVariantImageIds = $product->images()->pluck('id');
if (isset($variant['images'])) {
foreach ($variant['images'] as $imageId => $image) {
$file = 'variants.' . $product->id .'.'. 'images.' . $imageId;
$dir = 'product/' . $product->id;
if ($image instanceof UploadedFile) {
if (request()->hasFile($file)) {
$this->create([
'path' => request()->file($file)->store($dir),
'product_id' => $product->id,
]);
}
} else {
if (is_numeric($index = $previousVariantImageIds->search($imageId))) {
$previousVariantImageIds->forget($index);
}
}
}
}
foreach ($previousVariantImageIds as $imageId) {
if ($imageModel = $this->find($imageId)) {
Storage::delete($imageModel->path);
$this->delete($imageId);
}
}
}
}
}