ORIENT/plugins/abwebdevelopers/imageresize/models/ImagePermalink.php

255 lines
6.5 KiB
PHP
Raw Normal View History

2021-04-08 12:38:39 +00:00
<?php
namespace ABWebDevelopers\ImageResize\Models;
use ABWebDevelopers\ImageResize\Classes\Resizer;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\Eloquent\Builder;
use Model;
class ImagePermalink extends Model
{
public $table = 'abweb_imageresize_permalinks';
/**
* Define cast types for each modifier type
*
* @var array
*/
protected $castModifiers = [
'identifier' => 'string',
'image' => 'string',
'path' => 'string',
];
public $jsonable = [
'options',
];
/**
* When casting this object to string, retrieve the Permalink URL
*
* @return string
*/
public function __toString()
{
return $this->permalink_url;
}
/**
* Set default for options (empty array) and path (empty string) on save
*
* @return void
*/
public function beforeSave()
{
if (is_null($this->options)) {
$this->options = [];
}
if (is_null($this->path)) {
$this->path = '';
}
}
/**
* Get an ImagePermalink class by the given identifier (and provide
* defaults for when not resized yet: width, height, options)
*
* @param string $identifier
* @param string $image
* @param integer $width
* @param integer $height
* @param array $options
* @return ImagePermalink
*/
public static function getPermalink(string $identifier, string $image, int $width = null, int $height = null, array $options = []): ImagePermalink
{
$resizer = new Resizer((string) $image);
$width = ($width !== null) ? (int) $width : null;
$height = ($height !== null) ? (int) $height : null;
$options = ($options instanceof Arrayable) ? $options->toArray() : (array) $options;
return $resizer->resizePermalink($identifier, $width, $height, $options)->permalink_url;
}
/**
* Scope all results by those matching the identifier (should always be only one)
*
* @param Builder $query
* @param string $identifier
* @return void
*/
public function scopeByIdentifier(Builder $query, string $identifier): void
{
$query->where('identifier', $identifier);
}
/**
* Get the Image Permalink with this identifier if it exists
*
* @param string $identifier
* @return ImagePermalink|null
*/
public static function withIdentifer(string $identifier): ?ImagePermalink
{
return static::byIdentifier($identifier)->first();
}
/**
* Does the resized version of this image exist?
*
* @return boolean
*/
public function resizeExists(): bool
{
return !empty($this->path) && file_exists($this->absolute_path);
}
/**
* Generate a short life hash for this file.
* This will be where the image is stored in the storage path
*
* @return string
*/
public function generateShortLifeHash(): string
{
return hash('sha256', $this->identifier . ':permalink:' . json_encode($this->options));
}
/**
* Resize the image, if not already resized
*
* @return void
*/
public function resize()
{
if ($this->resizeExists() === false) {
$config = $this->options ?? [];
$resizer = Resizer::using($this->image)
->setHash($hash = $this->generateShortLifeHash())
->setOptions($config)
->doResize();
$path = $resizer->getRelativePath();
$this->path = $path;
$this->resized_at = now();
$this->save();
}
return $this;
}
/**
* Get the absolute path to the resized image
*
* @return string
*/
public function getAbsolutePathAttribute(): string
{
return base_path($this->path);
}
/**
* Get the permalink URL for this image
*
* @return string
*/
public function getPermalinkUrlAttribute(): string
{
return url('/imageresizestatic/' . $this->identifier . '.' . $this->extension);
}
/**
* If the resized copy of this image exists, delete it.
*
* @return $this
*/
public function deleteResize()
{
if ($this->resizeExists()) {
unlink($this->absolute_path);
}
$this->path = null;
return $this;
}
/**
* Render this image to screen, now.
*
* @return void
*/
public function render()
{
$this->resize(); // if not resized
header('Content-Type: ' . $this->mime_type);
header('Content-Length: ' . filesize($this->absolute_path));
echo file_get_contents($this->absolute_path);
exit();
}
/**
* Get a default 404 image not found mock permalink
*
* @return ImagePermalink
*/
public static function defaultNotFound(): ImagePermalink
{
$identifier = '404';
$resizer = Resizer::using('');
return static::fromResizer($identifier, $resizer);
}
/**
* Initialise an ImagePermalink from the given Resizer instance
*
* @param string $identifier
* @param Resizer $resizer
* @return ImagePermalink
*/
public static function fromResizer(string $identifier, Resizer $resizer): ImagePermalink
{
$that = static::withIdentifer($identifier);
if ($that === null) {
$that = new static();
$resizer->preventDefaultImage();
$that->identifier = $identifier;
$that->image = $resizer->getImagePathRelativePreferred();
list($mime, $format) = $resizer->detectFormat(true);
$that->mime_type = 'image/' . $mime;
$that->extension = $format;
$that->options = $resizer->getCacheableOptions();
$that->save();
} elseif (($that->resizeExists() === false) || empty($that->image)) {
// In the case where the resize doesn't exist (typically after cache:flush) we want
// to update the image reference as well as options.
$that->image = $resizer->getImagePathRelativePreferred();
// If resize exists, delete the resized copy
$that->deleteResize();
list($mime, $format) = $resizer->detectFormat(true);
$that->mime_type = 'image/' . $mime;
$that->extension = $format;
$that->options = $resizer->getCacheableOptions();
$that->save();
}
return $that;
}
}