Media library
daravel_medialibrary melekatkan file ke model, seperti
spatie/laravel-medialibrary
v11: satu tabel media untuk semua model, collection, dan konversi gambar
(thumbnail dan preview) yang dibuat dari file asli. Baris dan file mengikuti
layout Spatie, sehingga aplikasi Laravel yang memakai database dan disk yang
sama bisa membaca, menyajikan, dan menghapus media yang ditambahkan Daravel,
begitu pula sebaliknya. Gambar dikonversi dengan Dart murni, tanpa GD atau
ImageMagick di container.
dartisan pub:add media
pub:add menambahkan dependency, .withMediaLibrary(), migration media,
dan command media:*. Setelah itu:
dartisan migrate
dartisan storage:link # menyajikan disk public di /storage
Model#
Model yang memiliki media memakai mixin InteractsWithMedia dan mendaftarkan
MediaObserver, yang menghapus media beserta file-nya bersama model
tersebut. Tambahkan model ke withModels(...) agar konversi di queue bisa
memuatnya.
final class Post extends Model with InteractsWithMedia {
static final ModelDefinition<Post> definition = ModelDefinition<Post>(
table: 'posts',
factory: Post.new,
observers: [MediaObserver<Post>()],
);
@override
ModelDefinition<Post> get modelDefinition => Post.definition;
@override
void registerMediaCollections() {
addMediaCollection('cover').singleFile();
addMediaCollection('attachments')
.acceptsMimeTypes(['application/pdf', 'image/jpeg', 'image/png']);
}
@override
void registerMediaConversions([Media? media]) {
addMediaConversion('thumb').fit(Fit.crop, 300, 200).nonQueued();
addMediaConversion('preview').width(1200).performOnCollections(['cover']);
}
}
Model yang memakai soft delete menyimpan media-nya sampai di-force delete.
post.deletePreservingMedia() menghapus model dan mempertahankan media-nya.
Menambahkan file#
router.post('/posts/{post}/cover', (Request request) async {
final post = (await Post.definition.query().find(request.param<int>('post')))!;
final media = await post
.addMedia((await request.file('cover'))!)
.usingName('Cover')
.withCustomProperties({'alt': 'Pelabuhan saat fajar'})
.toMediaCollection('cover');
return {'url': media.url(), 'thumb': media.url('thumb')};
});
addMediaFromBytes(bytes, fileName: ...), addMediaFromPath(path), dan
addMediaFromDisk(path, disk: ...) menambahkan file dari sumber lain.
toMediaCollection(collection, disk) menyimpan file di disk collection
(useDisk('s3')), atau di MEDIA_DISK bila collection tidak memilih disk.
File ditolak dengan FileCannotBeAdded bila ukurannya melebihi
MEDIA_MAX_FILE_SIZE (10 MiB), bila collection-nya tidak menerimanya, atau
bila salah satu bagian namanya adalah ekstensi yang bisa dijalankan web
server (php, phtml, phar, cgi, jsp, ...; termasuk shell.php.jpg).
Nama file dibersihkan seperti Spatie: karakter kontrol dibuang, spasi serta
#, /, \ diganti -.
Membaca dan menghapus#
final cover = await post.getFirstMediaUrl('cover', 'thumb');
for (final file in await post.getMedia('attachments')) {
print('${file.fileName} (${file.humanReadableSize}) ${file.url()}');
}
await post.clearMediaCollection('attachments');
await post.deleteMedia(mediaId);
Media memiliki name, fileName, mimeType, size, disk,
customProperties (getCustomProperty('alt')), url([conversion]),
path([conversion]) relatif terhadap disk, dan bytes([conversion]).
media.toJson() menambahkan original_url dan preview_url seperti Spatie.
getFirstMediaUrl mengembalikan useFallbackUrl(...) collection, atau '',
saat collection kosong.
Konversi#
Konversi adalah JPEG yang dibuat dari sebuah gambar, bernama
<nama file>-<konversi>.jpg di direktori conversions media tersebut,
sesuai penamaan Spatie. Manipulasi dijalankan sesuai urutan pemanggilannya,
masing-masing pada hasil manipulasi sebelumnya, seperti di Spatie:
| Method | Hasil |
|---|---|
width(w), height(h) |
Lebar atau tinggi tersebut, sisi lain mengikuti rasio aspek; jadi width(200).height(200) me-resize dua kali |
fit(Fit.contain, w, h) |
Di dalam kotak; Fit.max tanpa memperbesar; Fit.fill dan Fit.fillMax lalu mengisi kotak dengan putih |
fit(Fit.crop, w, h) |
Tepat seukuran kotak, dipotong dari tengah |
fit(Fit.stretch, w, h) |
Tepat seukuran kotak, rasio aspek diabaikan |
crop(w, h, CropPosition.top) |
Potongan di posisi tertentu |
quality(85) |
Kualitas JPEG (default 75, seperti GD) |
format(ImageFormat.png), keepOriginalImageFormat() |
PNG, GIF, BMP, atau TIFF sebagai ganti JPEG |
greyscale(), blur(10) |
Filter |
File JPEG, PNG, GIF, WebP, BMP, dan TIFF bisa dikonversi, setelah rotasi
EXIF-nya diterapkan. WebP dan AVIF tidak bisa ditulis: package:image tidak
memiliki encoder untuk keduanya.
Konversi berjalan di queue (PerformConversionsJob, di MEDIA_QUEUE),
kecuali konversi menyatakan nonQueued() atau
QUEUE_CONVERSIONS_BY_DEFAULT=false; di queue sync konversi langsung
berjalan. Pemrosesan gambar sendiri berjalan di isolate terpisah, sehingga
foto besar tidak menahan request lain.
Command#
| Command | Fungsinya |
|---|---|
media:regenerate [modelType] [--ids=1,2] [--only=thumb] [--only-missing] |
Membuat ulang konversi setelah definisinya berubah |
media:clean [--disk] [--dry-run] [--force] |
Menghapus konversi yang tidak lagi didefinisikan model dan direktori media tanpa baris |
Pengaturan#
| Variabel | Default | |
|---|---|---|
MEDIA_DISK |
public |
Disk untuk collection yang tidak memilih disk |
MEDIA_MAX_FILE_SIZE |
10485760 |
Ukuran file terbesar, dalam byte |
MEDIA_QUEUE |
queue default | Queue untuk job konversi |
QUEUE_CONVERSIONS_BY_DEFAULT |
true |
Konversi tanpa nonQueued() dijalankan di queue |
MEDIA_PREFIX |
tidak ada | Direktori di depan setiap direktori media |
MEDIA_VERSION_URLS |
false |
Menambahkan ?v=<updated_at> ke URL |
Media Laravel#
bench/interop/medialibrary.sh menjalankan Laravel 12 dengan
spatie/laravel-medialibrary 11.23 dan Daravel di satu database SQLite dan
satu disk public. Migration Spatie membuat tabelnya; masing-masing membaca
baris, custom property, dan konversi (ukuran sama) dari sisi lain,
menyajikannya di URL yang sama, dan menghapusnya beserta file-nya.
model_type sebuah model adalah morph class-nya (App\Models\Post secara
default, atau alias Relation.morphMap()), sama seperti yang disimpan
Laravel.
Padanan Laravel#
Bagian lain dari Laravel yang ikut didukung, beserta API yang bisa dicari di pub.dev.
| Laravel | Daravel | API | Catatan |
|---|---|---|---|
php artisan media-library:regenerate |
dartisan media:regenerate |
MediaRegenerateCommand |
|
php artisan media-library:clean |
dartisan media:clean |
MediaCleanCommand |