Upload
Adalah module yang bertugas menangani file upload. Secara default
semua file upload disimpan di folder media
. Ada juga opsi untuk
menyimpan file upload tersebut di ftp atau aws. Sebagai catatan,
ketika md5 suatu file sudah pernah ada di server, maka proses upload
akan di batalkan, dan akan mengembalikan informasi file yang sudah
pernah di upload sebelumnya.
Instalasi
Jalankan perintah di bawah di folder aplikasi:
mim app install lib-upload
Konfigurasi
Silahkan tambahkan konfigurasi seperti di bawah pada konfigurasi module atau aplikasi:
return [
// ...
'libUpload' => [
'filter' => [
// find file hanya dari file yang diupload oleh
// user bersangkutan
'own' => false
],
'base' => [
'local' => 'media', // folder dimana file upload disimpan
'host' => 'http://site.mim/media/'
],
'forms' => [
'my-upload' => [
'size' => [ // in byte
'min' => 0,
'max' => 233112
],
'mime' => [
'*/*', // accept all
'image/*', // accept all image
'text/plain' // accept mime type text/plain
],
'exts' => [
'*',
'jpg',
'txt'
],
'image' => [ // for image file upload only
'width' => [ // in pixel
'min' => 10,
'max' => 1024
],
'height' => [ // in pixel
'min' => 10,
'max' => 1024
]
],
// use only this keepr to store the file
'keeper' => ['/name/']
]
]
]
// ...
];
Sebagai catatan, module ini sudah mendaftarkan form upload dengan nama std-image
untuk
menerima semua image, dan std-audio
untuk menerima semua file audio.
Custom Keeper
Selain menyimpan file di folder ./media
, developer bisa juga membuatkan
metode penyimpanan lain seperti ftp atau aws. Untuk itu, buatkan class
yang mengimplementasikan interface LibUpload\Iface\Keeper
yang memiliki
static method sebagai berikut:
getId(string $file): ?string
Fungsi yang akan dipanggil oleh system untuk mendapatkan id suatu file berdasarkan full-url dari file tersebut. Fungsi ini diharapkan mengembalikan null jika keeper tidak mengenali file, atau string file id jika diketahui.
lastError(): ?string
Mengambil informasi error terakhir.
save(object $file): ?string
Method yang akan dipanggil ketika suatu file berhasil di upload dan sudah melewati proses verifikasi rules. Method ini adalah static method yang akan dipanggil dengan parameter sebagai berikuta:
$file = (object)[
// original file name
'name' => 'filename.jpg',
// file mime type
'type' => 'image/jpg',
// file size
'size' => 21975,
// soure file to upload
'source' => '/tmp/file-source',
// target file where to put
'target' => 'aa/bb/cc/filename.jpg'
];
Fungsi ini diharapkan mengembalikan nilai string
final URL file jika berhasil, dan null
jika
gagal.
Implementasi Keeper
Untuk implementasinya, silahkan mengacup pada file keeper LibUpload\Keeper\Local
.
Tambahkan juga konfigurasi seperti di bawah pada konfigurasi module agar module ini tahu keberadaan keeper tersebut:
return [
// ...
'libUpload' => [
'keeper' => [
'handlers' => [
'my-keeper' => [
'class' => 'LibMyKeeper\\Library\\MyKeeper',
'use' => true
]
]
]
]
// ...
];
Ketika event upload terjadi, semua handlers
yang terdaftar dengan
properti use
adalah true
akan di panggil. Jadi jika ada 5 keeper
terdaftar dan semuanya adalah use => true
, maka file upload user
tersebut akan disimpan oleh 5 keeper. Kecuali jika form upload mendefinisikan
keeper yang akan digunakan, maka rule use
tidak digunakan.
FrontEnd
Ketika melakukan upload file dari front-end. Pastikan mengirim dua parameter sebagai berikut:
file
File objectform
Form name
Dalam bentuk html, maka bentuk di atas adalah sebagai berikut:
<form method="POST" enctype="multipart/form-data" action="<?= $this->router->to('apiUpload') ?>">
<input type="file" name="file">
<input type="hidden" name="form" value="my-form">
<button>Upload</button>
</form>
Endpoint upload menggunakan route dengan nama apiUpload
dan melalui gate api
. Nilai
yang dikembalikan dari endpoint ini adalah sebagai berikut:
{
"error":0,
"message":"OK",
"data":{
"url":"/media/d4/7d/e0/3e/d47de03e7b5b7040d11fc8bfa5203271.jpg",
"path":"d4/7d/e0/3e/d47de03e7b5b7040d11fc8bfa5203271.jpg",
"name":"Nature-Beach-Scenery-Wallpaper-HD.jpg",
"type":"image/jpeg",
"size":446517
}
}
Filter
Route apiUploadFilter
atau url /upload/filter
bisa digunakan untuk memfilter file yang pernah di upload
oleh semua user. Endpoint ini menerima query string:
name
Filter berdasarkan nama file ketika di upload. Menerima nama parsial.type
Filter berdasarkan mime type file. Karaketer*
dianggap sebagai cocok dengan semua (ex:image/*
).hash
Filter berdasarkan hash file ( md5 ).
Validate
Sebelum malanjutkan proses upload file ke server, sebaiknya validasi file yang akan di upload untuk meminimalisir
kemungkinan error setelah file terupload. Panggil route /upload/validate
dengan body seperti di bawah:
{
"form": "form-name",
"file": {
"size": 123123,
"type": "image/jpeg",
"name": "file.jpg",
"width": 1223,
"height": 123321
}
}
Properti width
dan height
khusus untuk file tipe gambar.
Jika file yang akan diupload cocok dengan form, maka validator akan mengembalikan
nilai token
seperti di bawah yang bisa digunakan untuk upload dengan metode chunk:
{
"error": 0,
"message": "OK",
"data": {
"token": "UzHz6q/528879b833183b4158551768335784f3"
}
}
Validator
Jika module lib-validator
terpasang, maka module ini mendaftarkan tipe validasi dengan
sebagai berikut:
upload
Tipe validasi ini memastikan nilai file yang dikirim pernah diupload.
return [
'upload' => true,
'upload' => 'avatar-file'
];
Jika nilai yang diberikan adalah true
, maka validor hanya mengecek jika file pernah diupload
dan ada di server. Atau bisa juga memberikan nilai string nama form upload untuk memastikan file
yang dikirim cocok dengan file yang terupload.
upload-list
Sama dengan tipe validasi upload
, kecuali tipe ini menerima multiple data dalam bentuk array
dan akan mencocokan masing-masing file dengan form yang ditentukan.
return [
'upload-list' => true,
'upload-list' => 'avatar-file'
];
Nilai yang dikirimkan bisa berbentuk ["path/to/file.ext"]
atau object dalam array dengan
key media adalah url
seperti [{"url":"path/to/file.ext"}]
.
Formatter
Module ini menambah satu formatter dengan nama std-cover
untuk memformat data string object
menjadi object cover dengan label. Nilai property dengan format ini harus berbentuk seperti di
bawah:
{"url":"...","label":"..."}
Nilai seperti di atas akan diubah menjadi object media untuk properti URL, dan object text untuk properti label.
Form
Module ini juga menambahkan satu form yang bisa di-extends untuk menghasilkan 2 form field baru, yaitu
cover-url
dan cover-label
. Kedua properti ini kemudian bisa digunakan untuk mengambil object cover
dengan label.
Form Handler
Pada form std-cover
, cover memiliki URL dan label yang disimpan dalam object json. Untuk mempermudah
proses conversi dari properti cover
menjadi form fields, module ini menambahkan satu library dengan
nama LibUpload\Library\Form
.
use LibUpload\Library\Form as UForm;
$object = (object)[
'id' => 1,
'cover' => '{"url":"/path/to/img.jpg","label":"..."}'
];
// parse property `cover` menjadi `cover-url` dan `cover-label`
UForm::parse($object, 'cover');
// $form = new Form('form-name');
// if(!($valid = $form->validate($object)))
// return $this->resp('event/edit', $params);
// menggabungkan properti `cover-url` dan `cover-label` ke dalam properti `cover`
UForm::combine($valid, 'cover');
Chunk Upload
Library ini mendukung chunk upload untuk memungkinkan upload file dengan ukuran yang besar. Step yang harus dilakukan untuk upload chunk file adalah sebagai berikut:
Dapatkan Token
Validasi file dengan memanggil route /upload/validate
seperti contoh di atas untuk mendapatkan
token chunk upload.
Split File
Split file dengan masing-masing chunk berukuran cukup kecil tapi tidak terlalu kecil untuk di upload per-bagian. Ukuran yang umumnya digunakan adalah 200kb.
Upload Chunk
Upload chunk ke route /upload/chunk
secara berurutan dari yang paling awal ke yang akhir
dengan body seperti di bawah:
file::File : Chunk file
form::String : Upload form name
token::String: File upload chunk token
Finalize
Begitu semua chunk berhasil di upload, panggil route /upload/finalize
dengan body seperti
dibawah dalam format json untuk menyelesaikan proses upload.
form::String : Upload form name
token::String : File upload chunk token
name::String : Original file name
Jika proses upload berhasil, maka fungsi ini akan mengembalikan nilai yang sama dengan proses upload metode biasa.
Authorizer
Secara default, semua aktifitas upload/filter media harus ter-authorize oleh user ( lib-user ). Untuk memungkinkan upload dengan custom authorize, silahkan tambahkan konfigurasi seperti di bawah pada konfigurasi module/aplikasi:
return [
'libUpload' => [
'authorizer' => [
'name' => 'Class'
]
]
];
Dan buatkan class authorize yang mengimplementasikan interface LibUpload\Iface\Authorizer
sehingga
class tersebut memiliki method sebagai berikut:
static getAuthId(): ?int
Fungsi untuk mengembalikan object id yang memperbolehkan aktifitas upload/filter, atau null jika tidak diperbolehkan.