Skip to content
This is the documentation for pieceofcake2/filebinder, a CakePHP 2.x plugin for pieceofcake2/cakephp. About this fork.

Amazon S3 ​

The S3 storage saves a copy of each file on Amazon S3. It works alongside the local files and the database storage. It needs an S3 client plugin.

Installing an S3 Client ​

Filebinder works with two S3 clients:

Install and load one of them.

AsyncAws ​

Install pieceofcake2/async-aws with async-aws/simple-s3:

bash
composer require pieceofcake2/async-aws async-aws/simple-s3

Load the plugin in config/bootstrap.php:

php
CakePlugin::load('AsyncAws');

AWS SDK for PHP ​

Install pieceofcake2/aws:

bash
composer require pieceofcake2/aws

Load the plugin in config/bootstrap.php:

php
CakePlugin::load('Aws');

Choosing the Client ​

Filebinder uses the client of the loaded plugin. When both plugins are loaded, it uses AsyncAws.

To choose the client yourself, set Filebinder.S3.client to 'AsyncAws' or 'Aws':

php
Configure::write('Filebinder.S3.client', 'AsyncAws');

The plugin of the client must be loaded. Installing the AWS SDK for PHP alone is not enough. When Filebinder cannot use any client, saving a file throws a FilebinderS3StorageException. Its message says which package to install and load.

Saving Files on S3 ​

Add BindableBehavior::STORAGE_S3 to the storage setting, and set the bucket of the field:

php
public $actsAs = [
    'Filebinder.Bindable' => [
        'storage' => [BindableBehavior::STORAGE_DB, BindableBehavior::STORAGE_S3],
    ],
];

public $bindFields = [
    [
        'field' => 'image',
        'filePath' => '/var/www/html/myapp/webroot/files/',
        'bucket' => 'my-bucket',
        'acl' => 'private',
    ],
];

The behavior saves each file with this key:

text
<urlPrefix><model>/<model_id>/<field_name>/<file_name>

When a local file does not exist, find() downloads it from S3 (see Restoring Files).

The Content-Type of a file on S3 comes from the contents of the file. Filebinder detects it with the fileinfo extension, as it does for file_content_type. It does not use the type that the browser sent or the extension of the file.

S3 Settings ​

Each field can set its own bucket, acl, urlPrefix and region in $bindFields (see Bound Fields). For the fields without them, Filebinder uses the Filebinder.S3 settings:

php
Configure::write('Filebinder.S3', [
    'bucket' => 'my-bucket',
    'acl' => 'private',
    'urlPrefix' => 'files/',
]);
SettingDescription
Filebinder.S3.client'AsyncAws' or 'Aws'. Default: the client of the loaded plugin.
Filebinder.S3.bucketBucket, for the fields without bucket.
Filebinder.S3.aclCanned ACL, for the fields without acl. Default: public-read.
Filebinder.S3.urlPrefixPrefix of the keys, for the fields without urlPrefix.
Filebinder.S3.regionDeprecated. Set region in the plugin configuration instead. Region, for the fields without region. It overrides the plugin configuration.
Filebinder.S3.key, Filebinder.S3.secretDeprecated. Set the credentials in the plugin configuration, or use the default credentials. Access key of AWS. It overrides the plugin configuration.

Client Configuration ​

Filebinder creates the S3 client from the configuration of the client plugin. Set the region and the credentials there.

pieceofcake2/async-aws reads the AsyncAws configuration. When AsyncAws is not set, it reads the Aws configuration. See AsyncAws Configuration.

php
Configure::write('AsyncAws', [
    'region' => 'ap-northeast-1',
]);

pieceofcake2/aws reads the Aws configuration. See AWS Configuration.

php
Configure::write('Aws', [
    'region' => 'ap-northeast-1',
]);

The region of a field overrides the region of the configuration for all the S3 requests of that field.

Credentials ​

When the configuration has no credentials, the SDKs use their default credentials:

  • environment variables
  • the shared credentials file
  • the IAM role of the EC2 instance, the ECS task or the Lambda function

Filebinder.S3.key and Filebinder.S3.secret still work and override the configuration, but they are deprecated. Move the credentials to the plugin configuration, or use the default credentials.

Public and Private Files ​

The ACL of a file decides how the Label helper links it. The ACL is the acl of the field, or else Filebinder.S3.acl. The default is public-read.

  • With a public ACL (public-read or public-read-write), the helper outputs the URL of the object. Anyone can open it.
  • With any other ACL, such as private, the helper outputs a presigned URL. The URL expires after Filebinder.expire, one minute by default.

To keep the files private, set the ACL to private:

php
Configure::write('Filebinder.S3.acl', 'private');

S3 checks the signature of a presigned URL. The files do not go through your application. See URLs of the Files.

S3 Storage API ​

s3Storage() returns the S3 storage of a field. The storage is a FilebinderS3StorageInterface, configured as the behavior configures it for that field:

php
$storage = $this->Post->s3Storage('image');

Call its methods with the bucket and the key of an object:

php
$this->set('imageUrl', $storage->url('my-bucket', 'files/Post/1/image/photo.jpg'));

The storage has these methods:

MethodDescription
put(string $bucket, string $key, string $file, array $options = []): voidUploads a local file. Options: ACL.
get(string $bucket, string $key): stringReturns the contents of an object.
saveAs(string $bucket, string $key, string $file): voidDownloads an object to a local file.
delete(string $bucket, string $key): voidDeletes an object.
url(string $bucket, string $key): stringReturns the URL of an object, as the client builds it. The URL is not signed.
presignedUrl(string $bucket, string $key, DateTimeImmutable $expires): stringReturns a presigned URL to download an object. The URL expires at $expires.

Storage Factory ​

FilebinderS3StorageFactory creates the storages. Load it first:

php
App::uses('FilebinderS3StorageFactory', 'Filebinder.Storage');

FilebinderS3StorageFactory::create() creates the storage of the configured client. It takes client options, such as region and credentials:

php
$storage = FilebinderS3StorageFactory::create(['region' => 'ap-northeast-1']);

FilebinderS3StorageFactory::client() returns the name of that client, 'AsyncAws' or 'Aws':

php
$client = FilebinderS3StorageFactory::client();

See LICENSE for copyright and license information. Not affiliated with the Cake Software Foundation.