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:
173
assets/js/media.js
Normal file
173
assets/js/media.js
Normal file
@@ -0,0 +1,173 @@
|
||||
var test = {};
|
||||
|
||||
( function( $, _ ) {
|
||||
|
||||
// Local reference to the WordPress media namespace.
|
||||
var media = wp.media;
|
||||
|
||||
// Local instance of the Attachment Details TwoColumn used in the edit attachment modal view
|
||||
var wpAttachmentDetailsTwoColumn = media.view.Attachment.Details.TwoColumn;
|
||||
|
||||
/**
|
||||
* Add S3 details to attachment.
|
||||
*/
|
||||
media.view.Attachment.Details.TwoColumn = wpAttachmentDetailsTwoColumn.extend( {
|
||||
events: function() {
|
||||
return _.extend( {}, wpAttachmentDetailsTwoColumn.prototype.events, {
|
||||
'click .local-warning': 'confirmS3Removal',
|
||||
'click #as3cfpro-toggle-acl': 'toggleACL'
|
||||
} );
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// Retrieve the S3 details for the attachment
|
||||
// before we render the view
|
||||
this.fetchS3Details( this.model.get( 'id' ) );
|
||||
},
|
||||
|
||||
fetchS3Details: function( id ) {
|
||||
wp.ajax.send( 'as3cf_get_attachment_provider_details', {
|
||||
data: {
|
||||
_nonce: as3cf_media.nonces.get_attachment_provider_details,
|
||||
id: id
|
||||
}
|
||||
} ).done( _.bind( this.renderView, this ) );
|
||||
},
|
||||
|
||||
renderView: function( response ) {
|
||||
// Render parent media.view.Attachment.Details
|
||||
wpAttachmentDetailsTwoColumn.prototype.render.apply( this );
|
||||
|
||||
this.renderActionLinks( response );
|
||||
this.renderS3Details( response );
|
||||
},
|
||||
|
||||
renderActionLinks: function( response ) {
|
||||
var links = ( response && response.links ) || [];
|
||||
var $actionsHtml = this.$el.find( '.actions' );
|
||||
var $s3Actions = $( '<div />', {
|
||||
'class': 's3-actions'
|
||||
} );
|
||||
|
||||
var s3Links = [];
|
||||
_( links ).each( function( link ) {
|
||||
s3Links.push( link );
|
||||
} );
|
||||
|
||||
$s3Actions.append( s3Links.join( ' | ' ) );
|
||||
$actionsHtml.append( $s3Actions );
|
||||
},
|
||||
|
||||
renderS3Details: function( response ) {
|
||||
if ( ! response || ! response.provider_object ) {
|
||||
return;
|
||||
}
|
||||
var $detailsHtml = this.$el.find( '.attachment-info .details' );
|
||||
var html = this.generateDetails( response, [ 'provider_name', 'region', 'bucket', 'key', 'acl', 'is_verified' ] );
|
||||
$detailsHtml.append( html );
|
||||
},
|
||||
|
||||
generateDetails: function( response, keys ) {
|
||||
var html = '';
|
||||
var template = _.template( '<div class="<%= key %>"><strong><%= label %>:</strong> <%= value %></div>' );
|
||||
|
||||
_( keys ).each( function( key ) {
|
||||
if ( response.provider_object[ key ] ) {
|
||||
var value = response.provider_object[ key ];
|
||||
|
||||
if ( 'acl' === key ) {
|
||||
value = response.provider_object[ key ][ 'name' ];
|
||||
|
||||
if ( response.acl_toggle ) {
|
||||
var acl_template = _.template( '<a href="#" id="as3cfpro-toggle-acl" title="<%= title %>" data-currentACL="<%= acl %>"><%= value %></a>' );
|
||||
|
||||
value = acl_template( {
|
||||
title: response.provider_object[ key ][ 'title' ],
|
||||
acl: response.provider_object[ key ][ 'acl' ],
|
||||
value: value
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'is_verified' === key ) {
|
||||
value = Boolean( parseInt( value ) );
|
||||
|
||||
if ( value ) {
|
||||
return;
|
||||
}
|
||||
|
||||
value = as3cf_media.strings[ 'not_verified' ];
|
||||
}
|
||||
|
||||
html += template( {
|
||||
key: key,
|
||||
label: as3cf_media.strings[ key ],
|
||||
value: value
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
confirmS3Removal: function( event ) {
|
||||
if ( ! confirm( as3cfpro_media.strings.local_warning ) ) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
toggleACL: function( event ) {
|
||||
event.preventDefault();
|
||||
|
||||
var toggle = $( '#as3cfpro-toggle-acl' );
|
||||
var currentACL = toggle.data( 'currentacl' );
|
||||
var newACL = as3cfpro_media.settings.private_acl;
|
||||
|
||||
toggle.hide();
|
||||
toggle.after( '<span id="as3cfpro-updating">' + as3cfpro_media.strings.updating_acl + '</span>' );
|
||||
|
||||
if ( currentACL === as3cfpro_media.settings.private_acl ) {
|
||||
newACL = as3cfpro_media.settings.default_acl;
|
||||
}
|
||||
|
||||
wp.ajax.send( 'as3cfpro_update_acl', {
|
||||
data: {
|
||||
_ajax_nonce: as3cfpro_media.nonces.singular_update_acl,
|
||||
id: this.model.get( 'id' ),
|
||||
acl: newACL
|
||||
}
|
||||
} )
|
||||
.done( _.bind( this.updateACL, this ) )
|
||||
.fail( _.bind( this.renderACLError, this ) );
|
||||
},
|
||||
|
||||
renderACLError: function() {
|
||||
$( '#as3cfpro-updating' ).remove();
|
||||
$( '#as3cfpro-toggle-acl' ).show();
|
||||
alert( as3cfpro_media.strings.change_acl_error );
|
||||
},
|
||||
|
||||
updateACL: function( response ) {
|
||||
if ( null == response.acl_display || null == response.title || null == response.acl || null == response.url ) {
|
||||
this.renderACLError();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.model.set( 'url', response.url );
|
||||
this.render();
|
||||
|
||||
var toggle = $( '#as3cfpro-toggle-acl' );
|
||||
|
||||
$( '#as3cfpro-updating' ).remove();
|
||||
|
||||
toggle.text( response.acl_display );
|
||||
toggle.attr( 'title', response.title );
|
||||
toggle.data( 'currentacl', response.acl );
|
||||
toggle.show();
|
||||
}
|
||||
} );
|
||||
|
||||
} )( jQuery, _ );
|
||||
Reference in New Issue
Block a user