Skip to content

Commit 88c1b9f

Browse files
author
Bradie Tilley
authored
Improve Permalinks
Various improvements, bugfixes and add new 404 image transparency setting
1 parent 1fc71c2 commit 88c1b9f

File tree

7 files changed

+172
-24
lines changed

7 files changed

+172
-24
lines changed

Plugin.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,41 @@ public function registerMarkupTags()
4242
return [
4343
'filters' => [
4444
'resize' => function ($image, $width, $height = null, $options = []) {
45-
$resizer = new Resizer((string) $image);
45+
$resizer = new Resizer();
4646

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

5151
// If the given configuration has a permalink identifier then resize using it
5252
if (isset($options['permalink']) && strlen($options['permalink'])) {
53+
$resizer->preventDefaultImage();
54+
$resizer->setImage((string) $image);
55+
5356
return $resizer->resizePermalink($options['permalink'], $width, $height, $options)->permalink_url;
5457
}
5558

59+
$resizer->setImage((string) $image);
60+
5661
return $resizer->resize($width, $height, $options);
5762
},
5863
'modify' => function ($image, $options = []) {
59-
$resizer = new Resizer((string) $image);
64+
$resizer = new Resizer();
6065

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

6570
// If the given configuration has a permalink identifier then resize using it
6671
if (isset($options['permalink']) && strlen($options['permalink'])) {
72+
$resizer->preventDefaultImage();
73+
$resizer->setImage((string) $image);
74+
6775
return $resizer->resizePermalink($options['permalink'], $width, $height, $options)->permalink_url;
6876
}
6977

78+
$resizer->setImage((string) $image);
79+
7080
return $resizer->resize($width, $height, $options);
7181
},
7282
'filterHtmlImageResize' => function ($html, $width, $height = null, $options = []) {

classes/Resizer.php

Lines changed: 128 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ class Resizer
3131
*/
3232
protected $options = [];
3333

34+
/**
35+
* The list of cacheable options (i.e. those specified, excl defaults)
36+
*
37+
* @var array
38+
*/
39+
protected $cacheableOptions = [];
40+
3441
/**
3542
* The original image resource
3643
*
@@ -66,6 +73,13 @@ class Resizer
6673
*/
6774
protected $formatCache = [];
6875

76+
/**
77+
* Can this Resizer default the image (when the image doesn't exist, for example)
78+
*
79+
* @var boolean
80+
*/
81+
protected $allowDefaultImage = true;
82+
6983
/**
7084
* Construct the resizer class
7185
*
@@ -128,14 +142,18 @@ public function setImage(string $image = null, bool $doNotModifyPath = false)
128142
}
129143
}
130144

145+
// Get the domain
146+
$domain = $_SERVER['SERVER_NAME'] ?? '';
147+
if (empty($domain)) {
148+
$domain = parse_url(url()->to('/'), PHP_URL_HOST);
149+
}
150+
131151
// Check if the image is an absolute url to the same server, if so get the storage path of the image
132-
if (!empty($_SERVER['SERVER_NAME'])) {
133-
$regex = '/^(?:https?:\/\/)?' . $_SERVER['SERVER_NAME'] . '(?::\d+)?\/(.+)$/';
134-
if (preg_match($regex, $image, $m)) {
135-
// Convert spaces, not going to urldecode as it will mess with pluses
136-
$image = base_path(str_replace('%20', ' ', $m[1]));
137-
$absolutePath = true;
138-
}
152+
$regex = '/^(?:https?:\/\/)?' . $domain . '(?::\d+)?\/(.+)$/';
153+
if (preg_match($regex, $image, $m)) {
154+
// Convert spaces, not going to urldecode as it will mess with pluses
155+
$image = base_path(str_replace('%20', ' ', $m[1]));
156+
$absolutePath = true;
139157
}
140158

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

162-
// If the image is invalid, default to Image Not Found
163-
if ($image === null || $image === '' || !file_exists($image)) {
164-
$image = $this->getDefaultImage();
180+
if ($this->allowDefaultImage) {
181+
// If the image is invalid, default to Image Not Found
182+
if ($image === null || $image === '' || !file_exists($image)) {
183+
$image = $this->getDefaultImage();
184+
}
185+
}
186+
187+
return $image;
188+
}
189+
190+
/**
191+
* Get the path to the image (relative path preferred)
192+
*/
193+
public function getImagePathRelativePreferred(): string
194+
{
195+
$image = $this->getImagePath();
196+
$base = rtrim(base_path(), '/');
197+
198+
if (Str::startsWith($image, $base)) {
199+
$image = ltrim(substr($image, strlen($base)), '/');
165200
}
166201

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

190-
// Use the default Image Not Found background, mode and quality
225+
// Use the default Image Not Found background
191226
$this->options['background'] = Settings::get('image_not_found_background', '#fff');
227+
228+
// If the 404 image should be transparent then remove the default background
229+
if (Settings::get('image_not_found_transparent')) {
230+
unset($this->options['background']);
231+
}
232+
233+
// If the 404 image format is not auto then apply this format
234+
$format = Settings::get('image_not_found_format', 'auto');
235+
if ($format !== 'auto') {
236+
$this->options['format'] = $format;
237+
}
238+
239+
// Apply 404 image mode and quality
192240
$this->options['mode'] = Settings::get('image_not_found_mode', 'cover');
193241
$this->options['quality'] = Settings::get('image_not_found_quality', 65);
194242

@@ -236,9 +284,22 @@ public function initResource()
236284
]);
237285

238286
try {
287+
// Default the image if it's a directory
288+
if (is_dir($this->image)) {
289+
throw new \Exception('Image file does not exist (is directory)');
290+
}
291+
292+
// Default the image if it doesn't exist
293+
if (is_dir($this->image)) {
294+
throw new \Exception('Image file does not exist (not found)');
295+
}
296+
239297
$this->im = $this->original = Image::make($this->image);
240298
} catch (\Exception $e) {
241-
$this->im = $this->original = Image::make($this->getDefaultImage());
299+
if ($this->allowDefaultImage) {
300+
$this->setFormatCache([]);
301+
$this->im = $this->original = Image::make($this->image = $this->getDefaultImage());
302+
}
242303
}
243304
}
244305

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

391+
// Don't cache defaults
392+
$this->cacheableOptions = $options;
393+
330394
// Merge defaults and options
331395
$this->options = array_merge($defaults, $options);
332396

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

413+
/**
414+
* Get the options defined in this resizer, excluding defaults
415+
*
416+
* @return array
417+
*/
418+
public function getCacheableOptions(): array
419+
{
420+
return $this->cacheableOptions;
421+
}
422+
349423
/**
350424
* Get the absolute physical path of the image
351425
*
@@ -500,6 +574,9 @@ public function resizePermalink(string $identifier, int $width = null, int $heig
500574
$options['width'] = $width;
501575
$options['height'] = $height;
502576

577+
// Don't need to cache this
578+
unset($options['permalink']);
579+
503580
// Set options, set hash for cache
504581
$this->initOptions($options);
505582

@@ -708,6 +785,30 @@ public function doResize()
708785
return $this;
709786
}
710787

788+
/**
789+
* Prevent the Resizer from defaulting the image
790+
*
791+
* @return $this
792+
*/
793+
public function preventDefaultImage()
794+
{
795+
$this->allowDefaultImage = false;
796+
797+
return $this;
798+
}
799+
800+
/**
801+
* Prevent the Resizer from defaulting the image
802+
*
803+
* @return $this
804+
*/
805+
public function allowDefaultImage()
806+
{
807+
$this->allowDefaultImage = false;
808+
809+
return $this;
810+
}
811+
711812
/**
712813
* Detect format of input file for default export format
713814
*
@@ -731,8 +832,21 @@ public function detectFormat(bool $useNewFormat = false): array
731832
if ($useNewFormat && !empty($this->options['format']) && ($this->options['format'] !== 'auto')) {
732833
$format = $this->options['format'];
733834
} else {
734-
$format = File::mimeType($this->getImagePath());
735-
$format = Str::after($format, '/');
835+
if (File::exists($path = $this->getImagePath())) {
836+
$format = File::mimeType($path);
837+
$format = Str::after($format, '/');
838+
} else {
839+
// If the file doesn't exist then inherit from the new format
840+
$format = $this->options['format'];
841+
// If the new format is automatic, then use the default 404 image format (otherwise jpg)
842+
if ($format === 'auto') {
843+
$format = Settings::get('image_not_found_format', 'auto');
844+
// And lastly, if you have nothing defined you can get a JPG
845+
if ($format === 'auto') {
846+
$format = 'jpg';
847+
}
848+
}
849+
}
736850
}
737851

738852
// For the most part, the mime is the format: image/{format}

commands/ImageResizeResetPermalinks.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace ABWebDevelopers\ImageResize\Commands;
44

5-
use ABWebDevelopers\ImageResize\Classes\Resizer;
65
use ABWebDevelopers\ImageResize\Models\ImagePermalink;
76
use Illuminate\Console\Command;
87
use Illuminate\Support\Str;
@@ -20,6 +19,6 @@ public function handle()
2019
// Delete all permalinks
2120
ImagePermalink::query()->delete();
2221

23-
$this->info('Successfully deleted ' . $deleted . ' ' . Str::plural('permalinks', $deleted));
22+
$this->info('Successfully deleted ' . $deleted . ' ' . Str::plural('permalink', $deleted));
2423
}
2524
}

lang/en/lang.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@
5050
],
5151
'image_not_found_background' => [
5252
'label' => '404 Image Background Color',
53-
'comment' => 'Background color for the image above',
53+
'comment' => 'Background color for the default 404 image',
54+
],
55+
'image_not_found_transparent' => [
56+
'label' => '404 Image Transparent?',
57+
'comment' => 'Should the 404 image be transparent?',
5458
],
5559
'image_not_found_mode' => [
5660
'label' => '404 Image Resize Mode',

models/ImagePermalink.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public function render()
172172
{
173173
$this->resize(); // if not resized
174174

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

208+
$resizer->preventDefaultImage();
208209
$that->identifier = $identifier;
209-
$that->image = $resizer->getImagePath();
210+
$that->image = $resizer->getImagePathRelativePreferred();
210211

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

213214
$that->mime_type = 'image/' . $mime;
214215
$that->extension = $format;
215-
$that->options = $resizer->getOptions();
216+
$that->options = $resizer->getCacheableOptions();
217+
218+
$that->save();
219+
} elseif ($that->resizeExists() === false) {
220+
// In the case where the resize doesn't exist (typically after cache:flush) we want
221+
// to update the image reference as well as options.
222+
$that->image = $resizer->getImagePathRelativePreferred();
223+
224+
list($mime, $format) = $resizer->detectFormat(true);
225+
226+
$that->mime_type = 'image/' . $mime;
227+
$that->extension = $format;
228+
$that->options = $resizer->getCacheableOptions();
216229

217230
$that->save();
218231
}

models/settings/fields.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ tabs:
8484
cover: 'abwebdevelopers.imageresize::lang.settings.fields.mode.options.cover'
8585
stretch: 'abwebdevelopers.imageresize::lang.settings.fields.mode.options.stretch'
8686
default: contain
87+
image_not_found_transparent:
88+
label: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_transparent.label'
89+
comment: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_transparent.comment'
90+
tab: 'abwebdevelopers.imageresize::lang.settings.tabs.main'
91+
span: right
92+
type: checkbox
8793
image_not_found_format:
8894
label: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_format.label'
8995
comment: 'abwebdevelopers.imageresize::lang.settings.fields.image_not_found_format.comment'
@@ -181,4 +187,4 @@ tabs:
181187
comment: 'abwebdevelopers.imageresize::lang.settings.fields.cleanup_on_cache_clear.comment'
182188
tab: 'abwebdevelopers.imageresize::lang.settings.tabs.cache'
183189
span: left
184-
type: checkbox
190+
type: checkbox

updates/version.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,6 @@
4949
2.2.1:
5050
- Fix issue where REMOTE_ADDR server variable is not set when running through CLI
5151
2.2.2:
52-
- Fix MySQL issue where text fields had default values
52+
- Fix MySQL issue where text fields had default values
53+
2.2.3:
54+
- Improvements to Permalinks

0 commit comments

Comments
 (0)