90 lines
3.0 KiB
PHP
90 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\NovaCards;
|
|
|
|
use App\Models\NovaCardBackground;
|
|
use App\Models\User;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Intervention\Image\Encoders\WebpEncoder;
|
|
use Intervention\Image\ImageManager;
|
|
use RuntimeException;
|
|
|
|
class NovaCardBackgroundService
|
|
{
|
|
private ?ImageManager $manager = null;
|
|
|
|
public function __construct()
|
|
{
|
|
try {
|
|
$this->manager = extension_loaded('gd') ? ImageManager::gd() : ImageManager::imagick();
|
|
} catch (\Throwable) {
|
|
$this->manager = null;
|
|
}
|
|
}
|
|
|
|
public function storeUploadedBackground(User $user, UploadedFile $file): NovaCardBackground
|
|
{
|
|
if ($this->manager === null) {
|
|
throw new RuntimeException('Nova card background processing requires Intervention Image.');
|
|
}
|
|
|
|
$sourcePath = $this->resolveUploadPath($file);
|
|
$binary = $this->readUploadedBinary($sourcePath);
|
|
|
|
$uuid = (string) Str::uuid();
|
|
$extension = strtolower($file->getClientOriginalExtension() ?: 'jpg');
|
|
$originalDisk = Storage::disk((string) config('nova_cards.storage.private_disk', 'local'));
|
|
$processedDisk = Storage::disk((string) config('nova_cards.storage.public_disk', 'public'));
|
|
|
|
$originalPath = trim((string) config('nova_cards.storage.background_original_prefix', 'cards/backgrounds/original'), '/')
|
|
. '/' . $user->id . '/' . $uuid . '.' . $extension;
|
|
|
|
$processedPath = trim((string) config('nova_cards.storage.background_processed_prefix', 'cards/backgrounds/processed'), '/')
|
|
. '/' . $user->id . '/' . $uuid . '.webp';
|
|
|
|
$originalDisk->put($originalPath, $binary);
|
|
|
|
$image = $this->manager->read($binary)->scaleDown(width: 2200, height: 2200);
|
|
$encoded = (string) $image->encode(new WebpEncoder(88));
|
|
$processedDisk->put($processedPath, $encoded);
|
|
|
|
return NovaCardBackground::query()->create([
|
|
'user_id' => $user->id,
|
|
'original_path' => $originalPath,
|
|
'processed_path' => $processedPath,
|
|
'width' => $image->width(),
|
|
'height' => $image->height(),
|
|
'mime_type' => (string) ($file->getMimeType() ?: 'image/jpeg'),
|
|
'file_size' => (int) $file->getSize(),
|
|
'sha256' => hash('sha256', $binary),
|
|
'visibility' => 'card-only',
|
|
]);
|
|
}
|
|
|
|
private function resolveUploadPath(UploadedFile $file): string
|
|
{
|
|
$path = $file->getRealPath() ?: $file->getPathname();
|
|
|
|
if (! is_string($path) || trim($path) === '' || ! is_readable($path)) {
|
|
throw new RuntimeException('Unable to resolve uploaded background path.');
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
|
|
private function readUploadedBinary(string $path): string
|
|
{
|
|
$binary = @file_get_contents($path);
|
|
|
|
if ($binary === false || $binary === '') {
|
|
throw new RuntimeException('Unable to read uploaded background image.');
|
|
}
|
|
|
|
return $binary;
|
|
}
|
|
}
|