adiachenko/pocket

This package is abandoned and no longer maintained. The author suggests using the spatie/laravel-medialibrary package instead.

Eloquent file management system for Laravel

v1.0.1 2017-05-30 17:10 UTC

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

  • 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 both jpg and jpeg 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.