-
Notifications
You must be signed in to change notification settings - Fork 2
Refactored Image Generation #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
e47f3e3
c8006a4
d38f10b
db23dc0
225d2c0
a747d72
da3e890
f03ba2a
af16bfa
8aaa8d1
dc29fd8
b1e765e
71394c8
e6e3784
c443f68
55e9d76
ed8218e
88c6c24
51fbafc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
/** | ||
* Because these routes should mimic static files, no middlewares are applied. | ||
*/ | ||
|
||
use Illuminate\Support\Facades\Route; | ||
use JustBetter\GlideDirective\Controllers\ImageController; | ||
|
||
$patterns = [ | ||
'file' => '.*', | ||
'format' => '\..+', | ||
]; | ||
|
||
Route::get('glide-image/placeholder/{file}', [ImageController::class, 'placeholder']) | ||
->where($patterns) | ||
->name('glide-image.placeholder'); | ||
|
||
Route::get('img/'.config('justbetter.glide-directive.storage_prefix', 'storage/glide-image').'/{preset}/{fit}/{s}/{file}{format}', [ImageController::class, 'getImageByPreset']) | ||
kevinmeijer97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
->where($patterns) | ||
->name('glide-image.preset'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
<?php | ||
|
||
namespace JustBetter\GlideDirective\Controllers; | ||
|
||
use Closure; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Http\Response; | ||
use Illuminate\Routing\Controller; | ||
use Illuminate\Support\Facades\Storage; | ||
use Illuminate\Support\Str; | ||
use JustBetter\GlideDirective\Responsive; | ||
use League\Glide\Server; | ||
use League\Glide\Signatures\Signature; | ||
use League\Glide\Signatures\SignatureException; | ||
use Statamic\Assets\Asset; | ||
use Statamic\Contracts\Assets\Asset as AssetContract; | ||
use Statamic\Contracts\Imaging\ImageManipulator; | ||
use Statamic\Facades\Asset as AssetFacade; | ||
use Statamic\Facades\Image; | ||
use Statamic\Imaging\ImageGenerator; | ||
use Symfony\Component\HttpFoundation\BinaryFileResponse; | ||
|
||
class ImageController extends Controller | ||
{ | ||
protected ?AssetContract $asset; | ||
|
||
protected array $params; | ||
|
||
public function __construct(protected ImageGenerator $imageGenerator, protected Server $server) {} | ||
|
||
public function placeholder(Request $request, string $file, string $webp = ''): Response | ||
{ | ||
/** @var ?Asset $asset */ | ||
$asset = AssetFacade::findByUrl(Str::start($file, '/')); | ||
$this->asset = $asset; | ||
|
||
if (! $this->asset) { | ||
abort(404); | ||
} | ||
|
||
$presets = Responsive::getPresets($this->asset); | ||
$base64Image = $presets['placeholder'] ?? ''; | ||
$base64Content = preg_replace('/^data:image\/\w+;base64,/', '', $base64Image); | ||
$imageData = base64_decode($base64Content); | ||
$mimeType = $this->asset->mimeType(); | ||
|
||
return response($imageData) | ||
->header('Content-Type', $mimeType) | ||
->header('Content-Disposition', 'inline'); | ||
} | ||
kevinmeijer97 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
public function getImageByPreset(Request $request, string $preset, string $fit, string $signature, string $file, string $format): BinaryFileResponse | ||
{ | ||
/** @var ?Asset $asset */ | ||
$asset = AssetFacade::findByUrl(Str::start($file, '/')); | ||
$this->asset = $asset; | ||
|
||
$this->params = ['s' => $signature, 'preset' => $preset, 'fit' => $fit, 'format' => $format]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe after merge; We can create a ImageRequest to validate the parameters, now it will probably have an empty string in one of these variables if not filled. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If one of these parameters is not filled it means the given path is not right, which already results in a 404. |
||
|
||
if (! $this->asset) { | ||
abort(404); | ||
} | ||
|
||
try { | ||
$signatureFactory = new Signature(config('app.key')); | ||
$signatureFactory->validateRequest($this->asset->url(), $this->params); | ||
} catch (SignatureException $e) { | ||
abort(404); | ||
} | ||
$path = $this->buildImage(); | ||
$cachePath = config('statamic.assets.image_manipulation.cache_path'); | ||
$publicPath = $cachePath.'/'.$path; | ||
|
||
if (! file_exists($publicPath)) { | ||
abort(404); | ||
} | ||
|
||
$contentType = $this->asset->mimeType(); | ||
|
||
return new BinaryFileResponse($publicPath, 200, [ | ||
'Content-Type' => $contentType, | ||
'Cache-Control' => 'public, max-age=31536000', | ||
]); | ||
} | ||
|
||
protected function buildImage(): ?string | ||
{ | ||
if (! $this->asset) { | ||
return null; | ||
} | ||
|
||
$this->server->setSource(Storage::build(['driver' => 'local', 'root' => public_path()])->getDriver()); | ||
kevinmeijer97 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$this->server->setSourcePathPrefix('/'); | ||
$this->server->setCachePathPrefix(config('justbetter.glide-directive.storage_prefix', 'storage/glide-image').'/'.$this->params['preset'].'/'.$this->params['fit'].'/'.$this->params['s']); | ||
$this->server->setCachePathCallable($this->getCachePathCallable()); | ||
|
||
$path = $this->server->makeImage($this->asset->url(), $this->params); | ||
|
||
return $path; | ||
} | ||
|
||
protected function getCachePathCallable(): ?Closure | ||
{ | ||
$server = $this->server; | ||
$asset = $this->asset; | ||
$params = $this->params; | ||
|
||
if (! $asset) { | ||
return null; | ||
} | ||
|
||
return function () use ($server, $asset, $params) { | ||
return $server->getCachePathPrefix().$asset->url().$params['format']; | ||
}; | ||
} | ||
} |
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.