feat: add S3-compatible storage provider (MinIO, Ceph, R2, etc.)
Adds a new 'S3-Compatible Storage' provider that works with any
S3-API-compatible object storage service, including MinIO, Ceph,
Cloudflare R2, Backblaze B2, and others.
Changes:
- New provider class: classes/providers/storage/s3-compatible-provider.php
- Provider key: s3compatible
- Reads user-configured endpoint URL from settings
- Uses path-style URL access (required by most S3-compatible services)
- Supports credentials via AS3CF_S3COMPAT_ACCESS_KEY_ID /
AS3CF_S3COMPAT_SECRET_ACCESS_KEY wp-config.php constants
- Disables AWS-specific features (Block Public Access, Object Ownership)
- New provider SVG icons (s3compatible.svg, -link.svg, -round.svg)
- Registered provider in main plugin class with endpoint setting support
- Updated StorageProviderSubPage to show endpoint URL input for S3-compatible
- Built pro settings bundle with rollup (Svelte 4.2.19)
- Added package.json and updated rollup.config.mjs for pro-only builds
This commit is contained in:
204
vendor/Aws3/Aws/QueryCompatibleInputMiddleware.php
vendored
Normal file
204
vendor/Aws3/Aws/QueryCompatibleInputMiddleware.php
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
namespace DeliciousBrains\WP_Offload_Media\Aws3\Aws;
|
||||
|
||||
use DeliciousBrains\WP_Offload_Media\Aws3\Aws\Api\ListShape;
|
||||
use DeliciousBrains\WP_Offload_Media\Aws3\Aws\Api\MapShape;
|
||||
use DeliciousBrains\WP_Offload_Media\Aws3\Aws\Api\Service;
|
||||
use DeliciousBrains\WP_Offload_Media\Aws3\Aws\Api\Shape;
|
||||
use DeliciousBrains\WP_Offload_Media\Aws3\Aws\Api\StructureShape;
|
||||
use Closure;
|
||||
/**
|
||||
* Inspects command input values and casts them to their modeled type.
|
||||
* This covers query compatible services which have migrated from query
|
||||
* to JSON wire protocols.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class QueryCompatibleInputMiddleware
|
||||
{
|
||||
/** @var callable */
|
||||
private $nextHandler;
|
||||
/** @var Service */
|
||||
private $service;
|
||||
/** @var CommandInterface */
|
||||
private $command;
|
||||
/**
|
||||
* Create a middleware wrapper function.
|
||||
*
|
||||
* @param Service $service
|
||||
* @return Closure
|
||||
*/
|
||||
public static function wrap(Service $service) : Closure
|
||||
{
|
||||
return static function (callable $handler) use($service) {
|
||||
return new self($handler, $service);
|
||||
};
|
||||
}
|
||||
public function __construct(callable $nextHandler, Service $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
$this->nextHandler = $nextHandler;
|
||||
}
|
||||
public function __invoke(CommandInterface $cmd)
|
||||
{
|
||||
$this->command = $cmd;
|
||||
$nextHandler = $this->nextHandler;
|
||||
$op = $this->service->getOperation($cmd->getName());
|
||||
$inputMembers = $op->getInput()->getMembers();
|
||||
$input = $cmd->toArray();
|
||||
foreach ($input as $param => $value) {
|
||||
if (isset($inputMembers[$param])) {
|
||||
$shape = $inputMembers[$param];
|
||||
$this->processInput($value, $shape, [$param]);
|
||||
}
|
||||
}
|
||||
return $nextHandler($this->command);
|
||||
}
|
||||
/**
|
||||
* Recurses a given input shape. if a given scalar input does not match its
|
||||
* modeled type, it is cast to its modeled type.
|
||||
*
|
||||
* @param $input
|
||||
* @param $shape
|
||||
* @param array $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function processInput($input, $shape, array $path) : void
|
||||
{
|
||||
switch ($shape->getType()) {
|
||||
case 'structure':
|
||||
$this->processStructure($input, $shape, $path);
|
||||
break;
|
||||
case 'list':
|
||||
$this->processList($input, $shape, $path);
|
||||
break;
|
||||
case 'map':
|
||||
$this->processMap($input, $shape, $path);
|
||||
break;
|
||||
default:
|
||||
$this->processScalar($input, $shape, $path);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param array $input
|
||||
* @param StructureShape $shape
|
||||
* @param array $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function processStructure(array $input, StructureShape $shape, array $path) : void
|
||||
{
|
||||
foreach ($input as $param => $value) {
|
||||
if ($shape->hasMember($param)) {
|
||||
$memberPath = \array_merge($path, [$param]);
|
||||
$this->processInput($value, $shape->getMember($param), $memberPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param array $input
|
||||
* @param ListShape $shape
|
||||
* @param array $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function processList(array $input, ListShape $shape, array $path) : void
|
||||
{
|
||||
foreach ($input as $param => $value) {
|
||||
$memberPath = \array_merge($path, [$param]);
|
||||
$this->processInput($value, $shape->getMember(), $memberPath);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param array $input
|
||||
* @param MapShape $shape
|
||||
* @param array $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function processMap(array $input, MapShape $shape, array $path) : void
|
||||
{
|
||||
foreach ($input as $param => $value) {
|
||||
$memberPath = \array_merge($path, [$param]);
|
||||
$this->processInput($value, $shape->getValue(), $memberPath);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param $input
|
||||
* @param Shape $shape
|
||||
* @param array $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function processScalar($input, Shape $shape, array $path) : void
|
||||
{
|
||||
$expectedType = $shape->getType();
|
||||
if (!$this->isModeledType($input, $expectedType)) {
|
||||
\trigger_error("The provided type for `" . \implode(' -> ', $path) . "` value was `" . (\gettype($input) === 'double' ? 'float' : \gettype($input)) . "`." . " The modeled type is `{$expectedType}`.", \E_USER_WARNING);
|
||||
$value = $this->castValue($input, $expectedType);
|
||||
$this->changeValueAtPath($path, $value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Modifies command in place
|
||||
*
|
||||
* @param array $path
|
||||
* @param $newValue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function changeValueAtPath(array $path, $newValue) : void
|
||||
{
|
||||
$commandRef =& $this->command;
|
||||
foreach ($path as $segment) {
|
||||
if (!isset($commandRef[$segment])) {
|
||||
return;
|
||||
}
|
||||
$commandRef =& $commandRef[$segment];
|
||||
}
|
||||
$commandRef = $newValue;
|
||||
}
|
||||
/**
|
||||
* @param $value
|
||||
* @param $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isModeledType($value, $type) : bool
|
||||
{
|
||||
switch ($type) {
|
||||
case 'string':
|
||||
return \is_string($value);
|
||||
case 'integer':
|
||||
case 'long':
|
||||
return \is_int($value);
|
||||
case 'float':
|
||||
return \is_float($value);
|
||||
default:
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param $value
|
||||
* @param $type
|
||||
*
|
||||
* @return float|int|mixed|string
|
||||
*/
|
||||
private function castValue($value, $type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
return (int) $value;
|
||||
case 'long':
|
||||
return $value + 0;
|
||||
case 'float':
|
||||
return (float) $value;
|
||||
case 'string':
|
||||
return (string) $value;
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user