Media
It is quite common to have a form where users can upload files. Aside from the FilePicker
and Image
field,
which both offer a simple upload input, you also have elements like Wysiwyg editors which allow for files to be pasted inside without
necessarily knowing which model (id) is related to the file.
Media files
By default, when uploading files via the FilePicker
and Image
field, Qore uses the Spatie Media Library package to store files.
This means that each file will have a corresponding record in the media
table. You can manually do this, for example:
/** @var HasMedia $model */
$media = $model->addMedia(Storage::disk('local')->path($path))
->setName($this->name)
->setFileName('somefilename.png')
->toMediaCollection();
This however can only work as long as you have a $model
available
Retrieving media files
Retrieving existing media requires:
- The
uuid
of the media - Permission to
view
the related model
The documentation can be found (here)
Media table
You can also show a table of all media files that exist in the media
table (only where the user has access to).
This is used by for example the MediaSelect
field:
<base-table
endpoint="/media"
fixedLayout
:appendToPagination="{ ignore: [...listOfMediaUuidsToNotShow] }"
>
<template v-slot:body-cell-file_name="{ props }">
<span>My slot for {{ props.row }}</span>
</template>
</base-table>
Roaming files
In elements like Wysiwig editors, or something like Dropzone libraries, you need to upload files without having a $model
or ID available.
Qore offers a route where you can post your file to. This file will have a publicly available url:
const data = new FormData()
data.append('media', file) // file is retrieved from a <input type="file" /> input
this.$api.post('media', data, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(({ data }) => {
console.log(data) // Response data contains url and file name
}).catch(({ response }) => {
let message = this.$t(`There was an error uploading [${file.name}]`)
if ('data' in response && 'message' in response.data) {
message = response.data.message
}
this.$q.notify({
message: message,
type: 'negative',
position: 'top'
})
})
Roaming files will be publicly available, but have a long unique name that is extremely hard to guess. It is recommended that
roaming files are moved to Media files as soon as it can be attached to a $model
.
You can move roaming files using code like this:
$path = "roaming/$roamingFileName";
if (!Storage::disk('public_global')->exists($path)) {
return;
}
/** @var HasMedia $model */
$media = $model->addMedia(Storage::disk('public_global')->path($path))
->setName($this->name)
->setFileName($file['name'])
->toMediaCollection();
Deleting roaming files
Roaming files can be deleted for a limited time (60 minutes after the upload, at this time of writing):
this.$api.delete('media', { data: { file_name: file.external_file_name } })