php-plug-storage/CLAUDE.md

50 lines
2.3 KiB
Markdown
Raw Permalink Normal View History

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
This is `lthn/php-plug-storage`, a Composer library providing storage provider integrations for the Plug framework. It depends on `lthn/php` (the core framework) and wraps Bunny CDN's storage API behind a driver-based abstraction.
## Commands
```bash
composer install # Install dependencies
```
There are no tests, linting, or build steps in this package.
## Architecture
**Namespace:** `Core\Plug\Storage\` (PSR-4 autoloaded from `src/`)
### Contract Layer (`src/Contract/`)
Four interfaces define storage operations. All return `Core\Plug\Response` (from the core framework):
- `Uploadable` — file and content uploads
- `Downloadable` — content retrieval and file downloads
- `Deletable` — single and bulk file deletion
- `Browseable` — directory listing, existence checks, file size
### Bunny Implementation (`src/Bunny/`)
Each contract has a corresponding Bunny CDN implementation (`Upload`, `Download`, `Delete`, `Browse`). They share a common pattern:
- Constructor accepts optional credentials or reads from config (`cdn.bunny.{zone}.api_key`, `cdn.bunny.{zone}.storage_zone`, `cdn.bunny.{zone}.region`)
- Lazy-initialized `Bunny\Storage\Client`
- `isConfigured()` guard before operations
- `BuildsResponse` trait for consistent `ok()`/`error()` responses
- Static `public()`/`private()` factory methods for zone selection
**VBucket** (`src/Bunny/VBucket.php`) provides workspace-isolated storage. It hashes a domain via `Core\Crypt\LthnHash::vBucketId()` and prefixes all paths with the resulting ID. It combines upload, download, delete, list, and exists operations in one class rather than implementing the individual contracts.
### StorageManager (`src/StorageManager.php`)
Factory that resolves operations by driver name. Configured via `cdn.storage_driver` config key (defaults to `bunny`). Supports zone switching and custom driver registration via `extend()`.
## Key Patterns
- All storage operations return `Core\Plug\Response`, never throw — errors are wrapped via `BuildsResponse::error()`.
- Zone (`public`/`private`) is threaded through constructors, not set after instantiation.
- Adding a new storage provider means: implement the four contracts, then register via `StorageManager::extend()`.