add image resizer

This commit is contained in:
Jérémy Munsch 2023-09-06 17:56:52 +02:00
parent e6796029ec
commit 042e78583e
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
4 changed files with 441 additions and 101 deletions

View file

@ -12,6 +12,7 @@
"carlos-meneses/laravel-mpdf": "^2.1",
"diglactic/laravel-breadcrumbs": "^8.0",
"guzzlehttp/guzzle": "^7.2",
"kwaadpepper/image-resizer": "^2.1",
"laravel/framework": "^10.0",
"laravel/tinker": "^2.8"
},

278
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "72bd46bbe723badbb255fbe8130d9305",
"content-hash": "681daf9716dc063b99412ff470a716dc",
"packages": [
{
"name": "brick/math",
@ -1154,6 +1154,217 @@
],
"time": "2021-10-07T12:57:01+00:00"
},
{
"name": "intervention/image",
"version": "2.7.2",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "04be355f8d6734c826045d02a1079ad658322dad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/04be355f8d6734c826045d02a1079ad658322dad",
"reference": "04be355f8d6734c826045d02a1079ad658322dad",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"guzzlehttp/psr7": "~1.1 || ^2.0",
"php": ">=5.4.0"
},
"require-dev": {
"mockery/mockery": "~0.9.2",
"phpunit/phpunit": "^4.8 || ^5.7 || ^7.5.15"
},
"suggest": {
"ext-gd": "to use GD library based image processing.",
"ext-imagick": "to use Imagick based image processing.",
"intervention/imagecache": "Caching extension for the Intervention Image library"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
},
"laravel": {
"providers": [
"Intervention\\Image\\ImageServiceProvider"
],
"aliases": {
"Image": "Intervention\\Image\\Facades\\Image"
}
}
},
"autoload": {
"psr-4": {
"Intervention\\Image\\": "src/Intervention/Image"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@intervention.io",
"homepage": "https://intervention.io/"
}
],
"description": "Image handling and manipulation library with support for Laravel integration",
"homepage": "http://image.intervention.io/",
"keywords": [
"gd",
"image",
"imagick",
"laravel",
"thumbnail",
"watermark"
],
"support": {
"issues": "https://github.com/Intervention/image/issues",
"source": "https://github.com/Intervention/image/tree/2.7.2"
},
"funding": [
{
"url": "https://paypal.me/interventionio",
"type": "custom"
},
{
"url": "https://github.com/Intervention",
"type": "github"
}
],
"time": "2022-05-21T17:30:32+00:00"
},
{
"name": "intervention/imagecache",
"version": "2.6.0",
"source": {
"type": "git",
"url": "https://github.com/Intervention/imagecache.git",
"reference": "86136575a62d3634b51f196a998fce4a583b49bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/imagecache/zipball/86136575a62d3634b51f196a998fce4a583b49bb",
"reference": "86136575a62d3634b51f196a998fce4a583b49bb",
"shasum": ""
},
"require": {
"illuminate/cache": "^5.5|~6|~7|~8|~9|~10",
"illuminate/filesystem": "^5.5|~6|~7|~8|~9|~10",
"intervention/image": "~2.2",
"nesbot/carbon": "^2.39",
"opis/closure": "^3.5",
"php": "~7.2|~8"
},
"require-dev": {
"phpunit/phpunit": "^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Intervention\\Image\\": "src/Intervention/Image"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@intervention.io",
"homepage": "http://intervention.io/"
}
],
"description": "Caching extension for the Intervention Image Class",
"homepage": "https://image.intervention.io",
"keywords": [
"cache",
"gd",
"image",
"imagick",
"laravel"
],
"support": {
"issues": "https://github.com/Intervention/imagecache/issues",
"source": "https://github.com/Intervention/imagecache/tree/2.6.0"
},
"funding": [
{
"url": "https://paypal.me/interventionio",
"type": "custom"
},
{
"url": "https://github.com/Intervention",
"type": "github"
}
],
"time": "2023-02-25T19:40:47+00:00"
},
{
"name": "kwaadpepper/image-resizer",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/Kwaadpepper/image-resizer.git",
"reference": "2a14ad153b34916f437af50549bad47c018902df"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Kwaadpepper/image-resizer/zipball/2a14ad153b34916f437af50549bad47c018902df",
"reference": "2a14ad153b34916f437af50549bad47c018902df",
"shasum": ""
},
"require": {
"illuminate/support": "~10",
"intervention/image": "^2.7.2",
"intervention/imagecache": "^2.6",
"laravel/framework": "~10"
},
"require-dev": {
"slevomat/coding-standard": "^8.11"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Kwaadpepper\\ImageResizer\\ImageResizerServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Kwaadpepper\\ImageResizer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jérémy Munsch",
"email": "github@jeremydev.ovh",
"homepage": "https://jeremydev.ovh"
}
],
"description": "Resize images on the fly and cache them",
"homepage": "https://github.com/kwaadpepper/image-resizer",
"keywords": [
"images",
"laravel",
"resize"
],
"support": {
"issues": "https://github.com/Kwaadpepper/image-resizer/issues",
"source": "https://github.com/Kwaadpepper/image-resizer/tree/2.1.0"
},
"time": "2023-06-08T12:07:24+00:00"
},
{
"name": "laravel/framework",
"version": "v10.10.1",
@ -2548,6 +2759,71 @@
],
"time": "2023-02-08T01:06:31+00:00"
},
{
"name": "opis/closure",
"version": "3.6.3",
"source": {
"type": "git",
"url": "https://github.com/opis/closure.git",
"reference": "3d81e4309d2a927abbe66df935f4bb60082805ad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad",
"reference": "3d81e4309d2a927abbe66df935f4bb60082805ad",
"shasum": ""
},
"require": {
"php": "^5.4 || ^7.0 || ^8.0"
},
"require-dev": {
"jeremeamia/superclosure": "^2.0",
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.6.x-dev"
}
},
"autoload": {
"files": [
"functions.php"
],
"psr-4": {
"Opis\\Closure\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marius Sarca",
"email": "marius.sarca@gmail.com"
},
{
"name": "Sorin Sarca",
"email": "sarca_sorin@hotmail.com"
}
],
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
"homepage": "https://opis.io/closure",
"keywords": [
"anonymous functions",
"closure",
"function",
"serializable",
"serialization",
"serialize"
],
"support": {
"issues": "https://github.com/opis/closure/issues",
"source": "https://github.com/opis/closure/tree/3.6.3"
},
"time": "2022-01-27T09:35:39+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v9.99.100",

