134 lines
3.8 KiB
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;
|
|
}
|
|
}
|