Skip to content

Tiger_Media_Storage_S3

@api · implements Tiger_Media_Storage_Interface

Tiger_Media_Storage_S3 — Amazon S3 (and S3-compatible) media storage.

One bucket holds everything; visibility selects a key prefix (not a separate bucket) so a single bucket policy can expose only the public prefix:

  • PUBLIC files land under public_prefix (default public/) → url() returns a direct CDN/S3 URL (make that prefix world-readable via a CloudFront distribution or a bucket policy — modern buckets block object ACLs, so we don't rely on public-read by default).
  • PRIVATE files land under private_prefix (default private/) → url() returns a short-lived presigned GET URL (presign_ttl), so S3 serves the bytes directly while the app still gates who gets handed a URL. If presigning is disabled, url() returns '' and the media layer streams through the ACL-checked /media/file/ route instead.

Credentials come from the default AWS provider chain (an EC2/ECS IAM role, env, or shared config) unless key+secret are set in the disk config. endpoint + use_path_style point it at an S3-compatible service (MinIO, DigitalOcean Spaces, R2).

Requires aws/aws-sdk-php (optional dependency — see composer suggest / MEDIA.md); the adapter throws a clear message if it's missing, and only loads when the s3 disk is used.

Methods

__construct()

__construct(array $config)

Build the S3 adapter from a disk config array.

  • $config array — the disk config (bucket required; plus optional region,

Throws RuntimeException — when bucket is missing

put()

put($key, $sourcePath, $visibility, $mime = null)

Upload a file from a local path to the bucket.

  • $key string — the storage key
  • $sourcePath string — local file path to upload
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)
  • $mime string|null — optional content-type

write()

write($key, $bytes, $visibility, $mime = null)

Write in-memory bytes to the bucket.

  • $key string — the storage key
  • $bytes string — the object body
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)
  • $mime string|null — optional content-type

get()

get($key, $visibility)

Fetch an object's full contents.

  • $key string — the storage key
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)

Returns string — the object bytes

Throws RuntimeException — when the object is not found

stream()

stream($key, $visibility)

Open a readable stream for an object (live socket when possible, else a temp buffer).

  • $key string — the storage key
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)

Returns resource — a readable stream handle

Throws RuntimeException — when the object is not found

delete()

delete($key, $visibility)

Delete an object (idempotent — deleting a missing key still succeeds).

  • $key string — the storage key
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)

exists()

exists($key, $visibility)

Report whether an object exists.

  • $key string — the storage key
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)

Returns bool — true when the object exists

size()

size($key, $visibility)

Return an object's size in bytes (0 when missing).

  • $key string — the storage key
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)

Returns int — the byte length, or 0 if not found

url()

url($key, $visibility, $ttl = null)

Build a URL for an object: a direct public URL, or a short-lived presigned GET for private.

Returns '' for private objects when presigning is disabled, so the media layer streams through the ACL-checked route instead.

  • $key string — the storage key
  • $visibility string — PUBLIC or PRIVATE (selects the key prefix)
  • $ttl int|null — override the presign lifetime (seconds) for a private object

Returns string — the object URL, or '' when no direct/presigned URL is available