أثناء العمل على مشروع جديد تستخدمه Laravel Nova لإدارته ، اختبرته باستخدام أدوات مشرفي المواقع من Google. اتضح أن بعض الصور على المورد لم يتم تحسينها - يمكن تقليل حجمها بشكل كبير. يمكن معالجة تلك الموجودة في المشروع عند بناء المشروع باستخدام node.js. هناك العديد من الحزم الجاهزة لهذا الغرض. لا يزال هناك صور تم تحميلها من قبل المستخدم مباشرة من لوحة إدارة الموقع. بالطبع ، يمكنك تحسين كل صورة قبل تحميلها على الموقع ، ولكن لماذا لا تجعل هذا الإجراء تلقائيًا. لذلك ولدت الفكرة لتقديم حزمة لارافيل نوفا: OptimalImage.
الحزمة بسيطة للغاية ، وبالتالي لا تدعي أنها دليل كامل لإنشاء حزم لـ Laravel Nova. لا يعالج موضوعًا شاملاً إلى حد ما بشأن العمل مع المكون المرئي للمكونات. إذا ظهرت فكرة مثيرة للاهتمام عن مكون ، مع مكون مرئي - سأكتب مقالًا حول هذا الموضوع.
صياغة المشكلة
تريد إنشاء حزمة تضيف حقلاً جديدًا. سيختلف هذا الحقل عن
الحقل المعتاد مع تحميل الصورة حيث سيتم إجراء التحسين للصورة المحملة.
تركيب وتكوين البيئة.
لتكرار جميع الخطوات في هذا الدليل ، ستحتاج إلى مشروع مع Laravel و Laravel Nova. Laravel Nova هي أداة مدفوعة ، ولكن في رأيي ، سعرها في متناول الجميع.
كنت في العمل:
- 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 .
, - . . .
.
الكود المصدري للمشروع متاح وموزع تحت رخصة MIT.
حزمة Packagist
حزمة Novapackages