\Drupal\strata\Storage StorageProviderInterface

Where Strata puts its objects.

Implemented for S3 and every S3-compatible endpoint, for Cloudflare R2, for SFTP and FTP, and for the local filesystem. An add-on provider implements this and registers with StorageProviderManager; nothing in the engine branches on a provider class.

Every key is relative to the store root, which the provider prefixes with _strata/<site-id>/ so a bucket can hold other things. Keys never begin with a slash.

Two rules bind every implementation:

  • Never return partial content. A short read, a truncated body or an unverified checksum raises. Downstream code cannot distinguish a truncated frame from a real one.
  • Report capabilities honestly through StorageProviderInterface::capabilities(). S3 compatibility varies by endpoint, and the engine branches on the answer rather than on a provider name.

Summary

Methods
Constants
id()
label()
capabilities()
isReachable()
unreachableReason()
put()
get()
stream()
head()
exists()
delete()
list()
No public constants found

Methods

id()

id() : string

The plugin id this provider registers under.

Returns

string —

A short lowercase token such as "s3", "r2", "sftp" or "local".

label()

label() : string

Human-readable name for the settings form.

Returns

string —

The label.

capabilities()

capabilities() : \Drupal\strata\Storage\Capabilities

What this endpoint can do.

Probed once per endpoint and cached; a probe that cannot run returns conservative defaults rather than optimistic ones, so an unknown endpoint degrades to more requests instead of to failed ones.

Returns

\Drupal\strata\Storage\Capabilities —

The capability set.

isReachable()

isReachable() : bool

Whether the endpoint is reachable and the credentials work.

Called by hook_requirements() and the settings form, so it must be cheap and must not throw.

Returns

bool —

TRUE when a request would succeed right now.

unreachableReason()

unreachableReason() : string|null

Why the endpoint is unreachable.

Returns

string|null —

A short human-readable reason, or NULL when it is reachable.

put()

put(string  $key, string|resource  $body, array  $options = []) : \Drupal\strata\Storage\PutResult

Writes an object.

Splits into parts automatically when the body exceeds what the endpoint takes in one request.

Parameters

string $key

Object key relative to the store root.

string|resource $body

The bytes, or an open readable stream. A stream is read once and not rewound, so a caller that needs it again must seek itself.

array $options

Provider options. ifNoneMatch (write only when the key is absent) is honoured wherever Capabilities::$conditionalWrite is true. metadata, contentType and storageClass are honoured only by providers whose endpoint carries them; a provider that cannot store an option refuses the write rather than dropping it, because an object written without the metadata its reader expects is indistinguishable from a corrupt one. Nothing in the engine depends on user metadata: a stored object carries whatever a reader needs in its own bytes.

Throws

\RuntimeException

When the write fails, the body is larger than the endpoint can store, or a conditional write was requested on an endpoint that does not honour one.

Returns

\Drupal\strata\Storage\PutResult —

What was written.

get()

get(string  $key, \Drupal\strata\Storage\ByteRange|null  $range = null) : string

Reads an object.

Parameters

string $key

Object key relative to the store root.

\Drupal\strata\Storage\ByteRange|null $range

A byte range, or NULL for the whole object.

Throws

\RuntimeException

When the object is absent, the read fails, or fewer bytes arrive than were asked for.

Returns

string —

The bytes.

stream()

stream(string  $key) : resource

Opens an object as a stream.

For objects too large to hold in memory. A caller that wants bytes should use StorageProviderInterface::get() instead.

Parameters

string $key

Object key relative to the store root.

Throws

\RuntimeException

When the object is absent or cannot be opened.

Returns

resource —

An open readable stream the caller must close.

head()

head(string  $key) : \Drupal\strata\Storage\ObjectMeta|null

Metadata for one object without reading it.

Parameters

string $key

Object key relative to the store root.

Returns

\Drupal\strata\Storage\ObjectMeta|null —

The metadata, or NULL when the object is absent. Absence is not an error, because every caller of this method is asking precisely in order to find out.

exists()

exists(string  $key) : bool

Whether an object exists.

Parameters

string $key

Object key relative to the store root.

Returns

bool —

TRUE when it is present.

delete()

delete(list  $keys) : int

Deletes objects.

Batches when the endpoint supports it. Deleting an absent key is not an error, so a retried prune is idempotent.

Parameters

list $keys

Object keys relative to the store root.

Throws

\RuntimeException

When the endpoint refuses the request.

Returns

int —

How many keys the endpoint accepted. A store that can tell an absent key from a removed one counts only what it removed; S3 reports success for an absent key and cannot distinguish, so it counts everything it was given. Do not read this as "how many existed" - a prune receipt counts from the frame index, which knows.

list()

list(string  $prefix = '', string|null  $cursor = null, int  $limit = 1000, string|null  $delimiter = null) : \Drupal\strata\Storage\ObjectPage

Lists one page of objects under a prefix.

Parameters

string $prefix

Key prefix relative to the store root; an empty string lists everything.

string|null $cursor

Continuation token from a previous page, or NULL to start.

int $limit

Most objects to return in this page.

string|null $delimiter

Grouping delimiter, or NULL for a flat listing.

Throws

\RuntimeException

When the listing fails.

Returns

\Drupal\strata\Storage\ObjectPage —

The page.