Membuat Paket Anda Sendiri untuk Laravel Nova: OptimalImage

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:


  1. PHP 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 .


, - . . .


.


Kode sumber untuk proyek tersedia di dan didistribusikan di bawah lisensi MIT.


Paket kemasan


Paket Novapackages


All Articles