adiachenko / pocket
Eloquent file management system for Laravel
Requires
- php: ^7.0
- illuminate/contracts: ~5.4
- illuminate/database: ~5.4
- illuminate/http: ~5.4
- illuminate/routing: ~5.4
- illuminate/support: ~5.4
- intervention/image: ~2.3
- nesbot/carbon: ^1.22
Requires (Dev)
- guzzlehttp/guzzle: ^6.0
- league/flysystem-aws-s3-v3: ^1.0
- orchestra/testbench: ~3.4
- phpunit/phpunit: ~5.7
Suggests
- league/flysystem-aws-s3-v3: Required to use AWS S3 file storage
This package is auto-updated.
Last update: 2019-01-25 18:26:19 UTC
README
Eloquent😜 file management for Laravel framework.
Table Of Contents
- Requirements
- Installation
- Enabling Model For Pocket Usage
- Basic Usage
- Editing Images
- Generating Public And Private URLs
- Limitations
Requirements
- PHP >= 7.0
- Laravel >= 5.4
- (optional)
league/flysystem-aws-s3-v3
Installation
To get started, install Pocket via the Composer package manager:
composer require adiachenko/pocket
Register the Pocket service provider in the providers array of your config/app.php
configuration file:
Adiachenko\Pocket\PocketServiceProvider::class,
The Pocket service provider registers its own database migration directory with the framework, so you should migrate your database after registering the provider. Migrations will create the table your application needs to store references to uploaded files:
php artisan migrate
Lastly, you can publish config/pocket.php
file, where you may specify your custom file reference model, change cache connection for storing presigned urls, provide various options for serving files (like cache control and content disposition) etc.:
php artisan vendor:publish --provider="Adiachenko\Pocket\PocketServiceProvider"
Make sure to have a look at it to get familiar with available options.
Enabling Model For Pocket Usage
Include Adiachenko\Pocket\Concerns\HasFiles
trait to the Eloquent model that you need to associate files with.
<?php
namespace App;
use Adiachenko\Pocket\Concerns\HasFiles;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFiles;
}
Basic Usage
Upload file and attach it to a model under specified namespace (in this case pictures
):
/** @var Illuminate\Http\UploadedFile $file */ $model->pocket('pictures')->add($file)->asPublic();
Or you may omit pocket name, in this case default
will be assumed:
/** @var Illuminate\Http\UploadedFile $file */ $model->pocket()->add($file)->asPublic();
Instead of passing the instance of UploadedFile directly, you can add file from request key:
$model->pocket()->addFromRequest('file')->asPublic();
Uploading via url is also possible:
$model->pocket()->addFromUrl('https://some-media.com/kitten.jpg')->asPublic();
Naturally, a file can be uploaded as private asset in which case it won't be directly accessible via url:
/** @var Illuminate\Http\UploadedFile $file */ $model->pocket()->add($file)->asPrivate();
You may explicitly specify filename on upload:
/** @var Illuminate\Http\UploadedFile $file */ $model->pocket()->add($file, 'whatever.txt')->asPublic();
Or disk where the file should be uploaded to (note, that we can optionally override default upload options with AWS S3):
/** @var Illuminate\Http\UploadedFile $file */ $model->pocket()->add($file)->asPublic('s3', [ 'CacheControl' => 'max-age=604800', 'ContentDisposition' => 'inline' ]);
You can retrieve a reference to uploaded file later like this:
/** @var Illuminate\Database\Eloquent\Model $fileRef */ $fileRef = $model->pocket()->collection()->first();
All references for specified pocket are lazy loaded so you don't need to worry much about microoptimizing your calls.
There is also a shortcut that will do the call to Illuminate\Database\Eloquent\Collection
instance for you under the hood:
/** @var Illuminate\Database\Eloquent\Model $fileRef */ $fileRef = $model->pocket()->first();
For more advanced database operations like paginating or ordering results, we recommend querying for file reference objects directly.
When deleting file reference, the related file be cleared automatically:
/** @var Illuminate\Database\Eloquent\Model $fileRef */ $fileRef->delete();
Or you can clear the whole pocket at once:
$model->pocket('whatever')->clear();
Editing Images
It's possible to generate image variants (for example, thumbnails, or watermarked images) with the help of Adiachenko\Pocket\ImageEditor
facade supplied with this package.
See example in the repo.
You should only be editing images in a queue or a scheduled job as this a memory-intensive operation.
Edited images are saved under variants
directory alongside the concerned file and can be accessed via variants
property on FileRef
instance.
When you run $fileRef->delete()
, all variants and related data will be cleared automatically so you shouldn't worry about managing these directly unless your use case goes beyond the public API described in here.
Generating Public And Private URLs
Generating public url is as simple as this:
/** @var Adiachenko\Pocket\Models\FileRef $fileRef */ $fileRef->getUrl()
Url can point to a variant, rather than original file:
/** @var Adiachenko\Pocket\Models\FileRef $fileRef */ $fileRef->getUrl('small')
Although we may provide a full filename here (e.g.
small.jpg
), it's not needed and in some cases even discouraged (e.g. it's possible that bothjpg
andjpeg
extensions are allowed). You only need to provide enough characters to uniquely identify the variant, we'll guess the rest.
If variant isn't found, getUrl
helper will fall back to retrieving original file instead.
To generate private url, specify expiry time in minutes:
/** @var Adiachenko\Pocket\Models\FileRef $fileRef */ $fileRef->getUrl(5)
The method signature for a file variant will look like this:
/** @var Adiachenko\Pocket\Models\FileRef $fileRef */ $fileRef->getUrl('small', 5)
Limitations
Although technically any Flysystem adapter is supported, to serve files from a driver other than local
or s3
a custom implementation of Adiachenko\Pocket\Channels\Channel
interface is required. Among other things, a channel is responsible for genereting presigned urls for your private assets. See configuration file for more information.
If you plan to serve file from an FTP drive rather than using third-party platform you might want to go a step further and extend Adiachenko\Pocket\Channels\SelfManagedChannel
class. This class has facilities in place that will help you hook into existing route used to serve private files from a local
disk.
Regenerating image variants must be done manually for now.