Skip to main content

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'
})
})
caution

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 } })