atk4 / filestore

Implements integration between ATK UI and FlySystem
https://agiletoolkit.org/
MIT License
9 stars 8 forks source link
agile atk4 filestore php upload

Starting from Version 1.4 of ATK UI, it adds support for File and Image uploads. In it's raw form, developer is responsible for taking care of the file once it's uploaded. In most cases, developer would want to store file either on a local or remote filesystem, but he would need to perform that action himself.

Filestore is a plugin for ATK Data and ATK UI which offers seamless integration with Flysystem.

Introduction

Attaching files to your database records is super-simple with Filestore. The next example can be implemented and added to YOUR php application in just a few lines:

upload1

Since ATK Form submits using AJAX file must be sent to the server as soon as it is selected. File is instantly placed inside flysystem (in the demo I'm using Local storage) and record in the database is created containing all the information about the file including if it is an image and if it is - dimensions:

upload1

Two random identifiers are generated - one is used for the actual file name (to make sure you don't overwrite existing file) and another one (token) will be used to reference the file. Actually you don't see a token at all, but it's used to keep things secure.

Files can be uploaded directly in your CRUD and you can have several file fields:

upload1

In your main table you only need one varchar field to store file token. If you use SQL, you can have instant access to additional fields such as name of original file or more:

upload1

This is especially valuable if you need to incorporate all these fields on your custom template.

Installation and Code

To install run composer require atk4\filestore and you will need to create filestore_file table. In the definition of your model, you simply need to declare a new field:

$this->addField('file', [\Atk4\Filestore\Field\FileField::class, 'flysystem' => $this->getApp()->filesystem]);

This pretty much takes care of everything! For full example see file demos/basic.php.

Features

Currently the following features are implemented:

Roadmap

We have the following ideas for the up-coming version. If you would like to help us implement (or sponsor) any of the features below, please contact @romaninsh (https://gitter.im/atk4/atk4):


OLD README:

event, so file upload will take place as soon as the file is selected. There are however some conditions, when file uploaded/deleted and form is not submitted.

On successful completion, PHP-side callback is executed to generate ID. Filestore provides this callback and performs the following actions:

Example

If you have a Model such as Friend and you wish to upload friend's photo, Filestore offers a great way to integrate:

// in Friend::init();
$this->addField('photo_file_token', [\Atk4\Filestore\Field\FileField::class]);

This field will automatically appear on the form as an upload field, but in the database will be storing "token" from the "File" model. You can even define multiple fields like that.

By default the local file storage will be used, but you can configure a different location simply by passing into your field:

$this->addField('photo_file_token', [
    \Atk4\Filestore\Field\FileField::class,
    // specify if you want to only accept certain types of files or extensions.
    'onlyTypes' => ['image/*', 'application/x-pdf'],
    'onlyExtensions' => ['img', 'png', 'pdf'], // safer to specify both

    // where to store
    'flysystem' => $flysystem,

    // you can also define callback if you wish to do something more with the file
    'onUpload' => function ($file) {
        // do something with file
    },

    // this is called when form with the file is submitted
    'onAttach' => function ($file) {
        // $file is a model object
    },

    // when user detaches file from the related entity
    'onDetach' => function ($file) {
        // $file is a model object
    },
])

If you open form for the Friend which already have a file attached, you will be able to remove the files. However just "removing" files may not mean they will be unassociated, user can still click "Cancel". When form is saved, however, if the file was removed, it will be also deleted from the storage and from File table.

Image

Filestore also implements \Atk4\Filestore\Field\Image class which offers additional features by extending File to automatically crop and store various thumbnails for an image.

$this->addField('picture_id', [
    \Atk4\Filestore\Field\Image::class,

    // no need to specify types, will only accept valid images

    // where to store
    'flysystem' => $flysystem,

    // you can still define this if you wish to pre-process your file, e.g. add watermark
    'onUpload' => function ($file) {
        // do something with file
    },

    // cropping table
    'crop' => [
        'medium' => [200, 300], // width, height
        'small' => [50, 50],
    ],
])

The cropping will maintain aspect ratio of original image, but will make sure that the image is filled. Will use either "imagick" or "gd" for the operation. Arguments are defined like that:

In order to store thumbnails, filestore will create additional file(s) inside File table.

File model

Filestore comes with a custom Model Atk4\Filestore\Model\File, which is designed to store file meta-information. For each uploaded file it stores:

Several "meta" fields are also defined which describe contents of the file

Methods

$file->createFromPath('path/to/file.txt', 'my_file.txt');

Create a File entity, save the data to flysystem and save the entity.

$stream = $file->getStream();

Returns stream of file contents. You can call $stream->getContents() to fetch the file content as a string.

Roadmap

Some of the possible future features: