Skip to content

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:

  1. Menyiapkan file — membaca, validasi, generate nama unik
  2. Memproses gambar — kompresi, resize, konversi ke WebP
  3. Upload ke ImageKit CDN untuk pengiriman optimal
  4. 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:

  1. Jika bukan gambar → return as-is
  2. Encode di kualitas awal (default: 80)
  3. Jika ukuran ≤ maxBytes → return
  4. Turunkan kualitas sebesar step (default: 5), encode ulang
  5. 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:

php
$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 CDN

Via 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:

php
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 _idStr::camel(str_replace('_id', '', $value))
    • logo_asset_id → relasi logoAsset()
  • Key string → Str::camel($key)
    • 'banner' => 'banner_asset_id' → relasi banner()

Penggunaan di controller:

php
// 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

php
$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 CDN

File Penting

FileTujuan
app/Services/Asset/ImageKitService.phpOrchestrator utama — prepare, upload, resolve options
app/Services/Asset/CompressService.phpKompresi gambar iteratif
app/Services/Asset/ResizeService.phpResize gambar
app/Services/Asset/ConversionService.phpKonversi WebP
app/Observers/Platform/AssetObserver.phpTrigger otomatis pipeline upload
app/Models/Platform/Asset/Asset.phpModel Eloquent dengan properti uploadedFile