From bbec348e604af731e044308f35079675c39a0de9 Mon Sep 17 00:00:00 2001 From: Cassandre Cantet Date: Fri, 27 Nov 2020 23:35:34 +0100 Subject: [PATCH] pass to laravel --- src/Http/Controllers/ImagesController.php | 63 ++++-- src/Model/Image.php | 262 +++++++++++++--------- src/Templates/Custom.php | 24 +- src/Templates/Large.php | 8 +- src/Templates/Medium.php | 4 +- src/Templates/Small.php | 4 +- src/Templates/Thumb.php | 4 +- 7 files changed, 236 insertions(+), 133 deletions(-) diff --git a/src/Http/Controllers/ImagesController.php b/src/Http/Controllers/ImagesController.php index ea4fa0c..d0bd244 100755 --- a/src/Http/Controllers/ImagesController.php +++ b/src/Http/Controllers/ImagesController.php @@ -2,18 +2,29 @@ namespace Meoran\Images\Http\Controllers; +use App\Http\Controllers\Controller; use Closure; +use Illuminate\Contracts\Container\BindingResolutionException; +use Illuminate\Contracts\Foundation\Application; +use Illuminate\Contracts\Routing\ResponseFactory; +use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Intervention\Image\Constraint; -use Intervention\Image\Exception\ImageException; -use Intervention\Image\Exception\NotSupportedException; -use Laravel\Lumen\Routing\Controller as BaseController; +use Illuminate\Http\Response; +use Illuminate\Validation\ValidationException; use Meoran\Images\Model\Image; use Meoran\Images\Templates\Custom; -class ImagesController extends BaseController +/** + * Class ImagesController + * @package Meoran\Images\Http\Controllers + */ +class ImagesController extends Controller { + /** + * @param $filename + * @return Application|ResponseFactory|Response + */ public function get($filename) { $template = app('request')->input('template'); @@ -30,7 +41,12 @@ class ImagesController extends BaseController } } - public function upload(Request $request) + /** + * @param Request $request + * @return JsonResponse + * @throws ValidationException + */ + public function upload(Request $request): JsonResponse { $this->validate($request, [ 'image' => 'required|file|image' @@ -79,6 +95,12 @@ class ImagesController extends BaseController abort(404); } + /** + * @param $template + * @param $filename + * @return Application|ResponseFactory|Response + * @throws BindingResolutionException + */ public function getImage($template, $filename) { $template = $this->getTemplate($template); @@ -97,6 +119,13 @@ class ImagesController extends BaseController return $this->buildResponse($content); } + /** + * @param $template + * @param $path + * @param null $image + * @return mixed + * @throws BindingResolutionException + */ private function applyTemplate($template, $path, $image = null) { if (empty($image)) { @@ -106,12 +135,12 @@ class ImagesController extends BaseController if ($template instanceof Closure) { // build from closure callback template return $template($image->make($path)); - } else { - // build from filter template - $res = $image->make($path)->filter($template); - if ($res === null) { - abort(404); - } + } + + // build from filter template + $res = $image->make($path)->filter($template); + if ($res === null) { + abort(404); } } @@ -140,6 +169,10 @@ class ImagesController extends BaseController } } + /** + * @param $content + * @return Application|ResponseFactory|Response + */ private function buildResponse($content) { // define mime type @@ -155,7 +188,11 @@ class ImagesController extends BaseController )); } - private function getCustomTemplate($templateName) + /** + * @param $templateName + * @return Custom + */ + private function getCustomTemplate($templateName): Custom { $custom = new Custom(); $custom->actions = [$templateName]; diff --git a/src/Model/Image.php b/src/Model/Image.php index 6250f8c..abe7455 100755 --- a/src/Model/Image.php +++ b/src/Model/Image.php @@ -2,48 +2,78 @@ namespace Meoran\Images\Model; +use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphToMany; +use Illuminate\Support\Str; use Intervention\Image\Exception\NotReadableException; use Intervention\Image\Image as InterventionImage; use Meoran\Images\Exception\InvalidContent; +use RuntimeException; use Spatie\ImageOptimizer\OptimizerChain; /** * Class Image * @property InterventionImage $content + * @property string filename + * @property string hash * @package App\Model */ class Image extends Model { - /** - * @var InterventionImage $_content - */ - protected $_content; - - protected $table = 'images'; - + /** @var string[] */ public $fillable = [ 'content', 'filename', 'created_at', - 'updated_at' + 'updated_at', ]; + /** @var InterventionImage */ + protected $_content; + /** @var string */ + protected $table = 'images'; + /** @var string[] */ protected $dates = ['created_at', 'updated_at']; + /** @var string[] */ protected $appends = ['url']; - protected $hidden = []; - public function getUrlAttribute() + /** + * @param string $filename + * @return string + */ + public static function sanitizeFilename(string $filename): string { - $route = config('image.route'); - if (empty($route)) { - return null; - } - return app('url')->to('/' . $route . '/' . $this->filename); + return Str::slug($filename, '-'); } - protected static function boot() + /** + * @param Model $class + * @param $relationName + * @return MorphToMany + */ + public static function createRelation(Model $class, $relationName): MorphToMany + { + $instance = $class->newRelatedInstance(static::class); + $foreignPivotKey = 'relation_id'; + $relatedPivotKey = 'image_id'; + $table = 'associate_images'; + $name = 'relation'; + + $morph = new MorphToMany( + $instance->newQuery(), $class, $name, $table, + $foreignPivotKey, $relatedPivotKey, $class->getKeyName(), + $instance->getKeyName(), $relationName, false + ); + $morph->withPivot('position'); + + return $morph; + } + + /** + * + */ + protected static function boot(): void { parent::boot(); @@ -67,7 +97,56 @@ class Image extends Model } - public function getPath() + protected function savePicture() + { + if (empty($this->content)) { + return true; + } + $this->generateFilename(); + return $this->saveContent(); + } + + /** + * @param boolean $force + */ + public function generateFilename($force = false): void + { + if ($this->filename && !$force) { + return; + } + $this->filename = self::generateRandomFilename(); + } + + /**+ + * @return string + */ + public static function generateRandomFilename(): string + { + return mb_strtolower(Str::random(60)); + } + + /** + * @return InterventionImage + */ + protected function saveContent(): InterventionImage + { + if (empty($this->content)) { + throw new \InvalidArgumentException("Content is Empty"); + } + $path = $this->getPath(); + $dir = dirname($path); + if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) { + throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir)); + } + $res = $this->content->save($path); + app(OptimizerChain::class)->optimize($path); + return $res; + } + + /** + * @return string|null + */ + public function getPath(): ?string { if (empty($this->filename)) { return null; @@ -76,29 +155,48 @@ class Image extends Model return self::getAbsolutePath($this->filename); } - static function getAbsolutePath($filename) + /** + * @param $filename + * @return string + */ + public static function getAbsolutePath($filename): string { $basePath = config('image.path'); if (empty($basePath)) { - throw new \Exception('You must defined config image.path'); + throw new RuntimeException('You must defined config image.path'); } $parts = array_slice(str_split(md5($filename), 2), 0, 2); - $path = $basePath . '/' . implode('/', $parts) . '/' . $filename; - - return $path; + return $basePath . '/' . implode('/', $parts) . '/' . $filename; } - static function generateRandomFilename() + /** + * @return bool + */ + protected function deletePicture(): bool { - return mb_strtolower(str_random(60)); + $path = $this->getPath(); + if (is_file($path)) { + return unlink($path); + } + return true; } - static function sanitizeFilename($filename) + /** + * @return string + */ + public function getUrlAttribute(): ?string { - return str_slug($filename, '-'); + $route = config('image.route'); + if (empty($route)) { + return null; + } + return app('url')->to('/' . $route . '/' . $this->filename); } - public function setFilenameAttribute($value) + /** + * @param string $value + */ + public function setFilenameAttribute(string $value): void { $pattern = '/[^a-z_\-\.0-9]/i'; $patternLetter = '/[a-z0-9]+/i'; @@ -108,25 +206,27 @@ class Image extends Model $this->attributes['filename'] = $value; } - public function fileExist() + /** + * @return bool + */ + public function fileExist(): bool { return is_file($this->getPath()); } - public function generateFilename($force = false) - { - if ($this->filename && !$force) { - return; - } - $this->filename = self::generateRandomFilename(); - } - - public function setContentAttribute($content) + /** + * @param $content + * @throws BindingResolutionException + */ + public function setContentAttribute($content): void { $this->_content = app('image')->make($content)->orientate(); } - public function getHashAttribute() + /** + * @return string|null + */ + public function getHashAttribute(): ?string { if (empty($this->content)) { return null; @@ -137,7 +237,10 @@ class Image extends Model return sha1($this->content->getEncoded()); } - public function getExtensionAttribute() + /** + * @return string|null + */ + public function getExtensionAttribute(): ?string { $mime = $this->content->mime(); if (empty($mime)) { @@ -146,21 +249,33 @@ class Image extends Model return str_replace('image/', '', $mime); } - public function getMimeAttribute() { + /** + * @return string|null + */ + public function getMimeAttribute(): ?string + { if (empty($this->content)) { return null; } return $this->content->mime(); } - public function same(Image $image) + /** + * @param Image $image + * @return bool + */ + public function same(Image $image): bool { $hash1 = $this->hash; $hash2 = $image->hash; return !empty($hash1) && !empty($hash2) && $hash1 === $hash2; } - public function getContentAttribute($value) + /** + * @return InterventionImage|null + * @throws BindingResolutionException + */ + public function getContentAttribute(): ?InterventionImage { if (empty($this->_content)) { try { @@ -172,67 +287,4 @@ class Image extends Model return $this->_content; } - protected function savePicture() - { - if (empty($this->content)) { - return true; - } - $this->generateFilename(); - return $this->saveContent(); - } - - protected function saveContent() - { - if (empty($this->content)) { - throw new \InvalidArgumentException("Content is Empty"); - } - $path = $this->getPath(); - $dir = dirname($path); - if (!is_dir($dir)) { - mkdir($dir, 0775, true); - } - $res = $this->content->save($path); - app(OptimizerChain::class)->optimize($path); - return $res; - } - - protected function deletePicture() - { - $path = $this->getPath(); - if (is_file($path)) { - return unlink($path); - } - return true; - } - - /** - * @param Model $class - * @param $relationName - * @return MorphToMany - */ - public static function createRelation(Model $class, $relationName) - { - $instance = $class->newRelatedInstance(static::class); - $foreignPivotKey = 'relation_id'; - $relatedPivotKey = 'image_id'; - $table = 'associate_images'; - $name = 'relation'; - - $morph = new MorphToMany( - $instance->newQuery(), $class, $name, $table, - $foreignPivotKey, $relatedPivotKey, $class->getKeyName(), - $instance->getKeyName(), $relationName, false - ); - $morph->withPivot('position'); - - return $morph; - } - - public function toArray() - { - $attributes = parent::toArray(); - - return $attributes; - } - } diff --git a/src/Templates/Custom.php b/src/Templates/Custom.php index 443538f..f29c37b 100755 --- a/src/Templates/Custom.php +++ b/src/Templates/Custom.php @@ -7,11 +7,19 @@ use Intervention\Image\Exception\NotSupportedException; use Intervention\Image\Filters\FilterInterface; use Intervention\Image\Image; +/** + * Class Custom + * @package Meoran\Images\Templates + */ class Custom implements FilterInterface { - public $actions = null; + public $actions; - public function applyFilter(Image $image) + /** + * @param Image $image + * @return Image|null + */ + public function applyFilter(Image $image): ?Image { $actions = $this->actions; if ($actions === null) { @@ -31,16 +39,18 @@ class Custom implements FilterInterface if (isset($exploded[1])) { $params = explode(',', $exploded[1]); } - $params[] = function (Constraint $constraint) { + $params[] = static function (Constraint $constraint) { $constraint->upsize(); $constraint->aspectRatio(); }; - $params = array_map(function($el) { - if (is_string($el) && $el === 'null') return null; + $params = array_map(static function($el) { + if (is_string($el) && $el === 'null') { + return null; + } return $el; },$params); try { - call_user_func_array([$image,$methodName], $params); + call_user_func_array([$image, $methodName], $params); } catch (NotSupportedException $exception) { return null; } @@ -48,4 +58,4 @@ class Custom implements FilterInterface return $image; } -} \ No newline at end of file +} diff --git a/src/Templates/Large.php b/src/Templates/Large.php index 27baadd..e8d423c 100755 --- a/src/Templates/Large.php +++ b/src/Templates/Large.php @@ -8,11 +8,15 @@ use Intervention\Image\Image; class Large implements FilterInterface { - public function applyFilter(Image $image) + /** + * @param Image $image + * @return Image + */ + public function applyFilter(Image $image): Image { return $image->resize(1920, null, function (Constraint $constraint) { $constraint->upsize(); $constraint->aspectRatio(); }); } -} \ No newline at end of file +} diff --git a/src/Templates/Medium.php b/src/Templates/Medium.php index 75bb5a4..19effcc 100755 --- a/src/Templates/Medium.php +++ b/src/Templates/Medium.php @@ -8,11 +8,11 @@ use Intervention\Image\Image; class Medium implements FilterInterface { - public function applyFilter(Image $image) + public function applyFilter(Image $image): Image { return $image->resize(960, null, function (Constraint $constraint) { $constraint->upsize(); $constraint->aspectRatio(); }); } -} \ No newline at end of file +} diff --git a/src/Templates/Small.php b/src/Templates/Small.php index 278acc1..c8a8f14 100755 --- a/src/Templates/Small.php +++ b/src/Templates/Small.php @@ -8,11 +8,11 @@ use Intervention\Image\Image; class Small implements FilterInterface { - public function applyFilter(Image $image) + public function applyFilter(Image $image): Image { return $image->resize(480, null, function (Constraint $constraint) { $constraint->upsize(); $constraint->aspectRatio(); }); } -} \ No newline at end of file +} diff --git a/src/Templates/Thumb.php b/src/Templates/Thumb.php index 9f21f5e..aa77b5b 100755 --- a/src/Templates/Thumb.php +++ b/src/Templates/Thumb.php @@ -8,11 +8,11 @@ use Intervention\Image\Image; class Thumb implements FilterInterface { - public function applyFilter(Image $image) + public function applyFilter(Image $image): Image { return $image->resize(120, null, function (Constraint $constraint) { $constraint->upsize(); $constraint->aspectRatio(); }); } -} \ No newline at end of file +}