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
140 lines
3.8 KiB
Svelte
140 lines
3.8 KiB
Svelte
<script>
|
|
import {createEventDispatcher, getContext, hasContext} from "svelte";
|
|
import {writable} from "svelte/store";
|
|
import {fade} from "svelte/transition";
|
|
import {link} from "svelte-spa-router";
|
|
import {defined_settings, strings} from "../js/stores";
|
|
import PanelContainer from "./PanelContainer.svelte";
|
|
import PanelRow from "./PanelRow.svelte";
|
|
import DefinedInWPConfig from "./DefinedInWPConfig.svelte";
|
|
import ToggleSwitch from "./ToggleSwitch.svelte";
|
|
import HelpButton from "./HelpButton.svelte";
|
|
import Button from "./Button.svelte";
|
|
|
|
const classes = $$props.class ? $$props.class : "";
|
|
const dispatch = createEventDispatcher();
|
|
|
|
export let ref = {};
|
|
export let name = "";
|
|
export let heading = "";
|
|
export let defined = false;
|
|
export let multi = false;
|
|
export let flyout = false;
|
|
export let toggleName = "";
|
|
export let toggle = false;
|
|
export let refresh = false;
|
|
export let refreshText = $strings.refresh_title;
|
|
export let refreshDesc = refreshText;
|
|
export let refreshing = false;
|
|
export let helpKey = "";
|
|
export let helpURL = "";
|
|
export let helpDesc = $strings.help_desc;
|
|
|
|
// We can display storage provider info on the right-hand side of the panel's header.
|
|
// In the future, if anything else needs to be displayed in the same position we
|
|
// should create a named slot or assignable component. CSS changes would be required.
|
|
export let storageProvider = null;
|
|
|
|
// Parent page may want to be locked.
|
|
let settingsLocked = writable( false );
|
|
|
|
if ( hasContext( "settingsLocked" ) ) {
|
|
settingsLocked = getContext( "settingsLocked" );
|
|
}
|
|
|
|
$: locked = $settingsLocked;
|
|
$: toggleDisabled = $defined_settings.includes( toggleName ) || locked;
|
|
|
|
/**
|
|
* If appropriate, clicking the header toggles to toggle switch.
|
|
*/
|
|
function headingClickHandler() {
|
|
if ( toggleName && !toggleDisabled ) {
|
|
toggle = !toggle;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Catch escape key and emit a custom cancel event.
|
|
*
|
|
* @param {KeyboardEvent} event
|
|
*/
|
|
function handleKeyup( event ) {
|
|
if ( event.key === "Escape" ) {
|
|
event.preventDefault();
|
|
dispatch( "cancel" );
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<!-- TODO: Fix a11y. -->
|
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
<div
|
|
class="panel {name}"
|
|
class:multi
|
|
class:flyout
|
|
class:locked
|
|
transition:fade={{duration: flyout ? 200 : 0}}
|
|
bind:this={ref}
|
|
on:focusout
|
|
on:mouseenter
|
|
on:mouseleave
|
|
on:mousedown
|
|
on:click
|
|
on:keyup={handleKeyup}
|
|
>
|
|
{#if !multi && heading}
|
|
<div class="heading">
|
|
<h2>{heading}</h2>
|
|
{#if helpURL}
|
|
<HelpButton url={helpURL} desc={helpDesc}/>
|
|
{:else if helpKey}
|
|
<HelpButton key={helpKey} desc={helpDesc}/>
|
|
{/if}
|
|
<DefinedInWPConfig {defined}/>
|
|
</div>
|
|
{/if}
|
|
<PanelContainer class={classes}>
|
|
{#if multi && heading}
|
|
<PanelRow header>
|
|
{#if toggleName}
|
|
<ToggleSwitch name={toggleName} bind:checked={toggle} disabled={toggleDisabled}>
|
|
{heading}
|
|
</ToggleSwitch>
|
|
<!-- TODO: Fix a11y. -->
|
|
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
<h3 on:click={headingClickHandler} class="toggler" class:toggleDisabled>{heading}</h3>
|
|
{:else}
|
|
<h3>{heading}</h3>
|
|
{/if}
|
|
<DefinedInWPConfig {defined}/>
|
|
{#if refresh}
|
|
<Button refresh {refreshing} title={refreshDesc} on:click={() => dispatch("refresh")}>{@html refreshText}</Button>
|
|
{/if}
|
|
{#if storageProvider}
|
|
<div class="provider">
|
|
<a href="/storage/provider" use:link class="link">
|
|
<img src={storageProvider.link_icon} alt={storageProvider.icon_desc}>
|
|
{storageProvider.provider_service_name}
|
|
</a>
|
|
</div>
|
|
{/if}
|
|
{#if helpURL}
|
|
<HelpButton url={helpURL} desc={helpDesc}/>
|
|
{:else if helpKey}
|
|
<HelpButton key={helpKey} desc={helpDesc}/>
|
|
{/if}
|
|
</PanelRow>
|
|
{/if}
|
|
|
|
<slot/>
|
|
</PanelContainer>
|
|
</div>
|
|
|
|
<style>
|
|
.toggler:not(.toggleDisabled) {
|
|
cursor: pointer;
|
|
}
|
|
</style>
|