Skip to content

Commit

Permalink
Improve Permalinks
Browse files Browse the repository at this point in the history
Various improvements, bugfixes and add new 404 image transparency setting
  • Loading branch information
Bradie Tilley authored Nov 18, 2020
1 parent 1fc71c2 commit 88c1b9f
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 24 deletions.
14 changes: 12 additions & 2 deletions Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,41 @@ public function registerMarkupTags()
return [
'filters' => [
'resize' => function ($image, $width, $height = null, $options = []) {
$resizer = new Resizer((string) $image);
$resizer = new Resizer();

$width = ($width !== null) ? (int) $width : null;
$height = ($height !== null) ? (int) $height : null;
$options = ($options instanceof Arrayable) ? $options->toArray() : (array) $options;

// If the given configuration has a permalink identifier then resize using it
if (isset($options['permalink']) && strlen($options['permalink'])) {
$resizer->preventDefaultImage();
$resizer->setImage((string) $image);

return $resizer->resizePermalink($options['permalink'], $width, $height, $options)->permalink_url;
}

$resizer->setImage((string) $image);

return $resizer->resize($width, $height, $options);
},
'modify' => function ($image, $options = []) {
$resizer = new Resizer((string) $image);
$resizer = new Resizer();

$width = null;
$height = null;
$options = ($options instanceof Arrayable) ? $options->toArray() : (array) $options;

// If the given configuration has a permalink identifier then resize using it
if (isset($options['permalink']) && strlen($options['permalink'])) {
$resizer->preventDefaultImage();
$resizer->setImage((string) $image);

return $resizer->resizePermalink($options['permalink'], $width, $height, $options)->permalink_url;
}

$resizer->setImage((string) $image);

return $resizer->resize($width, $height, $options);
},
'filterHtmlImageResize' => function ($html, $width, $height = null, $options = []) {
Expand Down
142 changes: 128 additions & 14 deletions classes/Resizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ class Resizer
*/
protected $options = [];

/**
* The list of cacheable options (i.e. those specified, excl defaults)
*
* @var array
*/
protected $cacheableOptions = [];

/**
* The original image resource
*
Expand Down Expand Up @@ -66,6 +73,13 @@ class Resizer
*/
protected $formatCache = [];

/**
* Can this Resizer default the image (when the image doesn't exist, for example)
*
* @var boolean
*/
protected $allowDefaultImage = true;

/**
* Construct the resizer class
*
Expand Down Expand Up @@ -128,14 +142,18 @@ public function setImage(string $image = null, bool $doNotModifyPath = false)
}
}

// Get the domain
$domain = $_SERVER['SERVER_NAME'] ?? '';
if (empty($domain)) {
$domain = parse_url(url()->to('/'), PHP_URL_HOST);
}

// Check if the image is an absolute url to the same server, if so get the storage path of the image
if (!empty($_SERVER['SERVER_NAME'])) {
$regex = '/^(?:https?:\/\/)?' . $_SERVER['SERVER_NAME'] . '(?::\d+)?\/(.+)$/';
if (preg_match($regex, $image, $m)) {
// Convert spaces, not going to urldecode as it will mess with pluses
$image = base_path(str_replace('%20', ' ', $m[1]));
$absolutePath = true;
}
$regex = '/^(?:https?:\/\/)?' . $domain . '(?::\d+)?\/(.+)$/';
if (preg_match($regex, $image, $m)) {
// Convert spaces, not going to urldecode as it will mess with pluses
$image = base_path(str_replace('%20', ' ', $m[1]));
$absolutePath = true;
}

// If not an absolute path, set it to an absolute path
Expand All @@ -159,9 +177,26 @@ public function getImagePath(): string
{
$image = $this->image;

// If the image is invalid, default to Image Not Found
if ($image === null || $image === '' || !file_exists($image)) {
$image = $this->getDefaultImage();
if ($this->allowDefaultImage) {
// If the image is invalid, default to Image Not Found
if ($image === null || $image === '' || !file_exists($image)) {
$image = $this->getDefaultImage();
}
}

return $image;
}

/**
* Get the path to the image (relative path preferred)
*/
public function getImagePathRelativePreferred(): string
{
$image = $this->getImagePath();
$base = rtrim(base_path(), '/');

if (Str::startsWith($image, $base)) {
$image = ltrim(substr($image, strlen($base)), '/');
}

return $image;
Expand All @@ -187,8 +222,21 @@ protected function getDefaultImage(): string
$image = Settings::getDefaultImageNotFound(true);
}

// Use the default Image Not Found background, mode and quality
// Use the default Image Not Found background
$this->options['background'] = Settings::get('image_not_found_background', '#fff');

// If the 404 image should be transparent then remove the default background
if (Settings::get('image_not_found_transparent')) {
unset($this->options['background']);
}

// If the 404 image format is not auto then apply this format
$format = Settings::get('image_not_found_format', 'auto');
if ($format !== 'auto') {
$this->options['format'] = $format;
}

// Apply 404 image mode and quality
$this->options['mode'] = Settings::get('image_not_found_mode', 'cover');
$this->options['quality'] = Settings::get('image_not_found_quality', 65);

Expand Down Expand Up @@ -236,9 +284,22 @@ public function initResource()
]);

try {
// Default the image if it's a directory
if (is_dir($this->image)) {
throw new \Exception('Image file does not exist (is directory)');
}

// Default the image if it doesn't exist
if (is_dir($this->image)) {
throw new \Exception('Image file does not exist (not found)');
}

$this->im = $this->original = Image::make($this->image);
} catch (\Exception $e) {
$this->im = $this->original = Image::make($this->getDefaultImage());
if ($this->allowDefaultImage) {
$this->setFormatCache([]);
$this->im = $this->original = Image::make($this->image = $this->getDefaultImage());
}
}
}

