remplacement/redimensionnement automatique d'images INCO lorsque disponible.

This commit is contained in:
Olivier Legat 2021-07-29 17:40:48 +02:00
parent 291a41f2ba
commit eb0a6dc919
4 changed files with 203 additions and 23 deletions

View file

@ -15,6 +15,7 @@ use App\Models\TaxRate;
use App\Models\XmlInco;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\File;
class ProductsController extends Controller
{
@ -190,7 +191,7 @@ class ProductsController extends Controller
*/
public function edit($id)
{
$product = Product::findOrFail($id);
$product = Product::findOrFail($id);
if(!empty($product->product_type)) {
$product->additionnalProductInfo = $product->additionnalProductInfo($product->product_type);
//above lines equivalent to :
@ -218,7 +219,6 @@ class ProductsController extends Controller
/**
* update an existing product
* @todo : enregistrer unité de vente, poids et unité de poids
*/
public function update(Request $request, $id)
{
@ -429,6 +429,152 @@ class ProductsController extends Controller
}
}
/**
* prepare Inco Images
*/
public function prepareIncoImages(Request $request) {
$picture = $request->picture;
$preparedImages = array();
foreach ($picture as $incoImage) {
//charge
if(File::exists(storage_path($incoImage))) {
$imagePath = storage_path($incoImage);
//redimensionne
//create mask
//Resize original image into mask
$this->resizeImg(
$imagePath,
config('theme.product_image_large_maxwidth'),
config('theme.product_image_large_maxheight'),
File::name($incoImage) . "_large.png"
);
$this->resizeImg(
$imagePath,
config('theme.product_image_maxwidth'),
config('theme.product_image_maxheight'),
File::name($incoImage) . "_small.png"
);
$preparedImages[] = "inco/images/" . File::name($incoImage) . "_large.png";
}
}
//return array("data"=> $preparedImages);
return view('bo.products.inco-images', compact('preparedImages'));
}
/**
* redimensionne une image dans un masque
*/
private function resizeImg($imagePath, $maskWidth, $maskHeight, $resizedName)
{
// ---- création du masque
$mask = imagecreatetruecolor($maskWidth, $maskHeight);
imagesavealpha($mask, true);
$color = imagecolorallocatealpha($mask, 0, 0, 0, 127);
imagefill($mask, 0, 0, $color);
// ---- Récupère le mime type de l'image
$info = getimagesize($imagePath);
$mime = $info['mime'];
// ---- Défini les fonctions à appeler selon le type de fichier
switch ($mime) {
case 'image/jpeg':
$image_create_func = 'imagecreatefromjpeg';
break;
case 'image/png':
$image_create_func = 'imagecreatefrompng';
break;
default:
return false;
}
// ---- Chargement de l'image source
$img = $image_create_func($imagePath);
list($imgWidth, $imgHeight) = getimagesize($imagePath);
// ---- Calcul les nouvelles dimensions de l'image
if($imgWidth > $imgHeight){
$finalWidth = $maskWidth;
$finalHeight = ($finalWidth*$imgHeight)/$imgWidth;
}else{
$finalHeight = $maskHeight;
$finalWidth = ($finalHeight*$imgWidth)/$imgHeight;
}
// ---- Redimensionne l'image source
$resizeImg = imagecreatetruecolor($finalWidth, $finalHeight);
imagealphablending( $resizeImg, false );
imagesavealpha( $resizeImg, true );
imagecopyresampled($resizeImg, $img, 0, 0, 0, 0, $finalWidth, $finalHeight, $imgWidth, $imgHeight);
// ---- Copie l'image redimensionnée dans le mask
imagecopy($mask, $resizeImg, ($maskWidth-$finalWidth)/2, ($maskHeight-$finalHeight)/2, 0, 0, imagesx($resizeImg), imagesy($resizeImg));
imagealphablending( $mask, false );
imagesavealpha( $mask, true );
//écrit dans storage/app/public
// ---- Créer le fichier final
imagepng($mask, storage_path('app/public/inco/images/' . $resizedName), 5);
// ---- Libère la mémoire associée aux images manipulées
imagedestroy($img);
imagedestroy($resizeImg);
imagedestroy($mask);
}
/**
* set une image préparée comme image du produit
*/
public function setIncoImage(Request $request)
{
$imagePath = $request->picture;
$imagePath = storage_path("app/public/" . $imagePath);
$product_id = $request->product;
$product = Product::findOrFail($product_id);
$str_random = Str::random(5);
//default is large image
$finalImageName = $product->id . '_' . $str_random . '_large.' . File::extension($imagePath);
$productimagespath = public_path('images/produits');
if(!File::isDirectory($productimagespath)) {
File::makeDirectory($productimagespath, 0644, true);
}
File::copy($imagePath, $productimagespath . "/" . $finalImageName);
//suppression de l'ancien fichier
if ($product->picture_large !== null && file_exists(public_path('images/produits/') . $product->picture_large)) {
unlink(public_path('images/produits/') . $product->picture_large);
}
$product->picture_large = $finalImageName;
//now set small image
$imagePath = str_replace("_large", "_small", $imagePath);
$finalImageName = $product->id . '_' . $str_random . '.' . File::extension($imagePath);
File::copy($imagePath, $productimagespath . "/" . $finalImageName);
//suppression de l'ancien fichier
if ($product->picture !== null && file_exists(public_path('images/produits/') . $product->picture)) {
unlink(public_path('images/produits/') . $product->picture);
}
$product->picture = $finalImageName;
$product->save();
}
/**
* helper method to update additionnal product info
* foodProduct

View file

@ -63,29 +63,15 @@
<img src="/images/produits/{{$product->picture}}" alt="{{$product->name}}" style="max-height: 100px;">
</a>
@endif
{{-- WIP : use Inco Assets
{{-- variante préparation d'images --}}
@if ($product->product_type == "foodProduct")
@if (!empty($product->foodProduct->xmlInco))
<input type="hidden" id="inco_picture" name="inco_picture">
<a class="btn btn-outline-info btn-sm" data-toggle="collapse" href="#inco_media" aria-expanded="false" aria-controls="collapseExample">Donnée inco</a>
@if (!empty($product->foodProduct->xmlInco->picture))
<a class="btn btn-outline-info btn-sm" data-toggle="collapse" href="#inco_media" aria-expanded="false" aria-controls="collapseExample" id="prepareIncoImages">Images inco</a>
<div class="collapse form-row" id="inco_media">
@foreach ($product->foodProduct->xmlInco->medias as $media)
<div class="input-group mb-2">
<div class="input-group-prepend">
<a class="btn btn-secondary" onclick="setPicture('{{$media['filename']}}','inco_picture')">Reprendre cette image</a>
</div>
<div class="inco_data alert-info">
<a data-fancybox="gallery-inco" data-src="#hidden-image-{{Str::slug($media['filename'])}}">
<img src="data:image/png;base64, {!! $media['imgdata'] !!}" alt="{{$media['filename']}}" style="max-height: 100px;">
</a>
<img id="hidden-image-{{Str::slug($media['filename'])}}" src="data:image/png;base64, {!! $media['imgdata'] !!}" alt="{{$media['filename']}}" style="display:none;">
</div>
</div>
@endforeach
<!--inco images container-->
</div>
@endif
@endif --}}
@endif
</div>
<div class="form-group">
<label for="picture_large">Image (grande) <small class="text-muted">- JPEG/PNG, 2Mo max. Dimensions {{ Config::get('theme.product_image_large_maxwidth') }} px par {{ Config::get('theme.product_image_large_maxheight') }} px</small></label></br>
@ -243,9 +229,24 @@
@section('scripts')
<script type="text/javascript">
function setPicture(text,to) {
function setPicture(imgname) {
//in fact we should Ajx call this opération to change just the image
document.getElementById(to).value = text;
console.log(imgname);
axios.post('/bo/ajax/set-inco-images', {
picture: imgname,
product: {{ $product->id}}
}).then(
(response) => {
if(response.data.length) {
}
}
)
.catch(function (error) {
console.log(error);
alert('Erreur lors de la mise à jour.');
this.processing = false;
});
}
function paste(from,to) {
@ -278,5 +279,24 @@
.catch( error => {
console.error( error );
} );
$(document).ready(function(){
$("#prepareIncoImages").click(function(){
axios.post('/bo/ajax/get-inco-images', {
picture: @json($product->foodProduct->xmlInco->picture ?? ''),
}).then(
(response) => {
if(response.data.length) {
$('#inco_media').html(response.data);
}
}
)
.catch(function (error) {
console.log(error);
alert('Erreur lors de la vérification.');
this.processing = false;
});
});
});
</script>
@endsection

View file

@ -0,0 +1,12 @@
@foreach ($preparedImages as $media)
<div class="input-group mb-2">
<div class="input-group-prepend">
<a class="btn btn-secondary" onclick="setPicture('{{ $media }}')">Reprendre cette Image</a>
</div>
<div class="inco_data form-control alert-info">
<a data-fancybox="gallery" href="/storage/{{ $media }}">
<img src="/storage/{{ $media }}" alt="visuel Inco" style="max-height: 100px;">
</a>
</div>
</div>
@endforeach

View file

@ -88,6 +88,8 @@ Route::namespace('App\Http\Controllers\Bo')
Route::post('/ajax/delete-creneaux-exception', [\App\Http\Controllers\Bo\MagasinsController::class, 'destroyExceptions']);
//recherche d'inco
Route::post('/ajax/check-inco-data', [\App\Http\Controllers\Bo\ProductsController::class, 'checkIncoData']);
Route::post('/ajax/get-inco-images', [\App\Http\Controllers\Bo\ProductsController::class, 'prepareIncoImages']);
Route::post('/ajax/set-inco-images', [\App\Http\Controllers\Bo\ProductsController::class, 'setIncoImage']);
// Produits
//route ajoutée avant la déclaration de route resource sinon la forme /products/{product} l'emporte lors du routage