# R2_Adapter

Cloudflare R2 storage adapter for SatisPress.

***

* Full name: `\Linchpin_SatisPress\Helper\R2_Adapter`
* Parent class: [`Local`](../../SatisPress/Storage/Local)
* This class implements:
  `Storage`

## Constants

| Constant         | Visibility | Type   | Value        |
|------------------|------------|--------|--------------|
| `DEFAULT_BUCKET` | private    | string | 'satispress' |

## Properties

### bucket

R2 Bucket name.

```php
protected string $bucket
```

Resolved in the constructor from the R2_BUCKET constant, the
satispress_r2_storage_bucket filter, or DEFAULT_BUCKET.

***

### client

S3 Client instance.

```php
protected \Aws\S3\S3Client $client
```

***

## Methods

### __construct

Constructor.

```php
public __construct(): mixed
```

***

### resolve_bucket

Determines which R2 bucket packages are stored in.

```php
private resolve_bucket(): string
```

**Return Value:**

Bucket name.

***

### checksum

Copy a file from one location to another.

```php
public checksum(string $algorithm, string $file): string
```

**Parameters:**

| Parameter    | Type       | Description             |
|--------------|------------|-------------------------|
| `$algorithm` | **string** | The checksum algorithm. |
| `$file`      | **string** | The file to checksum.   |

**Throws:**

If file does not match checksum.
- [`FileNotFound`](../../SatisPress/Exception/FileNotFound)

***

### compute_checksum

Compute a checksum by streaming the object directly from R2.

```php
private compute_checksum(string $algorithm, string $file): string
```

Fallback for legacy artifacts uploaded before their checksum was stored in
metadata. The S3 stream wrapper lets hash_file() read the object in chunks
rather than buffering the whole archive in memory.

**Parameters:**

| Parameter    | Type       | Description             |
|--------------|------------|-------------------------|
| `$algorithm` | **string** | The checksum algorithm. |
| `$file`      | **string** | The file to checksum.   |

**Return Value:**

Checksum, or an empty string on failure.

***

### delete

Delete a file from the storage.

```php
public delete(string $file): bool
```

**Parameters:**

| Parameter | Type       | Description     |
|-----------|------------|-----------------|
| `$file`   | **string** | File to delete. |

***

### exists

Check if a file exists in the storage.

```php
public exists(string $file): bool
```

Answered from the cached per-package listing rather than a headObject.
`ReleaseManager::archive()` calls this once per managed package on every
packages.json build, and each round-trip to R2 costs far more than the
whole rest of the transform put together -- it was measured as the entire
cost of building the repository once checksums moved into


- **See:** \Linchpin_SatisPress\Helper\Checksum_Store. `list_files()` already holds the answer, and both
writers below invalidate it, so this cannot go stale behind a write.

Keys are always `slug/slug-version.zip`; anything else falls back to the
network so an unexpected shape can never be answered wrongly.

**Parameters:**

| Parameter | Type       | Description        |
|-----------|------------|--------------------|
| `$file`   | **string** | The file to check. |

***

### listing_transient

Transient name holding the cached listing for a prefix.

```php
private static listing_transient(string $path): string
```

Shared by the reader and the invalidators so the two can never disagree
about which key a listing lives under.

* This method is **static**.
**Parameters:**

| Parameter | Type       | Description                                      |
|-----------|------------|--------------------------------------------------|
| `$path`   | **string** | Prefix, or an empty string for the whole bucket. |

***

### flush_listing

Drop the cached listings a write to this key invalidates.

```php
private static flush_listing(string $file): void
```

Both the package's own listing and the whole-bucket listing, since either
may have been populated and both now describe the bucket incorrectly.

* This method is **static**.
**Parameters:**

| Parameter | Type       | Description                      |
|-----------|------------|----------------------------------|
| `$file`   | **string** | Key that was written or removed. |

***

### list_files

List our files in the storage.

```php
public list_files(string $path = ''): array
```

**Parameters:**

| Parameter | Type       | Description                              |
|-----------|------------|------------------------------------------|
| `$path`   | **string** | Path where the files to be listed exist. |

***

### move

Move the file to Cloudflare R2 storage.

```php
public move(string $source, string $destination): bool
```

Every artifact reaches the bucket through here -- SatisPress's own
ReleaseManager::archive(), and the `linchpin migrate-to-r2` command -- so
this is where an artifact is made safe to extract. Normalising before the
checksum is taken keeps the sha1 published in packages.json describing the
bytes actually stored, which replacing an artifact after the fact does not.

**Parameters:**

| Parameter      | Type       | Description                         |
|----------------|------------|-------------------------------------|
| `$source`      | **string** | The source file.                    |
| `$destination` | **string** | The destination key in the storage. |

***

### download

Copy an artifact out of the bucket to a local path.

```php
public download(string $file, string $destination): bool
```

The S3 stream wrapper reads the object in chunks rather than buffering the
whole archive in memory, the same way compute_checksum() does.

**Parameters:**

| Parameter      | Type       | Description          |
|----------------|------------|----------------------|
| `$file`        | **string** | Key to read.         |
| `$destination` | **string** | Local path to write. |

***

### send

Download a file, authenticating with the storage provider.

```php
public send(string $file): \SatisPress\HTTP\Response
```

**Parameters:**

| Parameter | Type       | Description             |
|-----------|------------|-------------------------|
| `$file`   | **string** | The file to send to R2. |

***
