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
1 line
6.2 KiB
JavaScript
1 line
6.2 KiB
JavaScript
(function($,_){var media=wp.media;media.view.OffloadButton=media.view.Button.extend({defaults:{text:"",style:"primary",size:"large",disabled:false},initialize:function(options){if(options){this.options=options;this.defaults.text=as3cfpro_media.strings[this.options.action]}this.options=_.extend({},this.defaults,this.options);media.view.Button.prototype.initialize.apply(this,arguments);this.controller.on("selection:toggle",this.toggleDisabled,this);this.controller.on("select:activate",this.toggleDisabled,this)},render:function(){media.view.Button.prototype.render.apply(this,arguments);this.toggleDisabled();return this},toggleDisabled:function(){var selection=this.controller.state().get("selection").length>0;if(!selection){this.$el.addClass("disabled")}else{this.$el.removeClass("disabled")}},click:function(e){e.preventDefault();var selection=this.controller.state().get("selection");var models=selection.models;var library=this.controller.state().get("library");if(this.$el.hasClass("disabled")||!selection.length){return}var payload={_ajax_nonce:as3cfpro_media.nonces[this.options.scope+"_"+this.options.action],scope:this.options.scope,s3_action:this.options.action,ids:_.pluck(models,"id")};this.startOffloadAction();this.fireOffloadAction(payload).done((function(){_.each(models,(function(model){model.fetch()}));library._requery(true)}))},startOffloadAction:function(){$(".media-toolbar .spinner").css("visibility","visible").show();$(".media-toolbar-secondary .button").addClass("disabled");$(".offload-buttons__submenu").addClass("hidden")},fireOffloadAction:function(payload){return wp.ajax.send("as3cfpro_process_media_action",{data:payload}).done(_.bind(this.returnOffloadAction,this))},returnOffloadAction:function(response){if(response&&""!==response){$(".as3cf-notice").remove();$("#wp-media-grid h1").after(response)}this.controller.trigger("selection:action:done");$(".media-toolbar .spinner").attr("style","").hide()}});media.view.OffloadToggle=media.view.Button.extend({className:"offload-buttons__toggle",defaults:{style:"primary",size:"large",priority:-80,disabled:true},initialize:function(){media.view.Button.prototype.initialize.apply(this,arguments);this.controller.on("selection:toggle",this.toggleDisabled,this);this.controller.on("select:activate",this.toggleDisabled,this);$("body").on("click",this.blur);return this},click:function(e){e.preventDefault();if(this.$el.hasClass("disabled")){return}var toolbar=this.controller.content.get().toolbar;this.$el.toggleClass("opened");toolbar.$(".offload-buttons__submenu").toggleClass("hidden")},blur:function(){var $toggle=$(".media-toolbar .offload-buttons__toggle");var $submenu=$(".media-toolbar .offload-buttons__submenu");if($toggle.hasClass("opened")&&!$submenu.parent().is(":active, :hover")){$submenu.addClass("hidden");$toggle.removeClass("opened")}},toggleDisabled:function(){var selection=this.controller.state().get("selection").length>0;this.model.set("disabled",!selection);if(!selection){this.$el.addClass("disabled")}else{this.$el.removeClass("disabled")}}});var wpSelectModeToggleButton=media.view.SelectModeToggleButton;media.view.SelectModeToggleButton=wpSelectModeToggleButton.extend({toggleBulkEditHandler:function(){wpSelectModeToggleButton.prototype.toggleBulkEditHandler.call(this,arguments);var $toolbar=this.controller.content.get().toolbar;var $buttons=$toolbar.$(".offload-buttons");var $submenu=$buttons.find(".offload-buttons__submenu");if(this.controller.isModeActive("select")){$buttons.addClass("visible")}else{$buttons.removeClass("visible")}if($submenu.length){$buttons.width($submenu.outerWidth())}}});media.view.OffloadLocationFilter=wp.media.view.AttachmentFilters.extend({id:"media-attachment-as3cf-location-filter",initialize:function(){this.createFilters();_.extend(this.filters,this.options.filters);var html="";_(as3cfpro_media.filters.as3cf_location.options).each((function(option,key){if(typeof option==="string"){html+=$("<option></option>").val(key).html(option).wrap("<p>").parent().html()}else{html+='<optgroup label="'+key+'">';_(option).each((function(sub_option,sub_key){html+=$("<option></option>").val(sub_key).html(sub_option).wrap("<p>").parent().html()}));html+="</optgroup>"}}));this.$el.html(html);this.listenTo(this.model,"change",this.select);this.select()},createFilters:function(){var filters={};_(as3cfpro_media.filters.as3cf_location.options).each((function(option,key){if(typeof option==="string"){filters[key]={text:option,props:{as3cf_location:key},priority:10}}else{_(option).each((function(sub_option,sub_key){filters[sub_key]={text:sub_option,props:{as3cf_location:sub_key},priority:10}}))}}));this.filters=filters}});media.view.OffloadAccessFilter=wp.media.view.AttachmentFilters.extend({id:"media-attachment-as3cf-access-filter",createFilters:function(){var filters={};_(as3cfpro_media.filters.as3cf_access.options).each((function(value,key){filters[key]={text:value,props:{as3cf_access:key},priority:10}}));this.filters=filters}});var wpAttachmentsBrowser=media.view.AttachmentsBrowser;media.view.AttachmentsBrowser=wpAttachmentsBrowser.extend({createToolbar:function(){wpAttachmentsBrowser.prototype.createToolbar.call(this);var default_button_action=as3cfpro_media.actions.bulk.shift();var default_button=new media.view.OffloadButton({action:default_button_action,classes:"offload-buttons__action-default",scope:"bulk",controller:this.controller}).render();if(as3cfpro_media.actions.bulk.length){var buttons=[];_(as3cfpro_media.actions.bulk).each(function(action){buttons.push(new media.view.OffloadButton({action:action,classes:"offload-buttons__action",scope:"bulk",controller:this.controller}).render())}.bind(this));var dropdown_toggle=new media.view.OffloadToggle({controller:this.controller}).render();var buttons_submenu=new media.view.ButtonGroup({buttons:buttons,classes:"offload-buttons__submenu hidden"}).render();this.toolbar.set("OffloadButtons",new media.view.ButtonGroup({buttons:[default_button,buttons_submenu,dropdown_toggle],classes:"offload-buttons",priority:-80}))}this.toolbar.set("offloadLocationFilter",new media.view.OffloadLocationFilter({controller:this.controller,model:this.collection.props,priority:-75}));this.toolbar.set("offloadAccessFilter",new media.view.OffloadAccessFilter({controller:this.controller,model:this.collection.props,priority:-75}));this.toolbar.render()}})})(jQuery,_); |