store/app/Services/Media/MediaService.php

134 lines
3.8 KiB
PHP

<?php
namespace App\Services\Media;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class MediaService
{
/**
* @param list<UploadedFile>|null $newFiles
* @param list<int>|null $removeIds
*/
public function syncCollection(
HasMedia $model,
string $collection,
?array $newFiles,
?array $removeIds,
int $maxFiles,
?string $type = null,
bool $required = false,
?string $errorKey = null,
): void {
$newFiles = array_values(array_filter($newFiles ?? []));
if ($maxFiles === 1 && $newFiles !== []) {
$model->clearMediaCollection($collection);
} elseif ($removeIds !== null && $removeIds !== []) {
$model->getMedia($collection)
->whereIn('id', $removeIds)
->each->delete();
}
if ($maxFiles === 1) {
$newFiles = array_slice($newFiles, 0, 1);
}
$currentCount = $model->getMedia($collection)->count();
if ($currentCount + count($newFiles) > $maxFiles) {
throw ValidationException::withMessages([
$errorKey ?? $collection => "Maksimal {$maxFiles} gambar per item.",
]);
}
foreach ($newFiles as $file) {
$this->addUploadedFile($model, $file, $collection, $type);
}
if ($required && $model->getMedia($collection)->isEmpty()) {
throw ValidationException::withMessages([
$errorKey ?? $collection => 'Foto wajib diisi.',
]);
}
}
public function addUploadedFile(
HasMedia $model,
UploadedFile $file,
string $collection,
?string $type = null,
): Media {
return $model->addMedia($file)
->withCustomProperties($this->customProperties($model, $type ?? $collection))
->toMediaCollection($collection);
}
public function addBase64Image(
HasMedia $model,
string $base64Photo,
string $collection,
?string $type = null,
string $extension = 'jpg',
): Media {
$image = base64_decode(
(string) preg_replace('#^data:image/\w+;base64,#i', '', $base64Photo),
true,
);
if ($image === false) {
throw ValidationException::withMessages([
'photo' => 'Foto tidak valid.',
]);
}
$filename = sprintf('%s.%s', Str::uuid(), $extension);
$tempPath = 'temp/'.$filename;
Storage::disk('local')->put($tempPath, $image);
try {
return $model->addMedia(Storage::disk('local')->path($tempPath))
->usingFileName($filename)
->withCustomProperties($this->customProperties($model, $type ?? $collection))
->toMediaCollection($collection);
} finally {
Storage::disk('local')->delete($tempPath);
}
}
public function replaceSingleFile(
HasMedia $model,
UploadedFile $file,
string $collection,
?string $type = null,
): Media {
$model->clearMediaCollection($collection);
return $this->addUploadedFile($model, $file, $collection, $type);
}
/**
* @return array{module: string, type?: string}
*/
private function customProperties(HasMedia $model, ?string $type): array
{
$properties = [
'module' => method_exists($model, 'mediaModuleName')
? $model::mediaModuleName()
: 'media',
];
if ($type !== null && $type !== '') {
$properties['type'] = $type;
}
return $properties;
}
}