czim/laravel-cms-upload-module

There is no license information available for the latest version (1.0.3) of this package.

Laravel CMS: File Upload Module

1.0.3 2018-02-16 14:37 UTC

This package is auto-updated.

Last update: 2020-10-19 20:44:59 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status

CMS for Laravel - File uploader module

Simple file uploading module for the CMS.

This module offers functionality for simple temporary file uploads, to be used by other modules to allow users of the CMS to upload files with AJAX requests.

To be used to with the Laravel CMS Core.

This package is compatible and tested with Laravel 5.3 and 5.4.

Changelog

View the changelog.

Installation

Add the module class to your cms-modules.php configuration file:

    'modules' => [
        // ...
        Czim\CmsUploadModule\Modules\UploadModule::class,
    ],

Add the service provider to your cms-modules.php configuration file:

    'providers' => [
        // ...
        Czim\CmsUploadModule\Providers\CmsUploadModuleServiceProvider::class,
        // ...
    ],

To publish the config and migration:

php artisan vendor:publish

Run the CMS migration:

php artisan cms:migrate

The purpose of this module

This module is intended to help with situations where files should be uploaded using AJAX, before a form is submitted.

The happy-path flow for a user using a CMS form:

  1. Form displays.
  2. User selects files for upload and enters some data.
  3. User submits form.
  4. Data is stored.

However, when a validation error or some other problem occurs after form submission:

  1. Form displays.
  2. User selects files for upload and enters some data.
  3. User submits form.
  4. Form validation errors display.
  5. User fixes data.
  6. User re-selects all files for upload.
  7. User submits form.
  8. Data is stored.

The upload inputs are annoyingly cleared, forcing the user to re-select their files.

The solution

By uploading files asynchronously, the form can 'remember' a reference to these files.

  1. Form displays.
  2. User selects and uploads files and enters some data.
  3. User submits form.
  4. Form validation errors display.
  5. User fixes data.
  6. Data is stored.

Additionally, the files are only uploaded once, and the form submit request will be much smaller, since the files are already stored on the server.

This is the flow that this module facilitates.

Usage

This module does not have a CMS 'presence' directly; it does not do anything on its own. Its functionality may be employed by other CMS modules.

Storing a file

Files may be stored using the module's store route.

Send a POST request to <base>/cms/fileupload/file, with the following data:

  • file (file content, required)
    The file to be stored.

  • name (string, required)
    The (original) filename for the file to be stored.

  • reference (string)
    An optional custom reference. This is not guaranteerd to be unique.

  • validation (string, json)
    Optional Laravel validation rules, encoded as JSON. If these are given, the file content will be validated using these rules; if validation fails, the upload is not stored and a validation error message is returned.

Don't forget to include a CSRF token (in any standard way that Laravel accepts).

An example success response returned by the server:

{
    "success": true,
    "id": 79,
    "reference": "REF:804747507",
    "name": "test-file.jpg",
    "size": 129059,
    "mimetype": "image/jpeg"
}

The id value should be stored and used for further access to the file, as it is the unique identifier for this upload.

An example error response:

{
    "success": false,
    "error": "The file must be a file of type: txt."
}

Deleting a file

Files that have been uploaded (using the user's own session) may be deleted using the module's delete route.

Send a DELETE request to <base>/cms/fileupload/file/{id}.

Don't forget to include a CSRF token (in any standard way that Laravel accepts).

Retrieving a file

File uploads each have a record that can be looked up using the FileRepository:

$repository = app(\Czim\CmsUploadModule\Contracts\Repositories\FileRepositoryInterface::class);

// Look up an upload record by ID ...
$record = $repository->findById($fileRecordId);

// ... or by a manually set reference (returns a Collection)
$records = $repository->findByReference($referenceString);

Security

As with any module, only authenticated CMS users can access its routes.

Additionally a non-admin user must have the following permissions:

Permission key Description
fileupload.file.create Upload new files.
fileupload.file.delete Delete (your own) uploaded files.

Or simply set fileupload.file.* for all of the above.

Session Guard

Asynchronous uploads require special attention to security.

In addition to requiring validation and checks during file upload as well as during form submission, uploads are at risk of being hijacked by other CMS users.

This module offers a SessionGuard class to help prevent It is enabled by default: each upload will be linked to the user's session.

However, note that custom calls, such as accessing records through the FileRepository are not protected. The SessionGuard must be manually invoked to check:

$guard = app(\Czim\CmsUploadModule\Contracts\Support\Security\SessionGuardInterface::class);

if ( ! $guard->check($fileRecordId)) {
    throw new \Exception('Not your file!');
}

The session guard may be disabled by setting the cms-upload-module.upload.restrict.session config key to false.

Security beyond these basics, such as linking uploads to (CMS) users specifically, are not available out of the box. This should be implemented in your application or CMS module, if required.

Checking whether the module is available

When writing a CMS module that uses this upload module, it is recommended to create fall-back behavior, in case the upload module is not available.

To check whether this module is available, you can ask the Core's module manager:

/** @var Czim\CmsCore\Contracts\Modules\ModuleManagerInterface $moduleManager */
$moduleManager = app(\Czim\CmsCore\Support\Enums\Component::MODULES);

if ($moduleManager->has('file-uploader')) {
    // The file upload module is available...
}

Example

For an example of this module in use, check out the Models Module.

It features form display strategies for Stapler file and image uploads, and a store strategy that uses the upload module if it is loaded.

Garbage Collection

Uploaded files that are not used, may clutter and bloat your application.

To help prevent this, automatic garbage collection is enabled by default. This works by lottery (there's a 1% chance for each file upload that cleanup is performed), and cleanup will delete files older than a day (but this time is configurable).

There is also an Artisan command available to perform cleanup:

php artisan cms:upload:cleanup

Contributing

Please see CONTRIBUTING for details.

Credits

License

The MIT License (MIT). Please see License File for more information.