69
config/image-resizer.php Normal file
View file

@ -0,0 +1,69 @@
<?php
return [
/**
* The php image driver to use
* this can be 'imagick' or 'gd'
*/
'driver' => 'imagick',
/**
* The cache driver to use as defined
* in config/cache of your app
*/
'cache' => 'file',
/**
* The path where to store image in cache
*/
'cachePath' => 'cache/images',
/**
* Image cache life time
* This is given in minutes
* Here the cache for images is
* one hour
*/
'lifetime' => 60,
/**
* Format can specifiy to which format save the image
* JPEG PNG GIF TIF BMP ICO PSD WebP
* GD ✔️ ✔️ ✔️ - - - - ✔️ *
* Imagick ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ *
* For WebP support GD driver must be used with PHP 5 >= 5.5.0 or PHP 7
* in order to use imagewebp(). If Imagick is used, it must be compiled
* with libwebp for WebP support.
* resize => will resize the image (boolean)
* fit => Combine cropping and resizing to format image in a smart way (boolean)
* keepRatio => will keep image ratio wile resizing (boolean)
* trim => boolean to trim the image using border color
* inCanvas => to make sure image boundarie is respected
* format => select tha wantd ouput form, yan can just convert images if you want
* example :
* 'small' => [
* 'height' => 500,
* 'width' => 250,
* 'inCanvas' => true,
* 'trim' => ['transparent', null, 10]
* ],
* 'smallWebp' => [
* 'height' => 500,
* 'width' => 250,
* 'inCanvas' => true,
* 'format' => 'webp'
* ],
* 'justconvertImage' => [
* 'format' => 'webp'
* ]
*/
'templates' => [
'productTiny' => [
'height' => 180,
'width' => 180,
'resize' => true,
'keepRatio' => true,
'format' => 'jpg',
],
]
];