Expand Down Expand Up @@ -327,6 +388,9 @@ private function initOptions(array $options = null)
'format' => Settings::get('format'),
];

// Don't cache defaults
$this->cacheableOptions = $options;

// Merge defaults and options
$this->options = array_merge($defaults, $options);

Expand All @@ -346,6 +410,16 @@ public function getOptions(): array
return $this->options;
}

/**
* Get the options defined in this resizer, excluding defaults
*
* @return array
*/
public function getCacheableOptions(): array
{
return $this->cacheableOptions;
}

/**
* Get the absolute physical path of the image
*
Expand Down Expand Up @@ -500,6 +574,9 @@ public function resizePermalink(string $identifier, int $width = null, int $heig
$options['width'] = $width;
$options['height'] = $height;

// Don't need to cache this
unset($options['permalink']);

// Set options, set hash for cache
$this->initOptions($options);

Expand Down Expand Up @@ -708,6 +785,30 @@ public function doResize()
return $this;
}

/**
* Prevent the Resizer from defaulting the image
*
* @return $this
*/
public function preventDefaultImage()
{
$this->allowDefaultImage = false;

return $this;
}

/**
* Prevent the Resizer from defaulting the image
*
* @return $this
*/
public function allowDefaultImage()
{
$this->allowDefaultImage = false;

return $this;
}

