Saat mengerjakan proyek baru yang digunakan Laravel Nova untuk mengelola , saya mengujinya dengan alat webmaster Google. Ternyata beberapa foto pada sumber daya tidak dioptimalkan - ukurannya dapat dikurangi secara signifikan. Yang ada di proyek dapat diproses saat membangun proyek menggunakan node.js. Ada banyak paket yang sudah jadi untuk ini. Masih ada gambar yang diunggah oleh pengguna langsung dari panel administrasi situs. Tentu saja, Anda dapat mengoptimalkan setiap gambar sebelum mengunggah ke situs, tetapi mengapa tidak menjadikan prosedur ini otomatis. Maka lahirlah ide untuk membuat paket untuk Laravel Nova: OptimalImage.
Paket ini cukup sederhana, dan karena itu tidak berpura-pura menjadi panduan lengkap untuk membuat paket untuk Laravel Nova. Itu tidak membahas topik yang agak luas tentang bekerja dengan komponen visual komponen. Jika ide menarik tentang komponen muncul, dengan komponen visual - saya akan menulis artikel tentang topik ini.
Perumusan masalah
Anda ingin membuat paket yang menambahkan bidang baru. Bidang ini akan berbeda dari
bidang biasa dengan pemuatan gambar dalam pengoptimalan yang akan dilakukan untuk gambar yang dimuat.
Instalasi dan konfigurasi lingkungan.
Untuk mengulangi semua langkah dalam panduan ini, Anda akan memerlukan proyek dengan Laravel dan Laravel Nova. Laravel Nova adalah alat berbayar, tetapi menurut saya harganya cukup terjangkau.
Saya digunakan dalam pekerjaan:
- PHP 7.3.16
- Laravel 7
- Laravel Nova 3.0
.
. — :
cd /path/to/nova/project
php artisan nova:field yarbala/optimal-image
. nova-components
OptimalImage.
nova-components
.gitignore git init
cd /path/to/nova/project/nova-components/OptimalImage
git init
git add .
git commit -m "First commit"
git remote add origin git@github.com:yarbala/nova-optimal-image-field.git
git push -u origin master
spatie/laravel-image-optimizer
, require
composer.json
"spatie/laravel-image-optimizer": "^1.6"
Laravel
composer update
.
:
nova-components/OptimalImage/dist
nova-components/OptimalImage/resources
:
nova-components/OptimalImage/webpack.mix.js
nova-components/OptimalImage/package.json
nova-components/OptimalImage/mix-manifest.json
OptimalImage :
namespace Yarbala\OptimalImage;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Laravel\Nova\Fields\Image;
class OptimalImage extends Image
{
protected function storeFile($request, $requestAttribute)
{
if (! $this->storeAsCallback) {
$fileName = $request->file($requestAttribute)->store($this->getStorageDir(), $this->getStorageDisk());
if ($fileName) {
try {
$this->optimizeImage($fileName);
} catch (FileNotFoundException $e) {
}
}
return $fileName;
}
$fileName = $request->file($requestAttribute)->storeAs(
$this->getStorageDir(), call_user_func($this->storeAsCallback, $request), $this->getStorageDisk()
);
if ($fileName) {
try {
$this->optimizeImage($fileName);
} catch (FileNotFoundException $e) {
}
}
return $fileName;
}
protected function optimizeImage($fileName)
{
}
}
Laravel\Nova\Fields\Image
.
public $component = 'optimal-image';
storeFile
Laravel\Nova\Fields\File
, Laravel\Nova\Fields\Image
. . , optimizeImage
.
optimizeImage:
namespace Yarbala\OptimalImage;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Laravel\Nova\Fields\Image;
use Spatie\ImageOptimizer\OptimizerChain as ImageOptimizer;
use Storage;
class OptimalImage extends Image
{
protected function optimizeImage($fileName)
{
$needsUploadBack = false;
$localDisk = 'local';
$disk = $this->getStorageDisk();
if (!Storage::disk($localDisk)->exists($fileName)) {
Storage::disk($localDisk)->put($fileName, Storage::disk($disk)->get($fileName));
$needsUploadBack = true;
}
$path = Storage::disk($localDisk)->path($fileName);
app(ImageOptimizer::class)->optimize($path);
if ($needsUploadBack) {
Storage::disk($disk)->put($fileName, Storage::disk($localDisk)->get($fileName));
Storage::disk($localDisk)->delete($fileName);
}
}
}
Storage, Spatie\ImageOptimizer . - local
.
:
class OptimalImage extends Image
{
public function localDisk(string $disk)
{
return $this->withMeta(['localDisk' => $disk]);
}
protected function getLocalDisk()
{
return $this->meta['localDisk'] ?? 'local';
}
}
OptimalImage :
<?php
namespace Yarbala\OptimalImage;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Laravel\Nova\Fields\Image;
use Spatie\ImageOptimizer\OptimizerChain as ImageOptimizer;
use Illuminate\Support\Facades\Storage;
class OptimalImage extends Image
{
protected function storeFile($request, $requestAttribute)
{
if (! $this->storeAsCallback) {
$fileName = $request->file($requestAttribute)->store($this->getStorageDir(), $this->getStorageDisk());
if ($fileName) {
try {
$this->optimizeImage($fileName);
} catch (FileNotFoundException $e) {
}
}
return $fileName;
}
$fileName = $request->file($requestAttribute)->storeAs(
$this->getStorageDir(), call_user_func($this->storeAsCallback, $request), $this->getStorageDisk()
);
if ($fileName) {
try {
$this->optimizeImage($fileName);
} catch (FileNotFoundException $e) {
}
}
return $fileName;
}
protected function optimizeImage($fileName)
{
$needsUploadBack = false;
$localDisk = $this->getLocalDisk();
$disk = $this->getStorageDisk();
if (!Storage::disk($localDisk)->exists($fileName)) {
Storage::disk($localDisk)->put($fileName, Storage::disk($disk)->get($fileName));
$needsUploadBack = true;
}
$path = Storage::disk($localDisk)->path($fileName);
app(ImageOptimizer::class)->optimize($path);
if ($needsUploadBack) {
Storage::disk($disk)->put($fileName, Storage::disk($localDisk)->get($fileName));
Storage::disk($localDisk)->delete($fileName);
}
}
public function localDisk(string $disk)
{
return $this->withMeta(['localDisk' => $disk]);
}
protected function getLocalDisk()
{
return $this->meta['localDisk'] ?? 'local';
}
}
. , config/image-optimizer.php :
php artisan vendor:publish --provider="Spatie\LaravelImageOptimizer\ImageOptimizerServiceProvider"
, .
, readme .
, - . . .
.
Kode sumber untuk proyek tersedia di dan didistribusikan di bawah lisensi MIT.
Paket kemasan
Paket Novapackages