View file

@ -1,109 +1,103 @@
<div class="table-responsive">
<table class="table fix-action m-0 mt-3">
<table class="fix-action m-0 mt-3 table">
<thead>
@php
$cols = [
'name' => __('Nom'),
'brand_id' => __('Marque'),
'picture' => __('Image'),
'multi_pdf' => __('Générer en pdf la sélection'),
];
$routeName = request()->route()->getName();
$rst = !is_null(request()->rst) || !Session::has("$routeName.sorted");
$noOrder = Session::get("$routeName.sort_col") !== 'order' and (Session::has("$routeName.sort_col") or Session::has("$routeName.sort_way"));
$noOrder = Session::get("$routeName.sort_col") !== '' and (Session::has("$routeName.sort_col") or Session::has("$routeName.sort_way"));
@endphp
@include('modules.table-col-sorter', ['cols' => $cols, 'mobileHide' => [], 'ignore' => ['multi_pdf']])
@php
$cols = [
'name' => __('Nom'),
'brand_id' => __('Marque'),
'picture' => __('Image'),
'multi_pdf' => __('Générer en pdf la sélection'),
];
$routeName = request()
->route()
->getName();
$rst = !is_null(request()->rst) || !Session::has("$routeName.sorted");
($noOrder = Session::get("$routeName.sort_col") !== 'order') and (Session::has("$routeName.sort_col") or Session::has("$routeName.sort_way"));
($noOrder = Session::get("$routeName.sort_col") !== '') and (Session::has("$routeName.sort_col") or Session::has("$routeName.sort_way"));
@endphp
@include('modules.table-col-sorter', ['cols' => $cols, 'mobileHide' => [], 'ignore' => ['multi_pdf']])
</thead>
<tbody>
@if ($products->count())
@foreach ($products as $productModel)
<tr>
<td class="align-middle text-center">
<span>{{ $productModel->name }}</span>
</td>
<td class="align-middle text-center">
@foreach($brands as $key => $brand)
@if ($brand->id === $productModel->brand_id)
<p class="m-0">{{ $brand->name }}</p>
@endif
@endforeach
</td>
<td class="align-middle text-center">
@if(isset($productModel->picture))
<img class="bo-image-preview" src="{{ asset($productModel->picture) }}">
@else
<p class="text-muted">{{ __('Aucune image enregistée') }}</p>
@endif
</td>
{{-- @if(!$noOrder or $rst) --}}
<td class="align-middle text-center">
@php
$data = [
'id' => 'productSelectMultiPdf',
'model' => $productModel,
'printMultiProduct' => $printMultiProduct,
];
@endphp
<div class="button-multi-pdf" data-json='@json($data)'></div>
</td>
{{-- @endif --}}
<td class="align-middle text-end">
<form action="{{ route('products.destroy', $productModel->id) }}" method="POST" class="d-inline confirmDeleteJS">
@method('DELETE')
@csrf
<div class="btn-group" role="group">
<a class="btn btn-sm btn-info glightbox" type="button"
href="{{ asset($productModel->picture) }}" target="_blank"
data-gallery="product{{ $productModel->id }}"
data-bs-title="{{ __('Visionner l\'image de la :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
data-bs="tooltip">
<i class="fa-solid fa-image"></i>
</a>
<a class="btn btn-sm btn-warning" type="button"
href="{{ route('products.download', $productModel) }}"
title="{{ __('Télécharger les annexes de la :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
data-bs="tooltip">
<i class="fa-solid fa-download"></i>
</a>
<a class="btn btn-sm btn-secondary btn-printing" type="button"
href="{{ route('products.pdf.show', $productModel) }}"
target="blank"
title="{{ __('Fichier .pdf de la :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
data-bs="tooltip"
data-id="{{ $productModel->id }}">
<i class="fa-solid fa-print"></i>
</a>
<a class="btn btn-sm btn-success"
href="{{ route('products.duplicate', $productModel) }}"
title="{{ __('Dupliquer cette :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
data-bs="tooltip">
<i class="fa-solid fa-copy"></i>
</a>
<a class="btn btn-sm btn-primary"
href="{{ route('products.edit', $productModel) }}"
title="{{ __('Modifier cette :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
data-bs="tooltip">
<i class="fa-solid fa-pencil"></i>
</a>
<button class="btn btn-sm btn-danger"
title="{{ __('Supprimer cette :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
data-bs="tooltip">
<i class="fa-solid fa-trash"></i>
</button>
</div>
</form>
</td>
</tr>
@endforeach
@foreach ($products as $productModel)
<tr>
<td class="text-center align-middle">
<span>{{ $productModel->name }}</span>
</td>
<td class="text-center align-middle">
@foreach ($brands as $key => $brand)
@if ($brand->id === $productModel->brand_id)
<p class="m-0">{{ $brand->name }}</p>
@endif
@endforeach
</td>
<td class="text-center align-middle">
@if ($productModel->picture)
<img class="bo-image-preview" src="{{ asset(resize($productModel->picture, 'productTiny')) }}">
@else
<p class="text-muted">{{ __('Aucune image enregistée') }}</p>
@endif
</td>
{{-- @if (!$noOrder or $rst) --}}
<td class="text-center align-middle">
@php
$data = [
'id' => 'productSelectMultiPdf',
'model' => $productModel,
'printMultiProduct' => $printMultiProduct,
];
@endphp
<div class="button-multi-pdf" data-json='@json($data)'></div>
</td>
{{-- @endif --}}
<td class="text-end align-middle">
<form class="d-inline confirmDeleteJS" action="{{ route('products.destroy', $productModel->id) }}"
method="POST">
@method('DELETE')
@csrf
<div class="btn-group" role="group">
<a class="btn btn-sm btn-info glightbox" data-gallery="product{{ $productModel->id }}"
data-bs-title="{{ __('Visionner l\'image de la :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
data-bs="tooltip" type="button" href="{{ asset($productModel->picture) }}" target="_blank">
<i class="fa-solid fa-image"></i>
</a>
<a class="btn btn-sm btn-warning" data-bs="tooltip" type="button"
href="{{ route('products.download', $productModel) }}"
title="{{ __('Télécharger les annexes de la :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}">
<i class="fa-solid fa-download"></i>
</a>
<a class="btn btn-sm btn-secondary btn-printing" data-bs="tooltip" data-id="{{ $productModel->id }}"
type="button" href="{{ route('products.pdf.show', $productModel) }}"
title="{{ __('Fichier .pdf de la :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}"
target="blank">
<i class="fa-solid fa-print"></i>
</a>
<a class="btn btn-sm btn-success" data-bs="tooltip"
href="{{ route('products.duplicate', $productModel) }}"
title="{{ __('Dupliquer cette :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}">
<i class="fa-solid fa-copy"></i>
</a>
<a class="btn btn-sm btn-primary" data-bs="tooltip" href="{{ route('products.edit', $productModel) }}"
title="{{ __('Modifier cette :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}">
<i class="fa-solid fa-pencil"></i>
</a>
<button class="btn btn-sm btn-danger" data-bs="tooltip"
title="{{ __('Supprimer cette :model', ['model' => trans_choice('models.classes.products_monitoring', 1)]) }}">
<i class="fa-solid fa-trash"></i>
</button>
</div>
</form>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="{{ count($cols)+1 }}" class="text-center">
<span
class="h3">{{ __('Aucun résultat pour les :models', ['models' => trans_choice('models.classes.products_monitoring', 2)]) }}
</span>
</td>
</tr>
<tr>
<td class="text-center" colspan="{{ count($cols) + 1 }}">
<span
class="h3">{{ __('Aucun résultat pour les :models', ['models' => trans_choice('models.classes.products_monitoring', 2)]) }}
</span>
</td>
</tr>
@endif
</tbody>
</table>