/**
* Detect format of input file for default export format
*
Expand All @@ -731,8 +832,21 @@ public function detectFormat(bool $useNewFormat = false): array
if ($useNewFormat && !empty($this->options['format']) && ($this->options['format'] !== 'auto')) {
$format = $this->options['format'];
} else {
$format = File::mimeType($this->getImagePath());
$format = Str::after($format, '/');
if (File::exists($path = $this->getImagePath())) {
$format = File::mimeType($path);
$format = Str::after($format, '/');
} else {
// If the file doesn't exist then inherit from the new format
$format = $this->options['format'];
// If the new format is automatic, then use the default 404 image format (otherwise jpg)
if ($format === 'auto') {
$format = Settings::get('image_not_found_format', 'auto');
// And lastly, if you have nothing defined you can get a JPG
if ($format === 'auto') {
$format = 'jpg';
}
}
}
}

// For the most part, the mime is the format: image/{format}
Expand Down
3 changes: 1 addition & 2 deletions commands/ImageResizeResetPermalinks.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace ABWebDevelopers\ImageResize\Commands;

use ABWebDevelopers\ImageResize\Classes\Resizer;
use ABWebDevelopers\ImageResize\Models\ImagePermalink;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
Expand All @@ -20,6 +19,6 @@ public function handle()
// Delete all permalinks
ImagePermalink::query()->delete();

$this->info('Successfully deleted ' . $deleted . ' ' . Str::plural('permalinks', $deleted));
$this->info('Successfully deleted ' . $deleted . ' ' . Str::plural('permalink', $deleted));
}
}
6 changes: 5 additions & 1 deletion lang/en/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@
],
'image_not_found_background' => [
'label' => '404 Image Background Color',
'comment' => 'Background color for the image above',
'comment' => 'Background color for the default 404 image',
],
'image_not_found_transparent' => [
'label' => '404 Image Transparent?',
'comment' => 'Should the 404 image be transparent?',
],
'image_not_found_mode' => [
'label' => '404 Image Resize Mode',
Expand Down
19 changes: 16 additions & 3 deletions models/ImagePermalink.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public function render()
{
$this->resize(); // if not resized

header('Content-Type: ' . $this->mime);
header('Content-Type: ' . $this->mime_type);
header('Content-Length: ' . filesize($this->absolute_path));
echo file_get_contents($this->absolute_path);
exit();
Expand Down Expand Up @@ -205,14 +205,27 @@ public static function fromResizer(string $identifier, Resizer $resizer): ImageP
if ($that === null) {
$that = new static();

$resizer->preventDefaultImage();
$that->identifier = $identifier;
$that->image = $resizer->getImagePath();
$that->image = $resizer->getImagePathRelativePreferred();

list($mime, $format) = $resizer->detectFormat(true);

$that->mime_type = 'image/' . $mime;
$that->extension = $format;
$that->options = $resizer->getOptions();
$that->options = $resizer->getCacheableOptions();

$that->save();
} elseif ($that->resizeExists() === false) {
// 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();

list($mime, $format) = $resizer->detectFormat(true);

$that->mime_type = 'image/' . $mime;
$that->extension = $format;
$that->options = $resizer->getCacheableOptions();

$that->save();
}
Expand Down
8 changes: 7 additions & 1 deletion models/settings/fields.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ tabs:
cover: 'abwebdevelopers.imageresize::lang.settings.fields.mode.options.cover'
stretch: 'abwebdevelopers.imageresize::lang.settings.fields.mode.options.stretch'
default: contain
image_not_found_transparent:
label: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_transparent.label'
comment: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_transparent.comment'
tab: 'abwebdevelopers.imageresize::lang.settings.tabs.main'
span: right
type: checkbox
image_not_found_format:
label: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_format.label'
comment: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_format.comment'
Expand Down Expand Up @@ -181,4 +187,4 @@ tabs:
comment: 'abwebdevelopers.imageresize::lang.settings.fields.cleanup_on_cache_clear.comment'
tab: 'abwebdevelopers.imageresize::lang.settings.tabs.cache'
span: left
type: checkbox
type: checkbox
4 changes: 3 additions & 1 deletion updates/version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@
2.2.1:
- Fix issue where REMOTE_ADDR server variable is not set when running through CLI
2.2.2:
- Fix MySQL issue where text fields had default values
- Fix MySQL issue where text fields had default values
2.2.3:
- Improvements to Permalinks

0 comments on commit 88c1b9f

Please sign in to comment.