Files
WPS3Media/assets/js/media.js
Malin 3248cbb029 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
2026-03-03 12:30:18 +01:00

174 lines
4.6 KiB
JavaScript

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, _ );