jqh 5 лет назад
Родитель
Сommit
fa1e490f00
3 измененных файлов с 181 добавлено и 0 удалено
  1. 14 0
      src/Form/Field/Image.php
  2. 115 0
      src/Form/Field/ImageField.php
  3. 52 0
      src/Traits/Resizable.php

+ 14 - 0
src/Form/Field/Image.php

@@ -119,6 +119,20 @@ class Image extends File
     protected function prepareFile(UploadedFile $file)
     {
         $this->callInterventionMethods($file->getRealPath(), $file->getMimeType());
+
+        $this->uploadAndDeleteOriginalThumbnail($file);
+    }
+
+    /**
+     * Destroy original files.
+     *
+     * @return void.
+     */
+    public function destroy()
+    {
+        parent::destroy();
+
+        $this->destroyThumbnail();
     }
 
 }

+ 115 - 0
src/Form/Field/ImageField.php

@@ -2,7 +2,11 @@
 
 namespace Dcat\Admin\Form\Field;
 
+use Illuminate\Support\Str;
 use Intervention\Image\ImageManagerStatic;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+use Intervention\Image\Constraint;
+use Intervention\Image\Facades\Image as InterventionImage;
 
 trait ImageField
 {
@@ -13,6 +17,13 @@ trait ImageField
      */
     protected $interventionCalls = [];
 
+    /**
+     * Thumbnail settings.
+     *
+     * @var array
+     */
+    protected $thumbnails = [];
+
     protected static $interventionAlias = [
         'filling' => 'fill'
     ];
@@ -80,4 +91,108 @@ trait ImageField
         return $this;
     }
 
+    /**
+     * @param string|array $name
+     * @param int          $width
+     * @param int          $height
+     *
+     * @return $this
+     */
+    public function thumbnail($name, int $width = null, int $height = null)
+    {
+        if (func_num_args() == 1 && is_array($name)) {
+            foreach ($name as $key => $size) {
+                if (count($size) >= 2) {
+                    $this->thumbnails[$key] = $size;
+                }
+            }
+        } elseif (func_num_args() == 3) {
+            $this->thumbnails[$name] = [$width, $height];
+        }
+
+        return $this;
+    }
+
+    /**
+     * Destroy original thumbnail files.
+     *
+     * @param string|array $file
+     * @param bool $force
+     *
+     * @return void.
+     */
+    public function destroyThumbnail($file = null, bool $force = false)
+    {
+        if ($this->retainable && ! $force) {
+            return;
+        }
+
+        $file = $file ?: $this->original;
+        if (! $file) {
+            return;
+        }
+
+        if (is_array($file)) {
+            foreach ($file as $f) {
+                $this->destroyThumbnail($f);
+            }
+            return;
+        }
+
+        foreach ($this->thumbnails as $name => $_) {
+            // We need to get extension type ( .jpeg , .png ...)
+            $ext = pathinfo($file, PATHINFO_EXTENSION);
+
+            // We remove extension from file name so we can append thumbnail type
+            $path = Str::replaceLast('.'.$ext, '', $file);
+
+            // We merge original name + thumbnail name + extension
+            $path = $path.'-'.$name.'.'.$ext;
+
+            if ($this->storage->exists($path)) {
+                $this->storage->delete($path);
+            }
+        }
+    }
+
+    /**
+     * Upload file and delete original thumbnail files.
+     *
+     * @param UploadedFile $file
+     *
+     * @return $this
+     */
+    protected function uploadAndDeleteOriginalThumbnail(UploadedFile $file)
+    {
+        foreach ($this->thumbnails as $name => $size) {
+            // We need to get extension type ( .jpeg , .png ...)
+            $ext = pathinfo($this->name, PATHINFO_EXTENSION);
+
+            // We remove extension from file name so we can append thumbnail type
+            $path = Str::replaceLast('.'.$ext, '', $this->name);
+
+            // We merge original name + thumbnail name + extension
+            $path = $path.'-'.$name.'.'.$ext;
+
+            /** @var \Intervention\Image\Image $image */
+            $image = InterventionImage::make($file);
+
+            $action = $size[2] ?? 'resize';
+            // Resize image with aspect ratio
+            $image->$action($size[0], $size[1], function (Constraint $constraint) {
+                $constraint->aspectRatio();
+            });
+
+            if (!is_null($this->storagePermission)) {
+                $this->storage->put("{$this->getDirectory()}/{$path}", $image->encode(), $this->storagePermission);
+            } else {
+                $this->storage->put("{$this->getDirectory()}/{$path}", $image->encode());
+            }
+        }
+
+        $this->destroyThumbnail();
+
+        return $this;
+    }
+
 }

+ 52 - 0
src/Traits/Resizable.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace Dcat\Admin\Traits;
+
+use Illuminate\Support\Facades\Storage;
+use Illuminate\Support\Str;
+
+trait Resizable
+{
+    /**
+     * Method for returning specific thumbnail for model.
+     *
+     * @param string $type
+     * @param string $attribute
+     *
+     * @return string|null
+     */
+    public function thumbnail($type, $attribute = 'image', $disk = null)
+    {
+        // Return empty string if the field not found
+        if (!isset($this->attributes[$attribute])) {
+            return '';
+        }
+
+        // We take image from posts field
+        $image = $this->attributes[$attribute];
+
+        $thumbnail = $this->getThumbnailPath($image, $type);
+
+        return Storage::disk($disk ?: config('admin.upload.disk'))->exists($thumbnail) ? $thumbnail : null;
+    }
+
+    /**
+     * Generate thumbnail URL.
+     *
+     * @param $image
+     * @param $type
+     *
+     * @return string
+     */
+    public function getThumbnailPath($image, $type)
+    {
+        // We need to get extension type ( .jpeg , .png ...)
+        $ext = pathinfo($image, PATHINFO_EXTENSION);
+
+        // We remove extension from file name so we can append thumbnail type
+        $name = Str::replaceLast('.'.$ext, '', $image);
+
+        // We merge original name + type + extension
+        return $name.'-'.$type.'.'.$ext;
+    }
+}