255 lines
6.5 KiB
PHP
255 lines
6.5 KiB
PHP
|
|
<?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;
|
||
|
|
}
|
||
|
|
}
|