Asset Service
Direktori: app/Services/Asset/
Menangani upload file, kompresi gambar, resize, konversi format, dan upload remote ke ImageKit CDN.
Ringkasan
Ketika user upload file (foto, dokumen, video), Asset service akan:
- Menyiapkan file — membaca, validasi, generate nama unik
- Memproses gambar — kompresi, resize, konversi ke WebP
- Upload ke ImageKit CDN untuk pengiriman optimal
- Menyimpan URL CDN di tabel database
assets
Pipeline: Upload → Kompresi → Resize → Konversi → ImageKit → Database
Kenapa Ada
Tanpa service ini:
- User bisa upload gambar 20MB langsung, memperlambat loading
- Setiap upload file perlu duplikasi logic resize/kompresi
- Tidak ada CDN upload terpusat dengan tracking URL
- Format gambar tidak konsisten (campuran JPEG, PNG, tanpa WebP)
Method
ImageKitService::prepare($file, $options): array
Entry point untuk semua upload. Membaca file, menerapkan opsi, mengembalikan payload yang sudah siap.
Opsi penting: width, height, folder, quality, convert_to_webp, max_file_size_kb, use_unique_file_name, tags.
ImageKitService::upload($contents, $fileName, $options): array
Upload file yang sudah diproses ke ImageKit CDN. Mengembalikan URL CDN, file ID, path, dan thumbnail URL.
CompressService::compress($contents, $mediaType, $quality, $maxBytes, $minimumQuality, $step): string
Kompresi gambar iteratif. Algoritma:
- Jika bukan gambar → return as-is
- Encode di kualitas awal (default: 80)
- Jika ukuran ≤ maxBytes → return
- Turunkan kualitas sebesar
step(default: 5), encode ulang - Ulangi sampai minimum quality tercapai
ResizeService::resize($contents, $mediaType, $width, $height): string
Scale down gambar agar muat dalam dimensi tertentu. Tidak pernah memperbesar.
ConversionService::convertToWebp($contents, $quality): string
Konversi format gambar ke WebP. WebP ~25-35% lebih kecil dari JPEG di kualitas yang sama.
Cara Pakai
Via Asset Model (Rekomendasi)
Model Asset punya properti uploadedFile yang otomatis memicu pipeline via observer:
$asset = new Asset;
$asset->uploadedFile = $request->file('photo');
$asset->uploadOptions = [
'folder' => 'schools/photos',
'use_unique_file_name' => true,
'convert_to_webp' => true,
'width' => 800,
];
$asset->save();
// $asset->path berisi URL CDNVia Trait HasAsset
Untuk model Eloquent yang butuh relasi asset (foto, logo, dokumen, dll), gunakan trait HasAsset. Trait ini otomatis membuat relasi BelongsTo berdasarkan array $assets di model.
Definisi assets di model:
use App\Traits\Common\HasAsset;
class School extends Model
{
use HasAsset;
protected array $assets = [
'logo_asset_id', // otomatis: logoAsset()
'banner' => 'banner_asset_id', // eksplisit: banner()
];
}Konvensi:
- Key numerik + suffix
_id→Str::camel(str_replace('_id', '', $value))logo_asset_id→ relasilogoAsset()
- Key string →
Str::camel($key)'banner' => 'banner_asset_id'→ relasibanner()
Penggunaan di controller:
// Assign asset
$school->logoAsset()->associate($asset);
$school->save();
// Akses URL CDN
$school->logoAsset?->path;
// Dengan fallback
$logoUrl = $school->logoAsset?->path ?? asset('images/default-logo.png');Via Service Langsung
$service = app(ImageKitService::class);
$prepared = $service->prepare($uploadedFile, ['width' => 400, 'convert_to_webp' => true]);
$result = $service->upload($prepared['contents'], $prepared['file_name']);
// $result['url'] adalah URL CDNFile Penting
| File | Tujuan |
|---|---|
app/Services/Asset/ImageKitService.php | Orchestrator utama — prepare, upload, resolve options |
app/Services/Asset/CompressService.php | Kompresi gambar iteratif |
app/Services/Asset/ResizeService.php | Resize gambar |
app/Services/Asset/ConversionService.php | Konversi WebP |
app/Observers/Platform/AssetObserver.php | Trigger otomatis pipeline upload |
app/Models/Platform/Asset/Asset.php | Model Eloquent dengan properti uploadedFile |