إنشاء الحزمة الخاصة بك ل Laravel Nova: OptimalImage

أثناء العمل على مشروع جديد تستخدمه Laravel Nova لإدارته ، اختبرته باستخدام أدوات مشرفي المواقع من Google. اتضح أن بعض الصور على المورد لم يتم تحسينها - يمكن تقليل حجمها بشكل كبير. يمكن معالجة تلك الموجودة في المشروع عند بناء المشروع باستخدام node.js. هناك العديد من الحزم الجاهزة لهذا الغرض. لا يزال هناك صور تم تحميلها من قبل المستخدم مباشرة من لوحة إدارة الموقع. بالطبع ، يمكنك تحسين كل صورة قبل تحميلها على الموقع ، ولكن لماذا لا تجعل هذا الإجراء تلقائيًا. لذلك ولدت الفكرة لتقديم حزمة لارافيل نوفا: OptimalImage.


الحزمة بسيطة للغاية ، وبالتالي لا تدعي أنها دليل كامل لإنشاء حزم لـ Laravel Nova. لا يعالج موضوعًا شاملاً إلى حد ما بشأن العمل مع المكون المرئي للمكونات. إذا ظهرت فكرة مثيرة للاهتمام عن مكون ، مع مكون مرئي - سأكتب مقالًا حول هذا الموضوع.


صياغة المشكلة


تريد إنشاء حزمة تضيف حقلاً جديدًا. سيختلف هذا الحقل عن
الحقل المعتاد مع تحميل الصورة حيث سيتم إجراء التحسين للصورة المحملة.


تركيب وتكوين البيئة.


لتكرار جميع الخطوات في هذا الدليل ، ستحتاج إلى مشروع مع Laravel و Laravel Nova. Laravel Nova هي أداة مدفوعة ، ولكن في رأيي ، سعرها في متناول الجميع.


كنت في العمل:


  1. 7.3.16 بيزو فلبيني
  2. Laravel 7
  3. 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;

/**
 *       Image.  ,    
 *   ,      .
 *
 * Class OptimalImage
 * @package Yarbala\OptimalImage
 */
class OptimalImage extends Image
{
    /**
     *        Image 'Fields/File.php'.     
     *    optimizeImage  .
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $requestAttribute
     * @return string
     */
    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;
    }

    /**
     *    
     *
     * @param $fileName
     * @throws FileNotFoundException
     */
    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;

/**
 *       Image.  ,    
 *   ,      .
 *
 * Class OptimalImage
 * @package Yarbala\OptimalImage
 */
class OptimalImage extends Image
{
    // ...

    /**
     *    
     *
     * @param $fileName
     * @throws FileNotFoundException
     */
    protected function optimizeImage($fileName)
    {
        $needsUploadBack = false;
        $localDisk = 'local';
        $disk = $this->getStorageDisk();

        /*         Storage,  Spatie\ImageOptimizer    
                    
        */
        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;

/**
 *       Image.  ,    
 *   ,      .
 *
 * Class OptimalImage
 * @package Yarbala\OptimalImage
 */
class OptimalImage extends Image
{
    /**
     *        Image 'Fields/File.php'.     
     *      optimizeImage  .
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $requestAttribute
     * @return string
     */
    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;
    }

    /**
     *    
     *
     * @param $fileName
     * @throws FileNotFoundException
     */
    protected function optimizeImage($fileName)
    {
        $needsUploadBack = false;
        $localDisk = $this->getLocalDisk();
        $disk = $this->getStorageDisk();

        /*         Storage,  Spatie\ImageOptimizer    
                    
        */
        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);
        }
    }

    /**
     *      
     *
     * @param string $disk
     * @return OptimalImage
     */
    public function localDisk(string $disk)
    {
        return $this->withMeta(['localDisk' => $disk]);
    }

    /**
     *   
     * 
     * @return string
     */
    protected function getLocalDisk()
    {
        return $this->meta['localDisk'] ?? 'local';
    }
}

. , config/image-optimizer.php :


php artisan vendor:publish --provider="Spatie\LaravelImageOptimizer\ImageOptimizerServiceProvider"

, .


, readme .


, - . . .


.


الكود المصدري للمشروع متاح وموزع تحت رخصة MIT.


حزمة Packagist


حزمة Novapackages


All Articles