Skip to content

Media

Form media

Use the MediaUploader.vue component to display media and handle uploading temporary media to save to the resource when submitting the (Inertia) form.

Users can drag and drop or click to upload files, with the ability to drag to sort if multiple items are uploaded. An optional cover flag allows marking an item with an icon. Items can be deleted from the list, and each upload undergoes back-end validation. Inline error messages display validation issues, while a toast message appears if the back-end fails. Files are only saved as temporary uploads if they pass validation.

TemporaryFileUploadRules

The front-end file upload rules are shown in the requirements info tooltip in the component. Only the maximum files and accepted MIME types requirements are also used to do some client-side validation, like preventing adding more files than allowed or selecting videos when only images are accepted.

TemporaryFileUploadGroup

Each use of MediaUploader.vue should be linked to a unique upload group, like category images or a questionnaire cover. This group is used to both figure out which validation rules to use when adding media, and later copying the correct temporary uploads to their final destination.

Each group requires specific back-end file validation rules as a single form request. This form request should be added to \Interfaces\App\Actions\ValidateTemporaryFileUploadGroup and is used to validate the temporary upload coming from the media component.

Uploading files

The application uses a single file upload endpoint accessible only to authenticated users. Upload requests are rate-limited to 20 per minute for regular users and 200 per minute for other roles. Generic validation ensures all requests require group, UUID, and valid file, with additional validation applied per group. Uploaded files are stored in the database as TemporaryUpload models within the temporary_uploads table, each linked to have one Media model in the default media collection. The TemporaryUpload model tracks the upload group and session ID, which is tied to the user, while the Media model references the original file stored on disk waiting to be attached to the target model when submitting the valid form.

Saving the form

Each valid temporary upload returns the Media model's UUID, which is added to an array, such as form.images for a category. The form is saved using only media UUIDs, combining existing media and temporary uploads, as all are stored as Media records. No revalidation of files or images occurs, only UUID validation using the MediaRules class. This class applies a batch ModelsExist rule to verify that each UUID corresponds to either an existing media record or a temporary upload. The validation ensures that temporary upload UUIDs belong to the correct group to prevent cross-group mismatches or confirms that each existing UUID corresponds to an existing media record of the expected model.

Attaching media

When saving, temporary media must be reassigned from the TemporaryUpload model to the Category model. This is handled by $category->synchronizeMedia($uuids, $uploadGroup), which defines the new media sort order, removes existing media not present in the provided UUID list (sync), and bypasses certain Spatie Media Library Pro checks. It then moves temporary Media records by copying and deleting them, and deletes the TemporaryUpload record since it is no longer linked to any media.

Remark: local/test media

Rearranging existing media right after deploying to a test environment does not work (because of how we statically seed media on test environments and locally). Please delete all media of the resource when editing first. Then upload new media, save, go back to the index, and back to edit to test the edit functionality.