Version Description
- 2015-08-27 =
- New: Update all existing attachments with missing file sizes when the 'Remove Files From Server' option is enabled (automatically runs in the background)
- Improvement: Show when constants are used to set bucket and region options
- Improvement: Don't show compatibility notices on plugin update screen
- Improvement: On Multisite installs don't call
restore_current_blog()
on successive loop iterations - Bug fix: 'Error getting URL preview' alert shown when enter key pressed on settings screen
- Bug fix: Unable to crop header images when the 'Remove Files From Server' option is enabled
- Bug fix: Incorrect storage space shown on Multisite installs when the 'Remove Files From Server' option is enabled
- Bug fix: Upload attempted to non existent bucket when defined by constant
- Bug fix: 'SignatureDoesNotMatch' error shown when using signed URLs with bucket names containing '.' characters
Download this release
Release Info
Developer | deliciousbrains |
Plugin | WP Offload S3 Lite |
Version | 0.9.4 |
Comparing to | |
See all releases |
Code changes from version 0.9.3 to 0.9.4
- README.md +20 -8
- assets/js/modal.js +27 -105
- assets/js/modal.min.js +1 -1
- assets/js/script.js +13 -0
- assets/js/script.min.js +1 -1
- classes/amazon-s3-and-cloudfront.php +298 -46
- classes/as3cf-plugin-compatibility.php +102 -5
- classes/as3cf-upgrade.php +244 -242
- classes/upgrades/as3cf-file-sizes.php +215 -0
- classes/upgrades/as3cf-region-meta.php +145 -0
- classes/wp-aws-compatibility-check.php +48 -16
- classes/wp-aws-uninstall.php +77 -39
- composer.lock +0 -107
- languages/amazon-s3-and-cloudfront-en.pot +170 -144
- languages/as3cf-pt-br.mo +0 -0
- readme.txt +20 -8
- uninstall.php +23 -4
- view/bucket-select.php +16 -10
- view/bucket-setting.php +4 -2
- view/sidebar.php +0 -6
- wordpress-s3.php +7 -5
README.md
CHANGED
@@ -1,10 +1,9 @@
|
|
1 |
# WP Offload S3 #
|
2 |
-
**Contributors:** bradt
|
3 |
-
**Donate link:** https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
|
4 |
**Tags:** uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
|
5 |
**Requires at least:** 3.7
|
6 |
**Tested up to:** 4.3
|
7 |
-
**Stable tag:** 0.9.
|
8 |
**License:** GPLv3
|
9 |
|
10 |
Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
|
@@ -17,19 +16,21 @@ This plugin automatically copies images, videos, documents, and any other media
|
|
17 |
|
18 |
Uploading files *directly* to your S3 account is not currently supported by this plugin. They are uploaded to your server first, then copied to S3. There is an option to automatically remove the files from your server once they are copied to S3 however.
|
19 |
|
20 |
-
If you're adding this plugin to a site that's been around for a while, your existing media files will not be copied or served from S3. Only newly uploaded files will be copied and served from S3.
|
21 |
|
22 |
**PRO Upgrade with Email Support and More Features**
|
23 |
|
24 |
* Upload existing Media Library to S3
|
25 |
* Find & replace file URLs in content
|
26 |
* Control S3 files from the Media Library
|
27 |
-
* [Assets addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=
|
28 |
-
* [WooCommerce addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=
|
29 |
-
* [Easy Digital Downloads addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=
|
30 |
* PriorityExpert™ email support
|
31 |
|
32 |
-
|
|
|
|
|
33 |
|
34 |
https://www.youtube.com/watch?v=55xNGnbJ_CY
|
35 |
|
@@ -66,6 +67,17 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
|
|
66 |
|
67 |
## Changelog ##
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
### 0.9.3 - 2015-08-17 ###
|
70 |
* New: Pro upgrade sidebar
|
71 |
* Bug fix: Create buckets in US standard region causing S3 URLs to 404 errors
|
1 |
# WP Offload S3 #
|
2 |
+
**Contributors:** bradt, deliciousbrains
|
|
|
3 |
**Tags:** uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
|
4 |
**Requires at least:** 3.7
|
5 |
**Tested up to:** 4.3
|
6 |
+
**Stable tag:** 0.9.4
|
7 |
**License:** GPLv3
|
8 |
|
9 |
Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
|
16 |
|
17 |
Uploading files *directly* to your S3 account is not currently supported by this plugin. They are uploaded to your server first, then copied to S3. There is an option to automatically remove the files from your server once they are copied to S3 however.
|
18 |
|
19 |
+
If you're adding this plugin to a site that's been around for a while, your existing media files will not be copied or served from S3. Only newly uploaded files will be copied and served from S3. The pro upgrade has an upload tool to handle existing media files.
|
20 |
|
21 |
**PRO Upgrade with Email Support and More Features**
|
22 |
|
23 |
* Upload existing Media Library to S3
|
24 |
* Find & replace file URLs in content
|
25 |
* Control S3 files from the Media Library
|
26 |
+
* [Assets addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin#assets-addon) - Serve your CSS & JS from S3/CloudFront
|
27 |
+
* [WooCommerce addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin#woocommerce-addon)
|
28 |
+
* [Easy Digital Downloads addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin#edd-addon)
|
29 |
* PriorityExpert™ email support
|
30 |
|
31 |
+
[Compare pro vs free →](http://deliciousbrains.com/wp-offload-s3/upgrade/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin)
|
32 |
+
|
33 |
+
The video below runs through the pro upgrade features...
|
34 |
|
35 |
https://www.youtube.com/watch?v=55xNGnbJ_CY
|
36 |
|
67 |
|
68 |
## Changelog ##
|
69 |
|
70 |
+
### 0.9.4 - 2015-08-27 ###
|
71 |
+
* New: Update all existing attachments with missing file sizes when the 'Remove Files From Server' option is enabled (automatically runs in the background)
|
72 |
+
* Improvement: Show when constants are used to set bucket and region options
|
73 |
+
* Improvement: Don't show compatibility notices on plugin update screen
|
74 |
+
* Improvement: On Multisite installs don't call `restore_current_blog()` on successive loop iterations
|
75 |
+
* Bug fix: 'Error getting URL preview' alert shown when enter key pressed on settings screen
|
76 |
+
* Bug fix: Unable to crop header images when the 'Remove Files From Server' option is enabled
|
77 |
+
* Bug fix: Incorrect storage space shown on Multisite installs when the 'Remove Files From Server' option is enabled
|
78 |
+
* Bug fix: Upload attempted to non existent bucket when defined by constant
|
79 |
+
* Bug fix: 'SignatureDoesNotMatch' error shown when using signed URLs with bucket names containing '.' characters
|
80 |
+
|
81 |
### 0.9.3 - 2015-08-17 ###
|
82 |
* New: Pro upgrade sidebar
|
83 |
* Bug fix: Create buckets in US standard region causing S3 URLs to 404 errors
|
assets/js/modal.js
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
var as3cfModal = (function ( $ ) {
|
2 |
|
3 |
var modal = {
|
4 |
-
prefix: 'as3cf'
|
|
|
5 |
};
|
6 |
|
7 |
var modals = {};
|
@@ -9,9 +10,9 @@ var as3cfModal = (function ( $ ) {
|
|
9 |
/**
|
10 |
* Target to key
|
11 |
*
|
12 |
-
* @param string target
|
13 |
*
|
14 |
-
* @return string
|
15 |
*/
|
16 |
function targetToKey( target ) {
|
17 |
return target.replace( /[^a-z]/g, '' );
|
@@ -20,10 +21,11 @@ var as3cfModal = (function ( $ ) {
|
|
20 |
/**
|
21 |
* Open modal
|
22 |
*
|
23 |
-
* @param string target
|
24 |
-
* @param function callback
|
|
|
25 |
*/
|
26 |
-
modal.open = function ( target, callback ) {
|
27 |
var key = targetToKey( target );
|
28 |
|
29 |
// Overlay
|
@@ -41,6 +43,10 @@ var as3cfModal = (function ( $ ) {
|
|
41 |
}
|
42 |
$modal.data( 'as3cf-modal-target', target ).append( modals[ key ] );
|
43 |
|
|
|
|
|
|
|
|
|
44 |
if ( 'function' === typeof callback ) {
|
45 |
callback( target );
|
46 |
}
|
@@ -58,9 +64,13 @@ var as3cfModal = (function ( $ ) {
|
|
58 |
/**
|
59 |
* Close modal
|
60 |
*
|
61 |
-
* @param function callback
|
62 |
*/
|
63 |
modal.close = function ( callback ) {
|
|
|
|
|
|
|
|
|
64 |
var target = $( '#as3cf-modal' ).data( 'as3cf-modal-target' );
|
65 |
|
66 |
$( '#as3cf-overlay' ).fadeOut( 150, function () {
|
@@ -76,6 +86,15 @@ var as3cfModal = (function ( $ ) {
|
|
76 |
$( 'body' ).trigger( 'as3cf-modal-close', [ target ] );
|
77 |
};
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
// Setup click handlers
|
80 |
$( document ).ready( function () {
|
81 |
|
@@ -99,101 +118,4 @@ var as3cfModal = (function ( $ ) {
|
|
99 |
|
100 |
return modal;
|
101 |
|
102 |
-
})( jQuery );
|
103 |
-
|
104 |
-
var as3cfFindAndReplaceModal = (function ( $, as3cfModal ) {
|
105 |
-
|
106 |
-
var modal = {
|
107 |
-
selector: '.as3cf-find-replace-container',
|
108 |
-
isBulk: false,
|
109 |
-
link: null,
|
110 |
-
payload: {}
|
111 |
-
};
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Open modal
|
115 |
-
*
|
116 |
-
* @param string link
|
117 |
-
* @param mixed payload
|
118 |
-
*/
|
119 |
-
modal.open = function ( link, payload ) {
|
120 |
-
if ( typeof link !== 'undefined' ) {
|
121 |
-
modal.link = link;
|
122 |
-
}
|
123 |
-
if ( typeof payload !== 'undefined' ) {
|
124 |
-
modal.payload = payload;
|
125 |
-
}
|
126 |
-
|
127 |
-
as3cfModal.open( modal.selector );
|
128 |
-
|
129 |
-
$( modal.selector ).find( '.single-file' ).show();
|
130 |
-
$( modal.selector ).find( '.multiple-files' ).hide();
|
131 |
-
if ( modal.isBulk ) {
|
132 |
-
$( modal.selector ).find( '.single-file' ).hide();
|
133 |
-
$( modal.selector ).find( '.multiple-files' ).show();
|
134 |
-
}
|
135 |
-
};
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Close modal
|
139 |
-
*/
|
140 |
-
modal.close = function () {
|
141 |
-
as3cfModal.close( modal.selector );
|
142 |
-
};
|
143 |
-
|
144 |
-
/**
|
145 |
-
* Set the isBulk flag
|
146 |
-
*/
|
147 |
-
modal.setBulk = function ( isBulk ) {
|
148 |
-
modal.isBulk = isBulk;
|
149 |
-
};
|
150 |
-
|
151 |
-
/**
|
152 |
-
* Create the loading state
|
153 |
-
*/
|
154 |
-
modal.startLoading = function () {
|
155 |
-
$( modal.selector + ' [data-find-replace]' ).prop( 'disabled', true ).siblings( '.spinner' ).css( 'visibility', 'visible' ).show();
|
156 |
-
};
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Remove the loading state
|
160 |
-
*/
|
161 |
-
modal.stopLoading = function () {
|
162 |
-
$( modal.selector + ' [data-find-replace]' ).prop( 'disabled', false ).siblings( '.spinner' ).css( 'visibility', 'hidden' ).hide();
|
163 |
-
};
|
164 |
-
|
165 |
-
// Setup click handlers
|
166 |
-
$( document ).ready( function () {
|
167 |
-
|
168 |
-
$( 'body' ).on( 'click', modal.selector + ' [data-find-replace]', function ( e ) {
|
169 |
-
var findAndReplace = $( this ).data( 'find-replace' );
|
170 |
-
|
171 |
-
if ( !modal.link ) {
|
172 |
-
// If there is no link set then this must be an AJAX
|
173 |
-
// request so trigger an event instead
|
174 |
-
$( modal.selector ).trigger( 'as3cf-find-and-replace', [ findAndReplace, modal.payload ] );
|
175 |
-
return;
|
176 |
-
}
|
177 |
-
|
178 |
-
if ( findAndReplace ) {
|
179 |
-
modal.link += '&find_and_replace=1';
|
180 |
-
}
|
181 |
-
|
182 |
-
modal.startLoading();
|
183 |
-
|
184 |
-
window.location = modal.link;
|
185 |
-
} );
|
186 |
-
|
187 |
-
$( 'body' ).on( 'as3cf-modal-close', function ( e ) {
|
188 |
-
modal.isBulk = false;
|
189 |
-
modal.link = null;
|
190 |
-
modal.payload = {};
|
191 |
-
} );
|
192 |
-
|
193 |
-
} );
|
194 |
-
|
195 |
-
return modal;
|
196 |
-
|
197 |
-
})( jQuery, as3cfModal );
|
198 |
-
|
199 |
-
|
1 |
var as3cfModal = (function ( $ ) {
|
2 |
|
3 |
var modal = {
|
4 |
+
prefix: 'as3cf',
|
5 |
+
loading: false
|
6 |
};
|
7 |
|
8 |
var modals = {};
|
10 |
/**
|
11 |
* Target to key
|
12 |
*
|
13 |
+
* @param {string} target
|
14 |
*
|
15 |
+
* @return {string}
|
16 |
*/
|
17 |
function targetToKey( target ) {
|
18 |
return target.replace( /[^a-z]/g, '' );
|
21 |
/**
|
22 |
* Open modal
|
23 |
*
|
24 |
+
* @param {string} target
|
25 |
+
* @param {function} callback
|
26 |
+
* @param {string} customClass
|
27 |
*/
|
28 |
+
modal.open = function ( target, callback, customClass ) {
|
29 |
var key = targetToKey( target );
|
30 |
|
31 |
// Overlay
|
43 |
}
|
44 |
$modal.data( 'as3cf-modal-target', target ).append( modals[ key ] );
|
45 |
|
46 |
+
if ( undefined !== customClass ) {
|
47 |
+
$modal.addClass( customClass );
|
48 |
+
}
|
49 |
+
|
50 |
if ( 'function' === typeof callback ) {
|
51 |
callback( target );
|
52 |
}
|
64 |
/**
|
65 |
* Close modal
|
66 |
*
|
67 |
+
* @param {function} callback
|
68 |
*/
|
69 |
modal.close = function ( callback ) {
|
70 |
+
if ( modal.loading ) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
var target = $( '#as3cf-modal' ).data( 'as3cf-modal-target' );
|
75 |
|
76 |
$( '#as3cf-overlay' ).fadeOut( 150, function () {
|
86 |
$( 'body' ).trigger( 'as3cf-modal-close', [ target ] );
|
87 |
};
|
88 |
|
89 |
+
/**
|
90 |
+
* Set loading state
|
91 |
+
*
|
92 |
+
* @param {bool} state
|
93 |
+
*/
|
94 |
+
modal.setLoadingState = function ( state ) {
|
95 |
+
modal.loading = state;
|
96 |
+
};
|
97 |
+
|
98 |
// Setup click handlers
|
99 |
$( document ).ready( function () {
|
100 |
|
118 |
|
119 |
return modal;
|
120 |
|
121 |
+
})( jQuery );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assets/js/modal.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
var as3cfModal=function(a){function b(a){return a.replace(/[^a-z]/g,"")}var c={prefix:"as3cf"},d={};return c.open=function(c,e){var
|
1 |
+
var as3cfModal=function(a){function b(a){return a.replace(/[^a-z]/g,"")}var c={prefix:"as3cf",loading:!1},d={};return c.open=function(c,e,f){var g=b(c);a("body").append('<div id="as3cf-overlay"></div>');var h=a("#as3cf-overlay");h.append('<div id="as3cf-modal"><span class="close-as3cf-modal">×</span></div>');var i=a("#as3cf-modal");if(void 0===d[g]){var j=a(c);d[g]=j.clone(!0).css("display","block"),j.remove()}i.data("as3cf-modal-target",c).append(d[g]),void 0!==f&&i.addClass(f),"function"==typeof e&&e(c),a("body").addClass("as3cf-modal-open"),h.fadeIn(150),i.fadeIn(150),a("body").trigger("as3cf-modal-open",[c])},c.close=function(b){if(!c.loading){var d=a("#as3cf-modal").data("as3cf-modal-target");a("#as3cf-overlay").fadeOut(150,function(){"function"==typeof b&&b(d),a("body").removeClass("as3cf-modal-open"),a(this).remove()}),a("body").trigger("as3cf-modal-close",[d])}},c.setLoadingState=function(a){c.loading=a},a(document).ready(function(){a("body").on("click","[data-as3cf-modal]",function(b){b.preventDefault(),c.open(a(this).data("as3cf-modal")+"."+c.prefix)}),a("body").on("click","#as3cf-overlay, .close-as3cf-modal",function(a){return a.preventDefault(),a.target!==this?!1:void c.close()})}),c}(jQuery);
|
assets/js/script.js
CHANGED
@@ -358,6 +358,9 @@
|
|
358 |
savedSettings[ id ] = serializedForm( id );
|
359 |
}
|
360 |
|
|
|
|
|
|
|
361 |
$activeBucket.text( bucket );
|
362 |
$manualBucketForm.find( '.as3cf-bucket-name' ).val( bucket );
|
363 |
$( '#' + as3cfModal.prefix + '-bucket' ).val( bucket );
|
@@ -627,6 +630,16 @@
|
|
627 |
generateUrlPreview();
|
628 |
} );
|
629 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
630 |
// Bucket select
|
631 |
// --------------------
|
632 |
|
358 |
savedSettings[ id ] = serializedForm( id );
|
359 |
}
|
360 |
|
361 |
+
// Remove previous permission errors
|
362 |
+
$( '.as3cf-error.fatal' ).hide();
|
363 |
+
|
364 |
$activeBucket.text( bucket );
|
365 |
$manualBucketForm.find( '.as3cf-bucket-name' ).val( bucket );
|
366 |
$( '#' + as3cfModal.prefix + '-bucket' ).val( bucket );
|
630 |
generateUrlPreview();
|
631 |
} );
|
632 |
|
633 |
+
// Don't allow 'enter' key to submit form on text input settings
|
634 |
+
$( '.as3cf-setting input[type="text"]' ).keypress( function( event ) {
|
635 |
+
if ( 13 === event.which ) {
|
636 |
+
event.preventDefault();
|
637 |
+
|
638 |
+
return false;
|
639 |
+
}
|
640 |
+
|
641 |
+
} );
|
642 |
+
|
643 |
// Bucket select
|
644 |
// --------------------
|
645 |
|
assets/js/script.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
!function(a,b){function c(b){return a("#"+b+" .as3cf-main-settings form").find("input:not(.no-compare)").serialize()}function d(b){var c=a("#"+b),d=c.find("input[type=checkbox]");c.toggleClass("on").find("span").toggleClass("checked");var e=c.find("span.on").hasClass("checked");d.attr("checked",e).trigger("change")}function e(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-"+as3cf.tabs.defaultTab+" .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function f(){as3cf.buckets.bucketSelectLock=!1}var g,h={},i=/[^a-z0-9.-]/,j=a(".as3cf-tab");as3cf.tabs={defaultTab:"media",toggle:function(c,d){j.hide(),g=a("#tab-"+c),g.show(),a(".nav-tab").removeClass("nav-tab-active"),a('a.nav-tab[data-tab="'+c+'"]').addClass("nav-tab-active"),a(".aws-main").attr("data-tab",c),g.attr("data-prefix")&&(b.prefix=g.attr("data-prefix")),d||a(".as3cf-updated").removeClass("show")}},as3cf.buckets={validLength:3,bucketSelectLock:!1,loadList:function(c){"undefined"==typeof c&&(c=!1);var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-list"),e=a("#"+b.prefix+"-bucket").val();if(!1===c&&d.find("li").length>1)return a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"),void this.scrollToSelected();d.html('<li class="loading">'+d.attr("data-working")+"</li>");var f={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets},g=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:f,error:function(a,b,c){d.html(""),g.showError(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),g.scrollToSelected()):g.showError(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})},scrollToSelected:function(){if(a(".as3cf-bucket-list a.selected").length){var b=a("ul.as3cf-bucket-list li").first().position().top+150;a(".as3cf-bucket-list").animate({scrollTop:a("ul.as3cf-bucket-list li a.selected").position().top-b})}},resetModal:function(){var c=a(".as3cf-bucket-container."+b.prefix);!1===g.hasClass("as3cf-has-bucket")||"manual"===a("#"+b.prefix+"-bucket-select").val()?(c.find(".as3cf-bucket-manual").show().siblings().hide(),c.find(".bucket-actions.manual").show().siblings(".bucket-actions").hide()):(c.find(".as3cf-bucket-select").show().siblings().hide(),c.find(".bucket-actions.select").show().siblings(".bucket-actions").hide(),this.loadList()),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d),this.bucketSelectLock=!1},saveManual:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find("button[type=submit]"),f=d.val(),h=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),g.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.attr("data-working")),e.prop("disabled",!0);var i={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){e.text(h),j.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c){e.text(h),e.prop("disabled",!1),"undefined"!=typeof c.success?(j.set(f,c.region,c.can_write),a("#"+b.prefix+"-bucket-select").val("manual"),a(".as3cf-bucket-list a").removeClass("selected").filter('[data-bucket="'+f+'"]').addClass("selected")):j.showError(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})},saveSelected:function(c){var d=a(".as3cf-bucket-list");if(!this.bucketSelectLock){if(this.bucketSelectLock=!0,c.hasClass("selected"))return g.addClass("as3cf-has-bucket"),void b.close();var e=a(".as3cf-bucket-list a.selected").attr("data-bucket");a(".as3cf-bucket-list a").removeClass("selected"),c.addClass("selected"),d.addClass("saving"),c.find(".spinner").show().css("visibility","visible");var f=c.attr("data-bucket"),h={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(b,c,f){d.removeClass("saving"),i.showError(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(i.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(i.showError(as3cf.strings.save_bucket_error,g.error,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"))}})}},disabledButtons:function(){if(0!==a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form").length){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").attr("disabled",!1),d.find(".as3cf-bucket-name").val().length<3?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").attr("disabled",!1)}},showError:function(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,(!d||e.hasClass(d))&&(f.find("span.title").html(b+" —"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(i,j,k){var l=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),m=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&""===m.text()){d("copy-to-s3-wrap"),d("serve-from-s3-wrap");var n=g.attr("id");h[n]=c(n)}m.text(i),l.find(".as3cf-bucket-name").val(i),a("#"+b.prefix+"-bucket").val(i),a("#"+b.prefix+"-region").val(j),a(".updated").not(".as3cf-notice").show(),g.addClass("as3cf-has-bucket"),g.find(".as3cf-can-write-error").toggle(!k),g.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&e(),b.close(f)},create:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find(".bucket-create-region"),f=c.find("button[type=submit]"),g=d.val(),h=f.text();a(".as3cf-bucket-error").hide(),f.text(f.attr("data-working")),f.prop("disabled",!0);var i={action:b.prefix+"-create-bucket",bucket_name:g,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.create_bucket};e.val()&&(i.region=e.val());var j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),j.showError(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(j.set(g,b.region,b.can_write),a(".as3cf-bucket-select-region").hide(),a(".as3cf-bucket-select-region").removeAttr("selected"),d.val(""),f.attr("disabled",!0)):j.showError(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})},isValidName:function(a){return a.length<3||a.length>63?!1:!0===i.test(a)?!1:!0},updateNameNotice:function(b){var c=null;!0===i.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),a(".as3cf-invalid-bucket-name").html(c&&b.length>0?c:"")}},a(document).ready(function(){var f=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(f),window.location.hash){var i=window.location.hash.substring(1);as3cf.tabs.toggle(i,!0)}else g=a("#tab-"+as3cf.tabs.defaultTab),a(".aws-main").attr("data-tab",as3cf.tabs.defaultTab);a(".aws-main").on("click",".nav-tab",function(b){if(b.preventDefault(),!a(this).hasClass("nav-tab-active")){var c=a(this).attr("data-tab");as3cf.tabs.toggle(c),"media"===c?(window.location.hash="","function"==typeof window.history.replaceState&&"#"===window.location.href.slice(-1)&&history.replaceState({},"",window.location.href.slice(0,-1))):window.location.hash=c}}),j.length&&j.each(function(a,b){h[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(h)){var b=g.attr("id");return c(b)!==h[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(){a(this).hasClass("disabled")||d(a(this).attr("id"))}),j.on("change",".sub-toggle",function(){var b=a(this).attr("id");a(".as3cf-setting."+b).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(){var b=a(this).closest('input:radio[name="domain"]:checked'),c=b.val(),d=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),e="cloudfront"===c;d.toggleClass("hide",!e)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(){var b=a('input:radio[name="ssl"]:checked').val();if("https"===b){var c=a('input:radio[name="domain"]:checked').val();"subdomain"===c&&a('input[name="domain"][value="path"]').attr("checked",!0),a(".subdomain-wrap input").attr("disabled",!0),a(".subdomain-wrap").addClass("disabled")}else a(".subdomain-wrap input").removeAttr("disabled"),a(".subdomain-wrap").removeClass("disabled")}),a(".url-preview").on("change","input",function(){e()}),a("#tab-media > .as3cf-bucket-error").detach().insertAfter(".as3cf-bucket-container h3"),a("body").on("click",".bucket-action-manual",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-manual").show().siblings().hide()}),a("body").on("click",".bucket-action-browse",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-select").show().siblings().hide(),as3cf.buckets.loadList()}),a("body").on("click",".bucket-action-create",function(c){c.preventDefault(),a(".as3cf-bucket-name").val(""),a(".as3cf-invalid-bucket-name").html(""),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-create").show().siblings().hide()}),a("body").on("click",".bucket-action-cancel",function(a){a.preventDefault(),as3cf.buckets.resetModal()}),a("body").on("click",".bucket-action-save",function(a){a.preventDefault(),as3cf.buckets.saveManual()}),a("body").on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),as3cf.buckets.create()}),a("body").on("click",".bucket-action-refresh",function(a){a.preventDefault(),as3cf.buckets.loadList(!0)}),a("body").on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),as3cf.buckets.saveSelected(a(this))}),a(".as3cf-bucket-container").on("click","a.js-link",function(b){return b.preventDefault(),window.open(a(this).attr("href")),!1}),a("body").on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){as3cf.buckets.resetModal();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),as3cf.buckets.disabledButtons()}}),as3cf.buckets.disabledButtons(),a("body").on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(){var c=a(this).val(),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(c)?d.find("button[type=submit]").removeAttr("disabled"):d.find("button[type=submit]").attr("disabled",!0),as3cf.buckets.updateNameNotice(c)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").removeAttr("disabled")})})}(jQuery,as3cfModal);
|
1 |
+
!function(a,b){function c(b){return a("#"+b+" .as3cf-main-settings form").find("input:not(.no-compare)").serialize()}function d(b){var c=a("#"+b),d=c.find("input[type=checkbox]");c.toggleClass("on").find("span").toggleClass("checked");var e=c.find("span.on").hasClass("checked");d.attr("checked",e).trigger("change")}function e(){a(".as3cf-url-preview").html("Generating...");var b={_nonce:as3cf.nonces.get_url_preview};a.each(a("#tab-"+as3cf.tabs.defaultTab+" .as3cf-main-settings form").serializeArray(),function(c,d){var e=d.name,f=d.value;e=e.replace("[]",""),b[e]=void 0===b[e]?f:a.isArray(b[e])?b[e].concat(f):[b[e],f]}),b.action="as3cf-get-url-preview",a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:b,error:function(a,b,c){alert(as3cf.strings.get_url_preview_error+c)},success:function(b){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function f(){as3cf.buckets.bucketSelectLock=!1}var g,h={},i=/[^a-z0-9.-]/,j=a(".as3cf-tab");as3cf.tabs={defaultTab:"media",toggle:function(c,d){j.hide(),g=a("#tab-"+c),g.show(),a(".nav-tab").removeClass("nav-tab-active"),a('a.nav-tab[data-tab="'+c+'"]').addClass("nav-tab-active"),a(".aws-main").attr("data-tab",c),g.attr("data-prefix")&&(b.prefix=g.attr("data-prefix")),d||a(".as3cf-updated").removeClass("show")}},as3cf.buckets={validLength:3,bucketSelectLock:!1,loadList:function(c){"undefined"==typeof c&&(c=!1);var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-list"),e=a("#"+b.prefix+"-bucket").val();if(!1===c&&d.find("li").length>1)return a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"),void this.scrollToSelected();d.html('<li class="loading">'+d.attr("data-working")+"</li>");var f={action:b.prefix+"-get-buckets",_nonce:window[b.prefix.replace(/-/g,"_")].nonces.get_buckets},g=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:f,error:function(a,b,c){d.html(""),g.showError(as3cf.strings.get_buckets_error,c,"as3cf-bucket-select")},success:function(b){d.html(""),"undefined"!=typeof b.success?(a(".as3cf-bucket-error").hide(),a(b.buckets).each(function(a,b){var c=b.Name===e?"selected":"";d.append('<li><a class="'+c+'" href="#" data-bucket="'+b.Name+'"><span class="bucket"><span class="dashicons dashicons-portfolio"></span> '+b.Name+'</span><span class="spinner"></span></span></a></li>')}),g.scrollToSelected()):g.showError(as3cf.strings.get_buckets_error,b.error,"as3cf-bucket-select")}})},scrollToSelected:function(){if(a(".as3cf-bucket-list a.selected").length){var b=a("ul.as3cf-bucket-list li").first().position().top+150;a(".as3cf-bucket-list").animate({scrollTop:a("ul.as3cf-bucket-list li a.selected").position().top-b})}},resetModal:function(){var c=a(".as3cf-bucket-container."+b.prefix);!1===g.hasClass("as3cf-has-bucket")||"manual"===a("#"+b.prefix+"-bucket-select").val()?(c.find(".as3cf-bucket-manual").show().siblings().hide(),c.find(".bucket-actions.manual").show().siblings(".bucket-actions").hide()):(c.find(".as3cf-bucket-select").show().siblings().hide(),c.find(".bucket-actions.select").show().siblings(".bucket-actions").hide(),this.loadList()),c.find(".as3cf-bucket-error").hide();var d=a("#"+b.prefix+"-bucket").val();c.find(".as3cf-bucket-manual .as3cf-bucket-name").val(d),this.bucketSelectLock=!1},saveManual:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find("button[type=submit]"),f=d.val(),h=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),g.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.attr("data-working")),e.prop("disabled",!0);var i={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){e.text(h),j.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c){e.text(h),e.prop("disabled",!1),"undefined"!=typeof c.success?(j.set(f,c.region,c.can_write),a("#"+b.prefix+"-bucket-select").val("manual"),a(".as3cf-bucket-list a").removeClass("selected").filter('[data-bucket="'+f+'"]').addClass("selected")):j.showError(as3cf.strings.save_bucket_error,c.error,"as3cf-bucket-manual")}})},saveSelected:function(c){var d=a(".as3cf-bucket-list");if(!this.bucketSelectLock){if(this.bucketSelectLock=!0,c.hasClass("selected"))return g.addClass("as3cf-has-bucket"),void b.close();var e=a(".as3cf-bucket-list a.selected").attr("data-bucket");a(".as3cf-bucket-list a").removeClass("selected"),c.addClass("selected"),d.addClass("saving"),c.find(".spinner").show().css("visibility","visible");var f=c.attr("data-bucket"),h={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(b,c,f){d.removeClass("saving"),i.showError(as3cf.strings.save_bucket_error,f,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected")},success:function(g){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(i.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(i.showError(as3cf.strings.save_bucket_error,g.error,"as3cf-bucket-select"),a(".as3cf-bucket-list a").removeClass("selected"),a('.as3cf-bucket-list a[data-bucket="'+e+'"]').addClass("selected"))}})}},disabledButtons:function(){if(0!==a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form").length){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<3?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").attr("disabled",!1),d.find(".as3cf-bucket-name").val().length<3?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").attr("disabled",!1)}},showError:function(b,c,d){var e=a(".as3cf-bucket-container").children(":visible"),f=e.find(".as3cf-bucket-error");d="undefined"==typeof d?null:d,(!d||e.hasClass(d))&&(f.find("span.title").html(b+" —"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(i,j,k){var l=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),m=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&""===m.text()){d("copy-to-s3-wrap"),d("serve-from-s3-wrap");var n=g.attr("id");h[n]=c(n)}a(".as3cf-error.fatal").hide(),m.text(i),l.find(".as3cf-bucket-name").val(i),a("#"+b.prefix+"-bucket").val(i),a("#"+b.prefix+"-region").val(j),a(".updated").not(".as3cf-notice").show(),g.addClass("as3cf-has-bucket"),g.find(".as3cf-can-write-error").toggle(!k),g.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&e(),b.close(f)},create:function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form"),d=c.find(".as3cf-bucket-name"),e=c.find(".bucket-create-region"),f=c.find("button[type=submit]"),g=d.val(),h=f.text();a(".as3cf-bucket-error").hide(),f.text(f.attr("data-working")),f.prop("disabled",!0);var i={action:b.prefix+"-create-bucket",bucket_name:g,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.create_bucket};e.val()&&(i.region=e.val());var j=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:i,error:function(a,b,c){f.text(h),j.showError(as3cf.strings.create_bucket_error,c,"as3cf-bucket-create")},success:function(b){f.text(h),f.prop("disabled",!1),"undefined"!=typeof b.success?(j.set(g,b.region,b.can_write),a(".as3cf-bucket-select-region").hide(),a(".as3cf-bucket-select-region").removeAttr("selected"),d.val(""),f.attr("disabled",!0)):j.showError(as3cf.strings.create_bucket_error,b.error,"as3cf-bucket-create")}})},isValidName:function(a){return a.length<3||a.length>63?!1:!0===i.test(a)?!1:!0},updateNameNotice:function(b){var c=null;!0===i.test(b)?c=as3cf.strings.create_bucket_invalid_chars:b.length<3?c=as3cf.strings.create_bucket_name_short:b.length>63&&(c=as3cf.strings.create_bucket_name_long),a(".as3cf-invalid-bucket-name").html(c&&b.length>0?c:"")}},a(document).ready(function(){var f=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(f),window.location.hash){var i=window.location.hash.substring(1);as3cf.tabs.toggle(i,!0)}else g=a("#tab-"+as3cf.tabs.defaultTab),a(".aws-main").attr("data-tab",as3cf.tabs.defaultTab);a(".aws-main").on("click",".nav-tab",function(b){if(b.preventDefault(),!a(this).hasClass("nav-tab-active")){var c=a(this).attr("data-tab");as3cf.tabs.toggle(c),"media"===c?(window.location.hash="","function"==typeof window.history.replaceState&&"#"===window.location.href.slice(-1)&&history.replaceState({},"",window.location.href.slice(0,-1))):window.location.hash=c}}),j.length&&j.each(function(a,b){h[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(h)){var b=g.attr("id");return c(b)!==h[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(){a(this).hasClass("disabled")||d(a(this).attr("id"))}),j.on("change",".sub-toggle",function(){var b=a(this).attr("id");a(".as3cf-setting."+b).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(){var b=a(this).closest('input:radio[name="domain"]:checked'),c=b.val(),d=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),e="cloudfront"===c;d.toggleClass("hide",!e)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(){var b=a('input:radio[name="ssl"]:checked').val();if("https"===b){var c=a('input:radio[name="domain"]:checked').val();"subdomain"===c&&a('input[name="domain"][value="path"]').attr("checked",!0),a(".subdomain-wrap input").attr("disabled",!0),a(".subdomain-wrap").addClass("disabled")}else a(".subdomain-wrap input").removeAttr("disabled"),a(".subdomain-wrap").removeClass("disabled")}),a(".url-preview").on("change","input",function(){e()}),a('.as3cf-setting input[type="text"]').keypress(function(a){return 13===a.which?(a.preventDefault(),!1):void 0}),a("#tab-media > .as3cf-bucket-error").detach().insertAfter(".as3cf-bucket-container h3"),a("body").on("click",".bucket-action-manual",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-manual").show().siblings().hide()}),a("body").on("click",".bucket-action-browse",function(c){c.preventDefault(),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-select").show().siblings().hide(),as3cf.buckets.loadList()}),a("body").on("click",".bucket-action-create",function(c){c.preventDefault(),a(".as3cf-bucket-name").val(""),a(".as3cf-invalid-bucket-name").html(""),a(".as3cf-bucket-container."+b.prefix+" .as3cf-bucket-create").show().siblings().hide()}),a("body").on("click",".bucket-action-cancel",function(a){a.preventDefault(),as3cf.buckets.resetModal()}),a("body").on("click",".bucket-action-save",function(a){a.preventDefault(),as3cf.buckets.saveManual()}),a("body").on("click",'.as3cf-create-bucket-form button[type="submit"]',function(a){a.preventDefault(),as3cf.buckets.create()}),a("body").on("click",".bucket-action-refresh",function(a){a.preventDefault(),as3cf.buckets.loadList(!0)}),a("body").on("click",".as3cf-bucket-list a",function(b){b.preventDefault(),as3cf.buckets.saveSelected(a(this))}),a(".as3cf-bucket-container").on("click","a.js-link",function(b){return b.preventDefault(),window.open(a(this).attr("href")),!1}),a("body").on("as3cf-modal-open",function(c,d){if(".as3cf-bucket-container."+b.prefix===d){as3cf.buckets.resetModal();var e=a(".as3cf-bucket-manual h3").data("modal-title");a(".as3cf-bucket-manual h3").text(e),as3cf.buckets.disabledButtons()}}),as3cf.buckets.disabledButtons(),a("body").on("input keyup",".as3cf-create-bucket-form .as3cf-bucket-name",function(){var c=a(this).val(),d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(c)?d.find("button[type=submit]").removeAttr("disabled"):d.find("button[type=submit]").attr("disabled",!0),as3cf.buckets.updateNameNotice(c)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(){var c=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");c.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?c.find("button[type=submit]").attr("disabled",!0):c.find("button[type=submit]").removeAttr("disabled")})})}(jQuery,as3cfModal);
|
classes/amazon-s3-and-cloudfront.php
CHANGED
@@ -43,7 +43,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
43 |
protected $default_tab = '';
|
44 |
|
45 |
/**
|
46 |
-
* @var
|
47 |
*/
|
48 |
public $hook_suffix;
|
49 |
|
@@ -84,8 +84,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
84 |
$this->plugin_title = __( 'Offload S3', 'as3cf' );
|
85 |
$this->plugin_menu_title = __( 'S3 and CloudFront', 'as3cf' );
|
86 |
|
87 |
-
|
88 |
-
new
|
89 |
|
90 |
add_action( 'aws_admin_menu', array( $this, 'admin_menu' ) );
|
91 |
add_action( 'wp_ajax_as3cf-get-buckets', array( $this, 'ajax_get_buckets' ) );
|
@@ -107,6 +107,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
107 |
add_filter( 'update_attached_file', array( $this, 'update_attached_file' ), 100, 2 );
|
108 |
add_filter( 'get_attached_file', array( $this, 'get_attached_file' ), 10, 2 );
|
109 |
add_filter( 'plugin_action_links', array( $this, 'plugin_actions_settings_link' ), 10, 2 );
|
|
|
110 |
|
111 |
// include compatibility code for other plugins
|
112 |
new AS3CF_Plugin_Compatibility( $this );
|
@@ -488,7 +489,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
488 |
}
|
489 |
|
490 |
// upload attachment to S3
|
491 |
-
$this->upload_attachment_to_s3( $post_id, $data );
|
492 |
|
493 |
return $data;
|
494 |
}
|
@@ -503,10 +504,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
503 |
* to cope with possible different regions
|
504 |
* @param bool $remove_local_files
|
505 |
*
|
506 |
-
* @return array|WP_Error $s3object
|
507 |
*/
|
508 |
function upload_attachment_to_s3( $post_id, $data = null, $file_path = null, $force_new_s3_client = false, $remove_local_files = true ) {
|
|
|
509 |
if ( is_null( $data ) ) {
|
|
|
510 |
$data = wp_get_attachment_metadata( $post_id, true );
|
511 |
}
|
512 |
|
@@ -616,6 +619,26 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
616 |
$file_paths = $this->get_attachment_file_paths( $post_id, true, $data );
|
617 |
$additional_images = array();
|
618 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
619 |
foreach ( $file_paths as $file_path ) {
|
620 |
if ( ! in_array( $file_path, $files_to_remove ) ) {
|
621 |
$additional_images[] = array(
|
@@ -624,6 +647,14 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
624 |
);
|
625 |
|
626 |
$files_to_remove[] = $file_path;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
627 |
}
|
628 |
}
|
629 |
|
@@ -639,20 +670,43 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
639 |
}
|
640 |
|
641 |
if ( $remove_local_files ) {
|
642 |
-
if ( $
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
}
|
650 |
-
}
|
651 |
-
|
652 |
$this->remove_local_files( $files_to_remove );
|
653 |
}
|
654 |
}
|
655 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
656 |
return $s3object;
|
657 |
}
|
658 |
|
@@ -676,6 +730,13 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
676 |
return $pathinfo['dirname'] . '/' . $pathinfo['filename'] . $hidpi_suffix . '.' . $pathinfo['extension'];
|
677 |
}
|
678 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
679 |
function get_object_version_string( $post_id ) {
|
680 |
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
|
681 |
$date_format = 'dHis';
|
@@ -708,8 +769,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
708 |
return null;
|
709 |
}
|
710 |
|
711 |
-
|
712 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
713 |
function get_attachment_folder_time( $post_id ) {
|
714 |
$time = current_time( 'timestamp' );
|
715 |
|
@@ -815,18 +883,39 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
815 |
return get_post_meta( $post_id, 'amazonS3_info', true );
|
816 |
}
|
817 |
|
|
|
|
|
|
|
|
|
|
|
818 |
function is_plugin_setup() {
|
819 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
820 |
}
|
821 |
|
822 |
/**
|
823 |
* Generate a link to download a file from Amazon S3 using query string
|
824 |
* authentication. This link is only valid for a limited amount of time.
|
825 |
*
|
826 |
-
* @param int
|
827 |
-
* @param int $expires Seconds for the link to live
|
828 |
-
* @param string $size Size of the image to get
|
829 |
-
* @param array
|
830 |
*
|
831 |
* @return mixed|void|WP_Error
|
832 |
*/
|
@@ -981,11 +1070,11 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
981 |
/**
|
982 |
* Get the url of the file from Amazon S3
|
983 |
*
|
984 |
-
* @param int
|
985 |
-
* @param int $expires Seconds for the link to live
|
986 |
-
* @param string $size Size of the image to get
|
987 |
-
* @param array $meta Pre retrieved _wp_attachment_metadata for the attachment
|
988 |
-
* @param array
|
989 |
*
|
990 |
* @return bool|mixed|void|WP_Error
|
991 |
*/
|
@@ -1016,7 +1105,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
1016 |
|
1017 |
$domain_bucket = $this->get_s3_url_domain( $s3object['bucket'], $region, $expires );
|
1018 |
|
1019 |
-
if ( $size ) {
|
1020 |
if ( is_null( $meta ) ) {
|
1021 |
$meta = get_post_meta( $post_id, '_wp_attachment_metadata', true );
|
1022 |
}
|
@@ -1027,23 +1116,20 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
1027 |
|
1028 |
if ( ! is_null( $expires ) ) {
|
1029 |
try {
|
1030 |
-
$expires
|
1031 |
$secure_url = $this->get_s3client( $region )->getObjectUrl( $s3object['bucket'], $s3object['key'], $expires, $headers );
|
|
|
|
|
1032 |
}
|
1033 |
catch ( Exception $e ) {
|
1034 |
return new WP_Error( 'exception', $e->getMessage() );
|
1035 |
}
|
1036 |
}
|
1037 |
|
1038 |
-
// encode file
|
1039 |
$file = $this->encode_filename_in_path( $s3object['key'] );
|
|
|
1040 |
|
1041 |
-
|
1042 |
-
if ( isset( $secure_url ) ) {
|
1043 |
-
$url .= substr( $secure_url, strpos( $secure_url, '?' ) );
|
1044 |
-
}
|
1045 |
-
|
1046 |
-
return apply_filters( 'as3cf_get_attachment_url', $url, $s3object, $post_id, $expires );
|
1047 |
}
|
1048 |
|
1049 |
/**
|
@@ -1410,8 +1496,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
1410 |
* @param Amazon_Web_Services $aws
|
1411 |
*/
|
1412 |
function admin_menu( $aws ) {
|
1413 |
-
$
|
1414 |
-
|
|
|
|
|
|
|
|
|
1415 |
}
|
1416 |
|
1417 |
/**
|
@@ -1450,12 +1540,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
1450 |
function get_bucket_region( $bucket ) {
|
1451 |
try {
|
1452 |
$region = $this->get_s3client()->getBucketLocation( array( 'Bucket' => $bucket ) );
|
1453 |
-
}
|
1454 |
-
|
1455 |
-
$error_msg
|
1456 |
error_log( $error_msg );
|
1457 |
|
1458 |
-
return new WP_Error( 'exception', $
|
1459 |
}
|
1460 |
|
1461 |
$region = $this->translate_region( $region['Location'] );
|
@@ -1508,7 +1598,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
1508 |
$region = strtolower( $region );
|
1509 |
|
1510 |
switch ( $region ) {
|
1511 |
-
case 'eu'
|
1512 |
$region = 'eu-west-1';
|
1513 |
break;
|
1514 |
}
|
@@ -1924,7 +2014,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
1924 |
* Apply ACL to an attachment and associated files
|
1925 |
*
|
1926 |
* @param int $post_id
|
1927 |
-
* @param
|
1928 |
* @param string $acl
|
1929 |
*/
|
1930 |
function set_attachment_acl_on_s3( $post_id, $s3object, $acl ) {
|
@@ -2144,6 +2234,21 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
2144 |
}
|
2145 |
echo "\r\n\r\n";
|
2146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2147 |
echo 'Bucket: ';
|
2148 |
echo $this->get_setting( 'bucket' );
|
2149 |
echo "\r\n";
|
@@ -2215,7 +2320,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
2215 |
/**
|
2216 |
* Helper for displaying settings
|
2217 |
*
|
2218 |
-
* @param $key setting key
|
2219 |
*
|
2220 |
* @return string
|
2221 |
*/
|
@@ -2228,7 +2333,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
2228 |
/**
|
2229 |
* Helper to display plugin details
|
2230 |
*
|
2231 |
-
* @param
|
2232 |
* @param string $suffix
|
2233 |
*/
|
2234 |
function print_plugin_details( $plugin_path, $suffix = '' ) {
|
@@ -2317,6 +2422,32 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
2317 |
return false;
|
2318 |
}
|
2319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2320 |
/**
|
2321 |
* Get all the table prefixes for the blogs in the site. MS compatible
|
2322 |
*
|
@@ -2437,4 +2568,125 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
|
|
2437 |
|
2438 |
return $message;
|
2439 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2440 |
}
|
43 |
protected $default_tab = '';
|
44 |
|
45 |
/**
|
46 |
+
* @var string
|
47 |
*/
|
48 |
public $hook_suffix;
|
49 |
|
84 |
$this->plugin_title = __( 'Offload S3', 'as3cf' );
|
85 |
$this->plugin_menu_title = __( 'S3 and CloudFront', 'as3cf' );
|
86 |
|
87 |
+
new AS3CF_Upgrade_Region_Meta( $this );
|
88 |
+
new AS3CF_Upgrade_File_Sizes( $this );
|
89 |
|
90 |
add_action( 'aws_admin_menu', array( $this, 'admin_menu' ) );
|
91 |
add_action( 'wp_ajax_as3cf-get-buckets', array( $this, 'ajax_get_buckets' ) );
|
107 |
add_filter( 'update_attached_file', array( $this, 'update_attached_file' ), 100, 2 );
|
108 |
add_filter( 'get_attached_file', array( $this, 'get_attached_file' ), 10, 2 );
|
109 |
add_filter( 'plugin_action_links', array( $this, 'plugin_actions_settings_link' ), 10, 2 );
|
110 |
+
add_filter( 'pre_get_space_used', array( $this, 'multisite_get_spaced_used' ) );
|
111 |
|
112 |
// include compatibility code for other plugins
|
113 |
new AS3CF_Plugin_Compatibility( $this );
|
489 |
}
|
490 |
|
491 |
// upload attachment to S3
|
492 |
+
$data = $this->upload_attachment_to_s3( $post_id, $data );
|
493 |
|
494 |
return $data;
|
495 |
}
|
504 |
* to cope with possible different regions
|
505 |
* @param bool $remove_local_files
|
506 |
*
|
507 |
+
* @return array|WP_Error $s3object|$meta If meta is supplied, return it. Else return S3 meta
|
508 |
*/
|
509 |
function upload_attachment_to_s3( $post_id, $data = null, $file_path = null, $force_new_s3_client = false, $remove_local_files = true ) {
|
510 |
+
$return_metadata = true;
|
511 |
if ( is_null( $data ) ) {
|
512 |
+
$return_metadata = false;
|
513 |
$data = wp_get_attachment_metadata( $post_id, true );
|
514 |
}
|
515 |
|
619 |
$file_paths = $this->get_attachment_file_paths( $post_id, true, $data );
|
620 |
$additional_images = array();
|
621 |
|
622 |
+
$filesize_total = 0;
|
623 |
+
$remove_local_files_setting = $this->get_setting( 'remove-local-file' );
|
624 |
+
|
625 |
+
if ( $remove_local_files_setting ) {
|
626 |
+
$bytes = filesize( $file_path );
|
627 |
+
if ( false !== $bytes ) {
|
628 |
+
// Store in the attachment meta data for use by WP
|
629 |
+
$data['filesize'] = $bytes;
|
630 |
+
|
631 |
+
if ( ! $return_metadata ) {
|
632 |
+
// Upload happening outside of 'wp_update_attachment_metadata' filter,
|
633 |
+
// So update metadata manually
|
634 |
+
update_post_meta( $post_id, '_wp_attachment_metadata', $data );
|
635 |
+
}
|
636 |
+
|
637 |
+
// Add to the file size total
|
638 |
+
$filesize_total += $bytes;
|
639 |
+
}
|
640 |
+
}
|
641 |
+
|
642 |
foreach ( $file_paths as $file_path ) {
|
643 |
if ( ! in_array( $file_path, $files_to_remove ) ) {
|
644 |
$additional_images[] = array(
|
647 |
);
|
648 |
|
649 |
$files_to_remove[] = $file_path;
|
650 |
+
|
651 |
+
if ( $remove_local_files_setting ) {
|
652 |
+
// Record the file size for the additional image
|
653 |
+
$bytes = filesize( $file_path );
|
654 |
+
if ( false !== $bytes ) {
|
655 |
+
$filesize_total += $bytes;
|
656 |
+
}
|
657 |
+
}
|
658 |
}
|
659 |
}
|
660 |
|
670 |
}
|
671 |
|
672 |
if ( $remove_local_files ) {
|
673 |
+
if ( $remove_local_files_setting ) {
|
674 |
+
// Allow other functions to remove files after they have processed
|
675 |
+
$files_to_remove = apply_filters( 'as3cf_upload_attachment_local_files_to_remove', $files_to_remove, $post_id, $file_path );
|
676 |
+
// Remove duplicates
|
677 |
+
$files_to_remove = array_unique( $files_to_remove );
|
678 |
+
|
679 |
+
// Delete the files
|
|
|
|
|
|
|
680 |
$this->remove_local_files( $files_to_remove );
|
681 |
}
|
682 |
}
|
683 |
|
684 |
+
// Store the file size in the attachment meta if we are removing local file
|
685 |
+
if ( $remove_local_files_setting ) {
|
686 |
+
if ( $filesize_total > 0 ) {
|
687 |
+
// Add the total file size for all image sizes
|
688 |
+
update_post_meta( $post_id, 'wpos3_filesize_total', $filesize_total );
|
689 |
+
}
|
690 |
+
} else {
|
691 |
+
if ( isset( $data['filesize'] ) ) {
|
692 |
+
// Make sure we don't have a cached file sizes in the meta
|
693 |
+
unset( $data['filesize'] );
|
694 |
+
|
695 |
+
if ( ! $return_metadata ) {
|
696 |
+
// Upload happening outside of 'wp_update_attachment_metadata' filter,
|
697 |
+
// So update metadata manually
|
698 |
+
update_post_meta( $post_id, '_wp_attachment_metadata', $data );
|
699 |
+
}
|
700 |
+
|
701 |
+
delete_post_meta( $post_id, 'wpos3_filesize_total' );
|
702 |
+
}
|
703 |
+
}
|
704 |
+
|
705 |
+
if ( $return_metadata ) {
|
706 |
+
// If the attachment metadata is supplied, return it
|
707 |
+
return $data;
|
708 |
+
}
|
709 |
+
|
710 |
return $s3object;
|
711 |
}
|
712 |
|
730 |
return $pathinfo['dirname'] . '/' . $pathinfo['filename'] . $hidpi_suffix . '.' . $pathinfo['extension'];
|
731 |
}
|
732 |
|
733 |
+
/**
|
734 |
+
* Get the object versioning string prefix
|
735 |
+
*
|
736 |
+
* @param int $post_id
|
737 |
+
*
|
738 |
+
* @return string
|
739 |
+
*/
|
740 |
function get_object_version_string( $post_id ) {
|
741 |
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
|
742 |
$date_format = 'dHis';
|
769 |
return null;
|
770 |
}
|
771 |
|
772 |
+
/**
|
773 |
+
* Get the time of attachment upload.
|
774 |
+
*
|
775 |
+
* Use post datetime if attached.
|
776 |
+
*
|
777 |
+
* @param int $post_id
|
778 |
+
*
|
779 |
+
* @return int|string
|
780 |
+
*/
|
781 |
function get_attachment_folder_time( $post_id ) {
|
782 |
$time = current_time( 'timestamp' );
|
783 |
|
883 |
return get_post_meta( $post_id, 'amazonS3_info', true );
|
884 |
}
|
885 |
|
886 |
+
/**
|
887 |
+
* Check the plugin is correctly setup
|
888 |
+
*
|
889 |
+
* @return bool
|
890 |
+
*/
|
891 |
function is_plugin_setup() {
|
892 |
+
if ( is_wp_error( $this->aws->get_client() ) ) {
|
893 |
+
// AWS not configured
|
894 |
+
return false;
|
895 |
+
}
|
896 |
+
|
897 |
+
if ( false === (bool) $this->get_setting( 'bucket' ) ) {
|
898 |
+
// No bucket selected
|
899 |
+
return false;
|
900 |
+
}
|
901 |
+
|
902 |
+
if ( is_wp_error( $this->get_setting( 'region' ) ) ) {
|
903 |
+
// Region error when retrieving bucket location
|
904 |
+
return false;
|
905 |
+
}
|
906 |
+
|
907 |
+
// All good, let's do this
|
908 |
+
return true;
|
909 |
}
|
910 |
|
911 |
/**
|
912 |
* Generate a link to download a file from Amazon S3 using query string
|
913 |
* authentication. This link is only valid for a limited amount of time.
|
914 |
*
|
915 |
+
* @param int $post_id Post ID of the attachment
|
916 |
+
* @param int|null $expires Seconds for the link to live
|
917 |
+
* @param string|null $size Size of the image to get
|
918 |
+
* @param array $headers Header overrides for request
|
919 |
*
|
920 |
* @return mixed|void|WP_Error
|
921 |
*/
|
1070 |
/**
|
1071 |
* Get the url of the file from Amazon S3
|
1072 |
*
|
1073 |
+
* @param int $post_id Post ID of the attachment
|
1074 |
+
* @param int|null $expires Seconds for the link to live
|
1075 |
+
* @param string|null $size Size of the image to get
|
1076 |
+
* @param array|null $meta Pre retrieved _wp_attachment_metadata for the attachment
|
1077 |
+
* @param array $headers Header overrides for request
|
1078 |
*
|
1079 |
* @return bool|mixed|void|WP_Error
|
1080 |
*/
|
1105 |
|
1106 |
$domain_bucket = $this->get_s3_url_domain( $s3object['bucket'], $region, $expires );
|
1107 |
|
1108 |
+
if ( ! is_null( $size ) ) {
|
1109 |
if ( is_null( $meta ) ) {
|
1110 |
$meta = get_post_meta( $post_id, '_wp_attachment_metadata', true );
|
1111 |
}
|
1116 |
|
1117 |
if ( ! is_null( $expires ) ) {
|
1118 |
try {
|
1119 |
+
$expires = time() + $expires;
|
1120 |
$secure_url = $this->get_s3client( $region )->getObjectUrl( $s3object['bucket'], $s3object['key'], $expires, $headers );
|
1121 |
+
|
1122 |
+
return apply_filters( 'as3cf_get_attachment_secure_url', $secure_url, $s3object, $post_id, $expires, $headers );
|
1123 |
}
|
1124 |
catch ( Exception $e ) {
|
1125 |
return new WP_Error( 'exception', $e->getMessage() );
|
1126 |
}
|
1127 |
}
|
1128 |
|
|
|
1129 |
$file = $this->encode_filename_in_path( $s3object['key'] );
|
1130 |
+
$url = $scheme . '://' . $domain_bucket . '/' . $file;
|
1131 |
|
1132 |
+
return apply_filters( 'as3cf_get_attachment_url', $url, $s3object, $post_id, $expires, $headers );
|
|
|
|
|
|
|
|
|
|
|
1133 |
}
|
1134 |
|
1135 |
/**
|
1496 |
* @param Amazon_Web_Services $aws
|
1497 |
*/
|
1498 |
function admin_menu( $aws ) {
|
1499 |
+
$hook_suffix = $aws->add_page( $this->get_plugin_page_title(), $this->plugin_menu_title, 'manage_options', $this->plugin_slug, array( $this, 'render_page' ) );
|
1500 |
+
|
1501 |
+
if ( false !== $hook_suffix ) {
|
1502 |
+
$this->hook_suffix = $hook_suffix;
|
1503 |
+
add_action( 'load-' . $this->hook_suffix, array( $this, 'plugin_load' ) );
|
1504 |
+
}
|
1505 |
}
|
1506 |
|
1507 |
/**
|
1540 |
function get_bucket_region( $bucket ) {
|
1541 |
try {
|
1542 |
$region = $this->get_s3client()->getBucketLocation( array( 'Bucket' => $bucket ) );
|
1543 |
+
} catch ( Exception $e ) {
|
1544 |
+
$error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'as3cf' ) . '</strong> —';
|
1545 |
+
$error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'as3cf' ), $bucket, $e->getMessage() );
|
1546 |
error_log( $error_msg );
|
1547 |
|
1548 |
+
return new WP_Error( 'exception', $error_msg_title . $error_msg );
|
1549 |
}
|
1550 |
|
1551 |
$region = $this->translate_region( $region['Location'] );
|
1598 |
$region = strtolower( $region );
|
1599 |
|
1600 |
switch ( $region ) {
|
1601 |
+
case 'eu':
|
1602 |
$region = 'eu-west-1';
|
1603 |
break;
|
1604 |
}
|
2014 |
* Apply ACL to an attachment and associated files
|
2015 |
*
|
2016 |
* @param int $post_id
|
2017 |
+
* @param array $s3object
|
2018 |
* @param string $acl
|
2019 |
*/
|
2020 |
function set_attachment_acl_on_s3( $post_id, $s3object, $acl ) {
|
2234 |
}
|
2235 |
echo "\r\n\r\n";
|
2236 |
|
2237 |
+
$media_counts = $this->diagnostic_media_counts();
|
2238 |
+
|
2239 |
+
echo 'Media Files: ';
|
2240 |
+
echo number_format_i18n( $media_counts['all'] );
|
2241 |
+
echo "\r\n";
|
2242 |
+
|
2243 |
+
echo 'Media Files on S3: ';
|
2244 |
+
echo number_format_i18n( $media_counts['s3'] );
|
2245 |
+
echo "\r\n";
|
2246 |
+
|
2247 |
+
echo 'Number of Image Sizes: ';
|
2248 |
+
$sizes = count( get_intermediate_image_sizes() );
|
2249 |
+
echo number_format_i18n( $sizes );
|
2250 |
+
echo "\r\n\r\n";
|
2251 |
+
|
2252 |
echo 'Bucket: ';
|
2253 |
echo $this->get_setting( 'bucket' );
|
2254 |
echo "\r\n";
|
2320 |
/**
|
2321 |
* Helper for displaying settings
|
2322 |
*
|
2323 |
+
* @param string $key setting key
|
2324 |
*
|
2325 |
* @return string
|
2326 |
*/
|
2333 |
/**
|
2334 |
* Helper to display plugin details
|
2335 |
*
|
2336 |
+
* @param string $plugin_path
|
2337 |
* @param string $suffix
|
2338 |
*/
|
2339 |
function print_plugin_details( $plugin_path, $suffix = '' ) {
|
2422 |
return false;
|
2423 |
}
|
2424 |
|
2425 |
+
/**
|
2426 |
+
* Helper to switch to a Multisite blog
|
2427 |
+
* - If the site is MS
|
2428 |
+
* - If the blog is not the current blog defined
|
2429 |
+
*
|
2430 |
+
* @param $blog_id
|
2431 |
+
*/
|
2432 |
+
function switch_to_blog( $blog_id ) {
|
2433 |
+
if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
|
2434 |
+
switch_to_blog( $blog_id );
|
2435 |
+
}
|
2436 |
+
}
|
2437 |
+
|
2438 |
+
/**
|
2439 |
+
* Helper to restore to the current Multisite blog
|
2440 |
+
* - If the site is MS
|
2441 |
+
* - If the blog is not the current blog defined
|
2442 |
+
*
|
2443 |
+
* @param $blog_id
|
2444 |
+
*/
|
2445 |
+
function restore_current_blog( $blog_id ) {
|
2446 |
+
if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
|
2447 |
+
restore_current_blog();
|
2448 |
+
}
|
2449 |
+
}
|
2450 |
+
|
2451 |
/**
|
2452 |
* Get all the table prefixes for the blogs in the site. MS compatible
|
2453 |
*
|
2568 |
|
2569 |
return $message;
|
2570 |
}
|
2571 |
+
|
2572 |
+
/**
|
2573 |
+
* Used to give a realistic total of storage space used on a Multisite subsite,
|
2574 |
+
* when there have been attachments uploaded to S3 but removed from server
|
2575 |
+
*
|
2576 |
+
* @param $space_used bool
|
2577 |
+
*
|
2578 |
+
* @return float|int
|
2579 |
+
*/
|
2580 |
+
function multisite_get_spaced_used( $space_used ) {
|
2581 |
+
if ( false === ( $space_used = get_transient( 'wpos3_site_space_used' ) ) ) {
|
2582 |
+
global $wpdb;
|
2583 |
+
|
2584 |
+
// Sum the total file size (including image sizes) for all S3 attachments
|
2585 |
+
$sql = "SELECT SUM( meta_value ) AS bytes_total
|
2586 |
+
FROM {$wpdb->postmeta}
|
2587 |
+
WHERE meta_key = 'wpos3_filesize_total'";
|
2588 |
+
|
2589 |
+
$space_used = $wpdb->get_var( $sql );
|
2590 |
+
|
2591 |
+
// Get local upload sizes
|
2592 |
+
$upload_dir = wp_upload_dir();
|
2593 |
+
$space_used += get_dirsize( $upload_dir['basedir'] );
|
2594 |
+
|
2595 |
+
if ( $space_used > 0 ) {
|
2596 |
+
// Convert to bytes to MB
|
2597 |
+
$space_used = $space_used / 1024 / 1024;
|
2598 |
+
}
|
2599 |
+
|
2600 |
+
set_transient( 'wpos3_site_space_used', $space_used, HOUR_IN_SECONDS );
|
2601 |
+
}
|
2602 |
+
|
2603 |
+
return $space_used;
|
2604 |
+
}
|
2605 |
+
|
2606 |
+
/**
|
2607 |
+
* Memory exceeded
|
2608 |
+
*
|
2609 |
+
* Ensures the a process never exceeds 90% of the maximum WordPress memory.
|
2610 |
+
*
|
2611 |
+
* @param null|string $filter_name Name of filter to apply to the return
|
2612 |
+
*
|
2613 |
+
* @return bool
|
2614 |
+
*/
|
2615 |
+
public function memory_exceeded( $filter_name = null ) {
|
2616 |
+
$current_memory = memory_get_usage( true );
|
2617 |
+
$memory_limit = ( intval( WP_MEMORY_LIMIT ) * 1024 * 1024 ) * 0.9; // 90% of max memory
|
2618 |
+
$return = false;
|
2619 |
+
|
2620 |
+
if ( $current_memory >= $memory_limit ) {
|
2621 |
+
$return = true;
|
2622 |
+
}
|
2623 |
+
|
2624 |
+
if ( is_null( $filter_name ) || ! is_string( $filter_name ) ) {
|
2625 |
+
return $return;
|
2626 |
+
}
|
2627 |
+
|
2628 |
+
return apply_filters( $filter_name, $return );
|
2629 |
+
}
|
2630 |
+
|
2631 |
+
/**
|
2632 |
+
* Count attachments on a site
|
2633 |
+
*
|
2634 |
+
* @param string $prefix
|
2635 |
+
* @param null|bool $uploaded_to_s3
|
2636 |
+
* null - All attachments
|
2637 |
+
* true - Attachments only uploaded to S3
|
2638 |
+
* false - Attachments not uploaded to S3
|
2639 |
+
*
|
2640 |
+
* @return null|string
|
2641 |
+
*/
|
2642 |
+
public function count_attachments( $prefix, $uploaded_to_s3 = null ) {
|
2643 |
+
global $wpdb;
|
2644 |
+
|
2645 |
+
$sql = "SELECT COUNT(*)
|
2646 |
+
FROM `{$prefix}posts` p";
|
2647 |
+
|
2648 |
+
$where = "WHERE p.post_type = 'attachment'";
|
2649 |
+
|
2650 |
+
if ( ! is_null( $uploaded_to_s3 ) && is_bool( $uploaded_to_s3 ) ) {
|
2651 |
+
$sql .= " LEFT OUTER JOIN `{$prefix}postmeta` pm
|
2652 |
+
ON p.`ID` = pm.`post_id`
|
2653 |
+
AND pm.`meta_key` = 'amazonS3_info'";
|
2654 |
+
|
2655 |
+
$operator = $uploaded_to_s3 ? 'not ' : '';
|
2656 |
+
$where .= " AND pm.`post_id` is {$operator}null";
|
2657 |
+
}
|
2658 |
+
|
2659 |
+
$sql .= ' ' . $where;
|
2660 |
+
|
2661 |
+
return $wpdb->get_var( $sql );
|
2662 |
+
}
|
2663 |
+
|
2664 |
+
/**
|
2665 |
+
* Get the total attachment and total S3 attachment counts for the diagnostic log
|
2666 |
+
*
|
2667 |
+
* @return array
|
2668 |
+
*/
|
2669 |
+
protected function diagnostic_media_counts() {
|
2670 |
+
if ( false === ( $attachment_counts = get_site_transient( 'wpos3_attachment_counts' ) ) ) {
|
2671 |
+
$table_prefixes = $this->get_all_blog_table_prefixes();
|
2672 |
+
$all_media = 0;
|
2673 |
+
$all_media_s3 = 0;
|
2674 |
+
|
2675 |
+
foreach ( $table_prefixes as $blog_id => $table_prefix ) {
|
2676 |
+
$count = $this->count_attachments( $table_prefix );
|
2677 |
+
$all_media += $count;
|
2678 |
+
$s3_count = $this->count_attachments( $table_prefix, true );
|
2679 |
+
$all_media_s3 += $s3_count;
|
2680 |
+
}
|
2681 |
+
|
2682 |
+
$attachment_counts = array(
|
2683 |
+
'all' => $all_media,
|
2684 |
+
's3' => $all_media_s3,
|
2685 |
+
);
|
2686 |
+
|
2687 |
+
set_site_transient( 'wpos3_attachment_counts', $attachment_counts, 2 * HOUR_IN_SECONDS );
|
2688 |
+
}
|
2689 |
+
|
2690 |
+
return $attachment_counts;
|
2691 |
+
}
|
2692 |
}
|
classes/as3cf-plugin-compatibility.php
CHANGED
@@ -50,13 +50,15 @@ class AS3CF_Plugin_Compatibility {
|
|
50 |
*/
|
51 |
add_action( 'as3cf_upload_attachment_pre_remove', array( $this, 'image_editor_remove_files' ), 10, 4 );
|
52 |
add_filter( 'as3cf_get_attached_file', array( $this, 'image_editor_download_file' ), 10, 4 );
|
|
|
|
|
|
|
53 |
|
54 |
/*
|
55 |
* WP_Customize_Control
|
56 |
* /wp-includes/class-wp-customize_control.php
|
57 |
*/
|
58 |
add_filter( 'attachment_url_to_postid', array( $this, 'customizer_background_image' ), 10, 2 );
|
59 |
-
|
60 |
/*
|
61 |
* Regenerate Thumbnails
|
62 |
* https://wordpress.org/plugins/regenerate-thumbnails/
|
@@ -91,6 +93,25 @@ class AS3CF_Plugin_Compatibility {
|
|
91 |
return $url;
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
/**
|
95 |
* Allow the WordPress Image Editor to remove edited version of images
|
96 |
* if the original image is being restored and 'IMAGE_EDIT_OVERWRITE' is set
|
@@ -144,9 +165,9 @@ class AS3CF_Plugin_Compatibility {
|
|
144 |
$this->copy_s3_file_to_server( $orig_s3, $orig_file );
|
145 |
|
146 |
// Copy the edited file back to the server as well, it will be cleaned up later
|
147 |
-
if ( ( $
|
148 |
// Return the file if successfully downloaded from S3
|
149 |
-
return $
|
150 |
};
|
151 |
}
|
152 |
|
@@ -156,9 +177,9 @@ class AS3CF_Plugin_Compatibility {
|
|
156 |
foreach ( $callers as $caller ) {
|
157 |
if ( isset( $caller['function'] ) && '_load_image_to_edit_path' == $caller['function'] ) {
|
158 |
// check this has been called by '_load_image_to_edit_path' so as only to copy back once
|
159 |
-
if ( ( $
|
160 |
// Return the file if successfully downloaded from S3
|
161 |
-
return $
|
162 |
};
|
163 |
}
|
164 |
}
|
@@ -167,6 +188,82 @@ class AS3CF_Plugin_Compatibility {
|
|
167 |
return $url;
|
168 |
}
|
169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
/**
|
171 |
* Show the correct background image in the customizer
|
172 |
*
|
50 |
*/
|
51 |
add_action( 'as3cf_upload_attachment_pre_remove', array( $this, 'image_editor_remove_files' ), 10, 4 );
|
52 |
add_filter( 'as3cf_get_attached_file', array( $this, 'image_editor_download_file' ), 10, 4 );
|
53 |
+
add_filter( 'as3cf_upload_attachment_local_files_to_remove', array( $this, 'image_editor_remove_original_image' ), 10, 3 );
|
54 |
+
add_filter( 'as3cf_get_attached_file', array( $this, 'customizer_header_crop_download_file' ), 10, 4 );
|
55 |
+
add_filter( 'as3cf_upload_attachment_local_files_to_remove', array( $this, 'customizer_header_crop_remove_original_image' ), 10, 3 );
|
56 |
|
57 |
/*
|
58 |
* WP_Customize_Control
|
59 |
* /wp-includes/class-wp-customize_control.php
|
60 |
*/
|
61 |
add_filter( 'attachment_url_to_postid', array( $this, 'customizer_background_image' ), 10, 2 );
|
|
|
62 |
/*
|
63 |
* Regenerate Thumbnails
|
64 |
* https://wordpress.org/plugins/regenerate-thumbnails/
|
93 |
return $url;
|
94 |
}
|
95 |
|
96 |
+
/**
|
97 |
+
* Get the file path of the original image file before an update
|
98 |
+
*
|
99 |
+
* @param int $post_id
|
100 |
+
* @param string $file_path
|
101 |
+
*
|
102 |
+
* @return bool|string
|
103 |
+
*/
|
104 |
+
function get_original_image_file( $post_id, $file_path ) {
|
105 |
+
// remove original main image after edit
|
106 |
+
$meta = get_post_meta( $post_id, '_wp_attachment_metadata', true );
|
107 |
+
$original_file = trailingslashit( dirname( $file_path ) ) . basename( $meta['file'] );
|
108 |
+
if ( file_exists( $original_file ) ) {
|
109 |
+
return $original_file;
|
110 |
+
}
|
111 |
+
|
112 |
+
return false;
|
113 |
+
}
|
114 |
+
|
115 |
/**
|
116 |
* Allow the WordPress Image Editor to remove edited version of images
|
117 |
* if the original image is being restored and 'IMAGE_EDIT_OVERWRITE' is set
|
165 |
$this->copy_s3_file_to_server( $orig_s3, $orig_file );
|
166 |
|
167 |
// Copy the edited file back to the server as well, it will be cleaned up later
|
168 |
+
if ( ( $s3_file = $this->copy_s3_file_to_server( $s3_object, $file ) ) ) {
|
169 |
// Return the file if successfully downloaded from S3
|
170 |
+
return $s3_file;
|
171 |
};
|
172 |
}
|
173 |
|
177 |
foreach ( $callers as $caller ) {
|
178 |
if ( isset( $caller['function'] ) && '_load_image_to_edit_path' == $caller['function'] ) {
|
179 |
// check this has been called by '_load_image_to_edit_path' so as only to copy back once
|
180 |
+
if ( ( $s3_file = $this->copy_s3_file_to_server( $s3_object, $file ) ) ) {
|
181 |
// Return the file if successfully downloaded from S3
|
182 |
+
return $s3_file;
|
183 |
};
|
184 |
}
|
185 |
}
|
188 |
return $url;
|
189 |
}
|
190 |
|
191 |
+
/**
|
192 |
+
* Allow the WordPress Image Editor to remove the main image file after it has been copied
|
193 |
+
* back from S3 after it has done the edit.
|
194 |
+
*
|
195 |
+
* @param array $files
|
196 |
+
* @param int $post_id
|
197 |
+
* @param string $file_path
|
198 |
+
*
|
199 |
+
* @return array
|
200 |
+
*/
|
201 |
+
function image_editor_remove_original_image( $files, $post_id, $file_path ) {
|
202 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
|
203 |
+
return $files;
|
204 |
+
}
|
205 |
+
|
206 |
+
if ( isset( $_POST['action'] ) && 'image-editor' === sanitize_key( $_POST['action'] ) ) { // input var okay
|
207 |
+
// remove original main image after edit
|
208 |
+
if ( ( $original_file = $this->get_original_image_file( $post_id, $file_path ) ) ) {
|
209 |
+
$files[] = $original_file;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
return $files;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Allow the WordPress Customizer to crop images that have been copied to S3
|
218 |
+
* but removed from the local server, by copying them back temporarily
|
219 |
+
*
|
220 |
+
* @param string $url
|
221 |
+
* @param string $file
|
222 |
+
* @param int $attachment_id
|
223 |
+
* @param array $s3_object
|
224 |
+
*
|
225 |
+
* @return string
|
226 |
+
*/
|
227 |
+
function customizer_header_crop_download_file( $url, $file, $attachment_id, $s3_object ) {
|
228 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
|
229 |
+
return $url;
|
230 |
+
}
|
231 |
+
|
232 |
+
if ( isset( $_POST['action'] ) && 'custom-header-crop' === sanitize_key( $_POST['action'] ) ) { // input var okay
|
233 |
+
if ( ( $file = $this->copy_s3_file_to_server( $s3_object, $file ) ) ) {
|
234 |
+
// Return the file if successfully downloaded from S3
|
235 |
+
return $file;
|
236 |
+
};
|
237 |
+
}
|
238 |
+
|
239 |
+
return $url;
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Allow the WordPress Image Editor to remove the main image file after it has been copied
|
244 |
+
* back from S3 after it has done the edit.
|
245 |
+
*
|
246 |
+
* @param array $files
|
247 |
+
* @param int $post_id
|
248 |
+
* @param string $file_path
|
249 |
+
*
|
250 |
+
* @return array
|
251 |
+
*/
|
252 |
+
function customizer_header_crop_remove_original_image( $files, $post_id, $file_path ) {
|
253 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
|
254 |
+
return $files;
|
255 |
+
}
|
256 |
+
|
257 |
+
if ( isset( $_POST['action'] ) && 'custom-header-crop' === sanitize_key( $_POST['action'] ) ) { // input var okay
|
258 |
+
// remove original main image after edit
|
259 |
+
if ( ( $original_file = $this->get_original_image_file( $_POST['id'], $file_path ) ) ) {
|
260 |
+
$files[] = $original_file;
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
return $files;
|
265 |
+
}
|
266 |
+
|
267 |
/**
|
268 |
* Show the correct background image in the customizer
|
269 |
*
|
classes/as3cf-upgrade.php
CHANGED
@@ -17,18 +17,66 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
17 |
/**
|
18 |
* AS3CF_Upgrade Class
|
19 |
*
|
20 |
-
* This class handles
|
21 |
*
|
22 |
* @since 0.6.2
|
23 |
*/
|
24 |
-
class AS3CF_Upgrade {
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
const STATUS_RUNNING = 1;
|
34 |
const STATUS_ERROR = 2;
|
@@ -42,169 +90,122 @@ class AS3CF_Upgrade {
|
|
42 |
function __construct( $as3cf ) {
|
43 |
$this->as3cf = $as3cf;
|
44 |
|
45 |
-
$this->
|
46 |
-
$this->
|
|
|
|
|
|
|
47 |
|
48 |
add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) );
|
49 |
-
add_action(
|
50 |
|
51 |
add_action( 'as3cf_pre_settings_render', array( $this, 'maybe_display_notices' ) );
|
52 |
add_action( 'admin_init', array( $this, 'maybe_handle_action' ) );
|
53 |
|
54 |
-
|
|
|
|
|
|
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
-
*
|
|
|
|
|
59 |
*/
|
60 |
-
function
|
61 |
if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
62 |
-
return;
|
63 |
}
|
64 |
|
65 |
// make sure this only fires inside the network admin for multisites
|
66 |
if ( is_multisite() && ! is_network_admin() ) {
|
67 |
-
return;
|
68 |
-
}
|
69 |
-
|
70 |
-
// Have we completed the upgrade yet?
|
71 |
-
if ( $this->as3cf->get_setting( 'post_meta_version', 0 ) > 0 ) {
|
72 |
-
return;
|
73 |
}
|
74 |
|
75 |
// If the upgrade status is already set, then we've already initialized the upgrade
|
76 |
if ( $this->get_upgrade_status() ) {
|
77 |
-
return;
|
78 |
}
|
79 |
|
80 |
-
//
|
81 |
-
|
82 |
-
|
83 |
-
$this->as3cf->set_setting( 'post_meta_version', 1 );
|
84 |
-
$this->as3cf->save_settings();
|
85 |
-
|
86 |
-
return;
|
87 |
}
|
88 |
|
89 |
-
//
|
90 |
-
$this->
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Adds notices about issues with upgrades allowing user to restart them
|
97 |
-
*/
|
98 |
-
function maybe_display_notices() {
|
99 |
-
$action_url = $this->as3cf->get_plugin_page_url( array( 'action' => 'restart_update_meta_with_region' ), 'self' );
|
100 |
-
$msg_type = 'notice-info';
|
101 |
-
|
102 |
-
switch ( $this->get_upgrade_status() ) {
|
103 |
-
case self::STATUS_RUNNING :
|
104 |
-
$msg = sprintf( __( '<strong>Running Metadata Update</strong> — We’re going through all the Media Library items uploaded to S3 and updating the metadata with the bucket region it is served from. This will allow us to serve your files from the proper S3 region subdomain <span style="white-space:nowrap;">(e.g. s3-us-west-2.amazonaws.com)</span>. This will be done quietly in the background, processing a small batch of Media Library items every %d minutes. There should be no noticeable impact on your server’s performance.', 'as3cf' ), $this->cron_interval_in_minutes );
|
105 |
-
$action_text = __( 'Pause Update', 'as3cf' );
|
106 |
-
$action_url = $this->as3cf->get_plugin_page_url( array( 'action' => 'pause_update_meta_with_region' ), 'self' );
|
107 |
-
break;
|
108 |
-
case self::STATUS_PAUSED :
|
109 |
-
$msg = __( '<strong>Metadata Update Paused</strong> — Updating Media Library metadata has been paused.', 'as3cf' );
|
110 |
-
$action_text = __( 'Restart Update', 'as3cf' );
|
111 |
-
break;
|
112 |
-
case self::STATUS_ERROR :
|
113 |
-
$msg = __( '<strong>Error Updating Metadata</strong> — We ran into some errors attempting to update the metadata for all your Media Library items that have been uploaded to S3. Please check your error log for details.', 'as3cf' );
|
114 |
-
$action_text = __( 'Try Run It Again', 'as3cf' );
|
115 |
-
$msg_type = 'error';
|
116 |
-
break;
|
117 |
-
default :
|
118 |
-
return;
|
119 |
}
|
120 |
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
'message' => $msg,
|
125 |
-
'type' => $msg_type,
|
126 |
-
);
|
127 |
|
128 |
-
|
129 |
-
}
|
130 |
-
|
131 |
-
function maybe_handle_action() {
|
132 |
-
if ( ! isset( $_GET['page'] ) || sanitize_key( $_GET['page'] ) != $this->as3cf->get_plugin_slug() || ! isset( $_GET['action'] ) ) { // input var okay
|
133 |
-
return;
|
134 |
}
|
135 |
|
136 |
-
|
137 |
-
if ( method_exists( $this, $method_name ) ) {
|
138 |
-
call_user_func( array( $this, $method_name ) );
|
139 |
-
}
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
-
*
|
144 |
*/
|
145 |
-
function
|
146 |
-
$this->change_status_request( self::STATUS_RUNNING );
|
147 |
-
$this->as3cf->schedule_event( self::CRON_HOOK, self::CRON_SCHEDULE_KEY );
|
148 |
-
}
|
149 |
|
150 |
/**
|
151 |
-
*
|
|
|
|
|
|
|
152 |
*/
|
153 |
-
function
|
154 |
-
$this->clear_scheduled_event();
|
155 |
-
$this->change_status_request( self::STATUS_PAUSED );
|
156 |
-
}
|
157 |
|
158 |
/**
|
159 |
-
*
|
160 |
*
|
161 |
-
* @
|
162 |
*/
|
163 |
-
function
|
164 |
-
$session = $this->get_session();
|
165 |
-
$session['status'] = $status;
|
166 |
-
$this->save_session( $session );
|
167 |
-
|
168 |
-
$url = $this->as3cf->get_plugin_page_url( array(), 'self' );
|
169 |
-
wp_redirect( $url );
|
170 |
-
}
|
171 |
|
172 |
/**
|
173 |
-
*
|
174 |
-
*
|
175 |
-
* @param array $schedules
|
176 |
-
*
|
177 |
-
* @return array
|
178 |
*/
|
179 |
-
function
|
180 |
-
//
|
181 |
-
$
|
182 |
-
'interval' => $this->cron_interval_in_minutes * 60,
|
183 |
-
'display' => sprintf( __( 'Every %d Minutes', 'as3cf' ), $this->cron_interval_in_minutes ),
|
184 |
-
);
|
185 |
|
186 |
-
|
187 |
}
|
188 |
-
|
189 |
/**
|
190 |
* Cron jon to update the region of the bucket in s3 metadata
|
191 |
*/
|
192 |
-
function
|
193 |
// Check if the cron should even be running
|
194 |
-
if ( $this->as3cf->get_setting(
|
195 |
-
$this->as3cf->clear_scheduled_event(
|
|
|
196 |
return;
|
197 |
}
|
198 |
|
199 |
// set the batch size limit for the query
|
200 |
-
$limit = apply_filters( '
|
201 |
$all_limit = $limit;
|
202 |
|
203 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
// find the blog IDs that have been processed so we can skip them
|
206 |
$processed_blog_ids = isset( $session['processed_blog_ids'] ) ? $session['processed_blog_ids'] : array();
|
207 |
-
$error_count = isset( $session['error_count'] ) ? $session['error_count'] : 0;
|
208 |
|
209 |
// get the table prefixes for all the blogs
|
210 |
$table_prefixes = $this->as3cf->get_all_blog_table_prefixes( $processed_blog_ids );
|
@@ -213,10 +214,10 @@ class AS3CF_Upgrade {
|
|
213 |
$all_count = 0;
|
214 |
|
215 |
foreach ( $table_prefixes as $blog_id => $table_prefix ) {
|
216 |
-
$attachments = $this->
|
217 |
$count = count( $attachments );
|
218 |
|
219 |
-
if ( 0
|
220 |
// no more attachments, record the blog ID to skip next time
|
221 |
$processed_blog_ids[] = $blog_id;
|
222 |
} else {
|
@@ -231,204 +232,205 @@ class AS3CF_Upgrade {
|
|
231 |
$limit = $limit - $count;
|
232 |
}
|
233 |
|
234 |
-
if ( 0
|
235 |
-
$this->
|
236 |
-
|
237 |
-
$this->as3cf->save_settings();
|
238 |
-
$this->as3cf->clear_scheduled_event( self::CRON_HOOK );
|
239 |
return;
|
240 |
}
|
241 |
|
242 |
-
// only process the loop for a certain amount of time
|
243 |
-
$minutes = $this->cron_interval_in_minutes * 60;
|
244 |
-
|
245 |
-
// smaller time limit so won't run into another instance of cron
|
246 |
-
$minutes = $minutes * 0.8;
|
247 |
-
|
248 |
-
$finish = time() + $minutes;
|
249 |
-
|
250 |
// loop through and update s3 meta with region
|
251 |
foreach ( $all_attachments as $blog_id => $attachments ) {
|
252 |
-
|
253 |
-
switch_to_blog( $blog_id );
|
254 |
-
}
|
255 |
|
256 |
foreach ( $attachments as $attachment ) {
|
257 |
-
if ( $error_count >= $this->error_threshold ) {
|
258 |
-
$session
|
259 |
-
$this->save_session( $session );
|
260 |
-
$this->clear_scheduled_event();
|
261 |
-
return;
|
262 |
-
}
|
263 |
|
264 |
-
|
265 |
-
break;
|
266 |
}
|
267 |
|
268 |
-
|
269 |
-
|
270 |
-
error_log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
|
271 |
-
$error_count++;
|
272 |
-
continue;
|
273 |
-
}
|
274 |
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
error_log( 'Error updating region: ' . $region->get_error_message() );
|
279 |
-
$error_count++;
|
280 |
}
|
281 |
}
|
282 |
-
|
283 |
-
if ( is_multisite() && ! $this->as3cf->is_current_blog( $blog_id ) ) {
|
284 |
-
restore_current_blog();
|
285 |
-
}
|
286 |
}
|
287 |
|
|
|
|
|
288 |
$session['processed_blog_ids'] = $processed_blog_ids;
|
289 |
-
$session['error_count'] = $error_count;
|
290 |
|
291 |
$this->save_session( $session );
|
292 |
}
|
293 |
|
294 |
/**
|
295 |
-
*
|
296 |
-
* for the whole site
|
297 |
-
*
|
298 |
-
* @return int
|
299 |
*/
|
300 |
-
function
|
301 |
-
|
302 |
-
$
|
303 |
-
$all_count = 0;
|
304 |
|
305 |
-
|
306 |
-
|
307 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
}
|
309 |
|
310 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
}
|
312 |
|
313 |
/**
|
314 |
-
*
|
315 |
-
* See STATUS_* constants in the class declaration above.
|
316 |
*/
|
317 |
-
function
|
318 |
-
$
|
319 |
-
|
320 |
-
if ( ! isset( $session['status'] ) ) {
|
321 |
-
return '';
|
322 |
}
|
323 |
|
324 |
-
|
|
|
|
|
|
|
325 |
}
|
326 |
|
327 |
/**
|
328 |
-
*
|
329 |
*
|
330 |
-
* @
|
331 |
*/
|
332 |
-
function
|
333 |
-
|
|
|
|
|
334 |
}
|
335 |
|
336 |
/**
|
337 |
-
*
|
338 |
-
*
|
339 |
-
* @param $session array of session data to store
|
340 |
*/
|
341 |
-
function
|
342 |
-
$this->
|
|
|
343 |
$this->as3cf->save_settings();
|
|
|
344 |
}
|
345 |
|
346 |
/**
|
347 |
-
*
|
348 |
-
*
|
349 |
-
* @param array $exclude_blog_ids blog ids to exclude
|
350 |
-
*
|
351 |
-
* @return array associative array with blog ID as key, prefix as value
|
352 |
*/
|
353 |
-
function
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
$table_prefixes = array();
|
358 |
-
|
359 |
-
if ( ! in_array( 1, $exclude_blog_ids ) ) {
|
360 |
-
$table_prefixes[1] = $prefix;
|
361 |
-
}
|
362 |
-
|
363 |
-
if ( is_multisite() ) {
|
364 |
-
$blog_ids = $this->as3cf->get_blog_ids();
|
365 |
-
foreach ( $blog_ids as $blog_id ) {
|
366 |
-
if ( in_array( $blog_id, $exclude_blog_ids ) ) {
|
367 |
-
continue;
|
368 |
-
}
|
369 |
-
$table_prefixes[ $blog_id ] = $wpdb->get_blog_prefix( $blog_id );
|
370 |
-
}
|
371 |
}
|
372 |
|
373 |
-
|
|
|
374 |
}
|
375 |
|
376 |
/**
|
377 |
-
*
|
378 |
-
*
|
379 |
-
* @param string $prefix
|
380 |
-
* @param int $limit
|
381 |
-
*
|
382 |
-
* @return mixed
|
383 |
*/
|
384 |
-
function
|
385 |
-
$
|
|
|
|
|
386 |
|
387 |
-
|
|
|
388 |
}
|
389 |
|
390 |
/**
|
391 |
-
*
|
392 |
-
* @param $prefix
|
393 |
*
|
394 |
-
* @
|
395 |
*/
|
396 |
-
function
|
397 |
-
$
|
|
|
|
|
398 |
|
399 |
-
|
|
|
|
|
400 |
}
|
401 |
|
402 |
/**
|
403 |
-
*
|
404 |
*
|
405 |
-
* @param
|
406 |
-
* @param bool $count return count of attachments
|
407 |
-
* @param null|int $limit
|
408 |
*
|
409 |
-
* @return
|
410 |
*/
|
411 |
-
function
|
412 |
-
|
|
|
|
|
|
|
|
|
413 |
|
414 |
-
|
415 |
-
|
416 |
-
AND `meta_value` NOT LIKE '%%\"region\"%%'";
|
417 |
|
418 |
-
|
419 |
-
|
|
|
|
|
|
|
|
|
420 |
|
421 |
-
|
|
|
422 |
}
|
423 |
|
424 |
-
$
|
|
|
425 |
|
426 |
-
|
427 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
428 |
|
429 |
-
|
430 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
431 |
|
432 |
-
|
|
|
|
|
|
|
|
|
|
|
433 |
}
|
434 |
}
|
17 |
/**
|
18 |
* AS3CF_Upgrade Class
|
19 |
*
|
20 |
+
* This class handles updates to attachments and attachment meta data
|
21 |
*
|
22 |
* @since 0.6.2
|
23 |
*/
|
24 |
+
abstract class AS3CF_Upgrade {
|
25 |
|
26 |
+
/**
|
27 |
+
* @var Amazon_S3_And_CloudFront
|
28 |
+
*/
|
29 |
+
protected $as3cf;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var int
|
33 |
+
*/
|
34 |
+
protected $upgrade_id;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
protected $upgrade_name;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @var string 'metadata', 'attachment'
|
43 |
+
*/
|
44 |
+
protected $upgrade_type;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
protected $running_update_text;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
protected $settings_key = 'post_meta_version';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
protected $cron_hook;
|
60 |
|
61 |
+
/**
|
62 |
+
* @var string
|
63 |
+
*/
|
64 |
+
protected $cron_schedule_key;
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @var mixed|void
|
68 |
+
*/
|
69 |
+
protected $cron_interval_in_minutes;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @var mixed|void
|
73 |
+
*/
|
74 |
+
protected $error_threshold;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @var int
|
78 |
+
*/
|
79 |
+
protected $error_count;
|
80 |
|
81 |
const STATUS_RUNNING = 1;
|
82 |
const STATUS_ERROR = 2;
|
90 |
function __construct( $as3cf ) {
|
91 |
$this->as3cf = $as3cf;
|
92 |
|
93 |
+
$this->cron_hook = 'as3cf_cron_update_' . $this->upgrade_name;
|
94 |
+
$this->cron_schedule_key = 'as3cf_update_' . $this->upgrade_name . '_interval';
|
95 |
+
|
96 |
+
$this->cron_interval_in_minutes = apply_filters( 'as3cf_update_' . $this->upgrade_name . '_interval', 5 );
|
97 |
+
$this->error_threshold = apply_filters( 'as3cf_update_' . $this->upgrade_name . '_error_threshold', 20 );
|
98 |
|
99 |
add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) );
|
100 |
+
add_action( $this->cron_hook, array( $this, 'do_upgrade' ) );
|
101 |
|
102 |
add_action( 'as3cf_pre_settings_render', array( $this, 'maybe_display_notices' ) );
|
103 |
add_action( 'admin_init', array( $this, 'maybe_handle_action' ) );
|
104 |
|
105 |
+
// Do default checks if the upgrade can be started
|
106 |
+
if ( $this->maybe_init() ) {
|
107 |
+
$this->init();
|
108 |
+
}
|
109 |
}
|
110 |
|
111 |
/**
|
112 |
+
* Can we start the upgrade using default checks
|
113 |
+
*
|
114 |
+
* @return bool
|
115 |
*/
|
116 |
+
protected function maybe_init() {
|
117 |
if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
118 |
+
return false;
|
119 |
}
|
120 |
|
121 |
// make sure this only fires inside the network admin for multisites
|
122 |
if ( is_multisite() && ! is_network_admin() ) {
|
123 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
|
126 |
// If the upgrade status is already set, then we've already initialized the upgrade
|
127 |
if ( $this->get_upgrade_status() ) {
|
128 |
+
return false;
|
129 |
}
|
130 |
|
131 |
+
// Have we completed the upgrade?
|
132 |
+
if ( $this->as3cf->get_setting( $this->settings_key, 0 ) >= $this->upgrade_id ) {
|
133 |
+
return false;
|
|
|
|
|
|
|
|
|
134 |
}
|
135 |
|
136 |
+
// Has the previous upgrade completed yet?
|
137 |
+
$previous_id = $this->upgrade_id - 1;
|
138 |
+
if ( 0 !== $previous_id && (int) $this->as3cf->get_setting( $this->settings_key, 0 ) < $previous_id ) {
|
139 |
+
// Previous still running, abort
|
140 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
}
|
142 |
|
143 |
+
// Do we actually attachments to process?
|
144 |
+
if ( 0 === $this->count_attachments_to_process() ) {
|
145 |
+
$this->upgrade_finished();
|
|
|
|
|
|
|
146 |
|
147 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
148 |
}
|
149 |
|
150 |
+
return true;
|
|
|
|
|
|
|
151 |
}
|
152 |
|
153 |
/**
|
154 |
+
* @return int
|
155 |
*/
|
156 |
+
abstract protected function count_attachments_to_process();
|
|
|
|
|
|
|
157 |
|
158 |
/**
|
159 |
+
* @param $prefix
|
160 |
+
* @param $limit
|
161 |
+
*
|
162 |
+
* @return array
|
163 |
*/
|
164 |
+
abstract protected function get_attachments_to_process( $prefix, $limit );
|
|
|
|
|
|
|
165 |
|
166 |
/**
|
167 |
+
* @param $attachment
|
168 |
*
|
169 |
+
* @return bool
|
170 |
*/
|
171 |
+
abstract protected function upgrade_attachment( $attachment );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
/**
|
174 |
+
* Fire up the upgrade
|
|
|
|
|
|
|
|
|
175 |
*/
|
176 |
+
protected function init() {
|
177 |
+
// Initialize the upgrade
|
178 |
+
$this->save_session( array( 'status' => self::STATUS_RUNNING ) );
|
|
|
|
|
|
|
179 |
|
180 |
+
$this->as3cf->schedule_event( $this->cron_hook, $this->cron_schedule_key );
|
181 |
}
|
182 |
+
|
183 |
/**
|
184 |
* Cron jon to update the region of the bucket in s3 metadata
|
185 |
*/
|
186 |
+
function do_upgrade() {
|
187 |
// Check if the cron should even be running
|
188 |
+
if ( $this->as3cf->get_setting( $this->settings_key, 0 ) >= $this->upgrade_id || $this->get_upgrade_status() !== self::STATUS_RUNNING ) {
|
189 |
+
$this->as3cf->clear_scheduled_event( $this->cron_hook );
|
190 |
+
|
191 |
return;
|
192 |
}
|
193 |
|
194 |
// set the batch size limit for the query
|
195 |
+
$limit = apply_filters( 'as3cf_update_' . $this->upgrade_name . '_batch_size', 500 );
|
196 |
$all_limit = $limit;
|
197 |
|
198 |
+
// only process the loop for a certain amount of time
|
199 |
+
$minutes = $this->cron_interval_in_minutes * 60;
|
200 |
+
// smaller time limit so won't run into another instance of cron
|
201 |
+
$minutes = $minutes * 0.8;
|
202 |
+
$finish = time() + $minutes;
|
203 |
+
|
204 |
+
$session = $this->get_session();
|
205 |
|
206 |
// find the blog IDs that have been processed so we can skip them
|
207 |
$processed_blog_ids = isset( $session['processed_blog_ids'] ) ? $session['processed_blog_ids'] : array();
|
208 |
+
$this->error_count = isset( $session['error_count'] ) ? $session['error_count'] : 0;
|
209 |
|
210 |
// get the table prefixes for all the blogs
|
211 |
$table_prefixes = $this->as3cf->get_all_blog_table_prefixes( $processed_blog_ids );
|
214 |
$all_count = 0;
|
215 |
|
216 |
foreach ( $table_prefixes as $blog_id => $table_prefix ) {
|
217 |
+
$attachments = $this->get_attachments_to_process( $table_prefix, $limit );
|
218 |
$count = count( $attachments );
|
219 |
|
220 |
+
if ( 0 === $count ) {
|
221 |
// no more attachments, record the blog ID to skip next time
|
222 |
$processed_blog_ids[] = $blog_id;
|
223 |
} else {
|
232 |
$limit = $limit - $count;
|
233 |
}
|
234 |
|
235 |
+
if ( 0 === $all_count ) {
|
236 |
+
$this->upgrade_finished();
|
237 |
+
|
|
|
|
|
238 |
return;
|
239 |
}
|
240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
// loop through and update s3 meta with region
|
242 |
foreach ( $all_attachments as $blog_id => $attachments ) {
|
243 |
+
$this->as3cf->switch_to_blog( $blog_id );
|
|
|
|
|
244 |
|
245 |
foreach ( $attachments as $attachment ) {
|
246 |
+
if ( $this->error_count >= $this->error_threshold ) {
|
247 |
+
$this->upgrade_error( $session );
|
|
|
|
|
|
|
|
|
248 |
|
249 |
+
return;
|
|
|
250 |
}
|
251 |
|
252 |
+
// Do the actual upgrade to the attachment
|
253 |
+
$this->upgrade_attachment( $attachment );
|
|
|
|
|
|
|
|
|
254 |
|
255 |
+
if ( time() >= $finish || $this->as3cf->memory_exceeded( 'as3cf_update_' . $this->upgrade_name . '_memory_exceeded' ) ) {
|
256 |
+
// Batch limits reached
|
257 |
+
break 2;
|
|
|
|
|
258 |
}
|
259 |
}
|
|
|
|
|
|
|
|
|
260 |
}
|
261 |
|
262 |
+
$this->as3cf->restore_current_blog( $blog_id );
|
263 |
+
|
264 |
$session['processed_blog_ids'] = $processed_blog_ids;
|
265 |
+
$session['error_count'] = $this->error_count;
|
266 |
|
267 |
$this->save_session( $session );
|
268 |
}
|
269 |
|
270 |
/**
|
271 |
+
* Adds notices about issues with upgrades allowing user to restart them
|
|
|
|
|
|
|
272 |
*/
|
273 |
+
function maybe_display_notices() {
|
274 |
+
$action_url = $this->as3cf->get_plugin_page_url( array( 'action' => 'restart_update', 'update' => $this->upgrade_name ), 'self' );
|
275 |
+
$msg_type = 'notice-info';
|
|
|
276 |
|
277 |
+
switch ( $this->get_upgrade_status() ) {
|
278 |
+
case self::STATUS_RUNNING:
|
279 |
+
$msg = sprintf( __( '<strong>Running %s Update</strong> — We’re going through all the Media Library items uploaded to S3 %s This will be done quietly in the background, processing a small batch of Media Library items every %d minutes. There should be no noticeable impact on your server’s performance.', 'as3cf' ), ucfirst( $this->upgrade_type ), $this->running_update_text, $this->cron_interval_in_minutes );
|
280 |
+
$action_text = __( 'Pause Update', 'as3cf' );
|
281 |
+
$action_url = $this->as3cf->get_plugin_page_url( array( 'action' => 'pause_update', 'update' => $this->upgrade_name ), 'self' );
|
282 |
+
break;
|
283 |
+
case self::STATUS_PAUSED:
|
284 |
+
$msg = sprintf( __( '<strong>%s Update Paused</strong> — Updating Media Library %s has been paused.', 'as3cf' ), ucfirst( $this->upgrade_type ), $this->upgrade_type );
|
285 |
+
$action_text = __( 'Restart Update', 'as3cf' );
|
286 |
+
break;
|
287 |
+
case self::STATUS_ERROR:
|
288 |
+
$msg = sprintf( __( '<strong>Error Updating %s</strong> — We ran into some errors attempting to update the %s for all your Media Library items that have been uploaded to S3. Please check your error log for details.', 'as3cf' ), ucfirst( $this->upgrade_type ), $this->upgrade_type );
|
289 |
+
$action_text = __( 'Try Run It Again', 'as3cf' );
|
290 |
+
$msg_type = 'error';
|
291 |
+
break;
|
292 |
+
default:
|
293 |
+
return;
|
294 |
}
|
295 |
|
296 |
+
$msg .= ' <strong><a href="' . $action_url . '">' . $action_text . '</a></strong>';
|
297 |
+
|
298 |
+
$args = array(
|
299 |
+
'message' => $msg,
|
300 |
+
'type' => $msg_type,
|
301 |
+
);
|
302 |
+
|
303 |
+
$this->as3cf->render_view( 'notice', $args );
|
304 |
}
|
305 |
|
306 |
/**
|
307 |
+
* Handler for the running upgrade actions
|
|
|
308 |
*/
|
309 |
+
function maybe_handle_action() {
|
310 |
+
if ( ! isset( $_GET['page'] ) || sanitize_key( $_GET['page'] ) !== $this->as3cf->get_plugin_slug() || ! isset( $_GET['action'] ) ) { // input var okay
|
311 |
+
return;
|
|
|
|
|
312 |
}
|
313 |
|
314 |
+
$method_name = 'action_' . sanitize_key( $_GET['action'] ); // input var okay
|
315 |
+
if ( method_exists( $this, $method_name ) ) {
|
316 |
+
call_user_func( array( $this, $method_name ) );
|
317 |
+
}
|
318 |
}
|
319 |
|
320 |
/**
|
321 |
+
* Exit upgrade with an error
|
322 |
*
|
323 |
+
* @param array $session
|
324 |
*/
|
325 |
+
function upgrade_error( $session ) {
|
326 |
+
$session['status'] = self::STATUS_ERROR;
|
327 |
+
$this->save_session( $session );
|
328 |
+
$this->as3cf->clear_scheduled_event( $this->cron_hook );
|
329 |
}
|
330 |
|
331 |
/**
|
332 |
+
* Complete the upgrade
|
|
|
|
|
333 |
*/
|
334 |
+
function upgrade_finished() {
|
335 |
+
$this->clear_session();
|
336 |
+
$this->as3cf->set_setting( $this->settings_key, $this->upgrade_id );
|
337 |
$this->as3cf->save_settings();
|
338 |
+
$this->as3cf->clear_scheduled_event( $this->cron_hook );
|
339 |
}
|
340 |
|
341 |
/**
|
342 |
+
* Restart upgrade
|
|
|
|
|
|
|
|
|
343 |
*/
|
344 |
+
function action_restart_update() {
|
345 |
+
if ( ! isset( $_GET['update'] ) || $this->upgrade_name !== sanitize_key( $_GET['update'] ) ) {
|
346 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
347 |
}
|
348 |
|
349 |
+
$this->as3cf->schedule_event( $this->cron_hook, $this->cron_schedule_key );
|
350 |
+
$this->change_status_request( self::STATUS_RUNNING );
|
351 |
}
|
352 |
|
353 |
/**
|
354 |
+
* Pause upgrade
|
|
|
|
|
|
|
|
|
|
|
355 |
*/
|
356 |
+
function action_pause_update() {
|
357 |
+
if ( ! isset( $_GET['update'] ) || $this->upgrade_name !== sanitize_key( $_GET['update'] ) ) {
|
358 |
+
return;
|
359 |
+
}
|
360 |
|
361 |
+
$this->as3cf->clear_scheduled_event( $this->cron_hook );
|
362 |
+
$this->change_status_request( self::STATUS_PAUSED );
|
363 |
}
|
364 |
|
365 |
/**
|
366 |
+
* Helper for the above action requests
|
|
|
367 |
*
|
368 |
+
* @param int $status
|
369 |
*/
|
370 |
+
function change_status_request( $status ) {
|
371 |
+
$session = $this->get_session();
|
372 |
+
$session['status'] = $status;
|
373 |
+
$this->save_session( $session );
|
374 |
|
375 |
+
$url = $this->as3cf->get_plugin_page_url( array(), 'self' );
|
376 |
+
wp_redirect( $url );
|
377 |
+
exit;
|
378 |
}
|
379 |
|
380 |
/**
|
381 |
+
* Add custom cron interval schedules
|
382 |
*
|
383 |
+
* @param array $schedules
|
|
|
|
|
384 |
*
|
385 |
+
* @return array
|
386 |
*/
|
387 |
+
function cron_schedules( $schedules ) {
|
388 |
+
// Add the upgrade interval to the existing schedules.
|
389 |
+
$schedules[ $this->cron_schedule_key ] = array(
|
390 |
+
'interval' => $this->cron_interval_in_minutes * 60,
|
391 |
+
'display' => sprintf( __( 'Every %d Minutes', 'as3cf' ), $this->cron_interval_in_minutes ),
|
392 |
+
);
|
393 |
|
394 |
+
return $schedules;
|
395 |
+
}
|
|
|
396 |
|
397 |
+
/**
|
398 |
+
* Get the current status of the upgrade
|
399 |
+
* See STATUS_* constants in the class declaration above.
|
400 |
+
*/
|
401 |
+
function get_upgrade_status() {
|
402 |
+
$session = $this->get_session();
|
403 |
|
404 |
+
if ( ! isset( $session['status'] ) ) {
|
405 |
+
return '';
|
406 |
}
|
407 |
|
408 |
+
return $session['status'];
|
409 |
+
}
|
410 |
|
411 |
+
/**
|
412 |
+
* Retrieve session data from plugin settings
|
413 |
+
*
|
414 |
+
* @return array
|
415 |
+
*/
|
416 |
+
function get_session() {
|
417 |
+
return get_site_option( 'update_' . $this->upgrade_name . '_session', array() );
|
418 |
+
}
|
419 |
|
420 |
+
/**
|
421 |
+
* Store data to be used between requests in plugin settings
|
422 |
+
*
|
423 |
+
* @param array $session session data to store
|
424 |
+
*/
|
425 |
+
function save_session( $session ) {
|
426 |
+
update_site_option( 'update_' . $this->upgrade_name . '_session', $session );
|
427 |
+
}
|
428 |
|
429 |
+
/**
|
430 |
+
* Remove the session data to be used between requests
|
431 |
+
*
|
432 |
+
*/
|
433 |
+
function clear_session() {
|
434 |
+
delete_site_option( 'update_' . $this->upgrade_name . '_session' );
|
435 |
}
|
436 |
}
|
classes/upgrades/as3cf-file-sizes.php
ADDED
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Update File Sizes
|
4 |
+
*
|
5 |
+
* @package amazon-s3-and-cloudfront
|
6 |
+
* @subpackage Classes/Upgrades/File-Sizes
|
7 |
+
* @copyright Copyright (c) 2015, Delicious Brains
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 0.9.3
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* AS3CF_Upgrade_File_Sizes Class
|
19 |
+
*
|
20 |
+
* This class handles updating the file sizes in the meta data
|
21 |
+
* for attachments that have been removed from the local server
|
22 |
+
*
|
23 |
+
* @since 0.9.3
|
24 |
+
*/
|
25 |
+
class AS3CF_Upgrade_File_Sizes extends AS3CF_Upgrade {
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Initiate the upgrade
|
29 |
+
*
|
30 |
+
* @param object $as3cf Instance of calling class
|
31 |
+
*/
|
32 |
+
public function __construct( $as3cf ) {
|
33 |
+
$this->upgrade_id = 2;
|
34 |
+
$this->upgrade_name = 'file_sizes';
|
35 |
+
$this->upgrade_type = 'attachments';
|
36 |
+
|
37 |
+
$this->running_update_text = __( 'and updating the metadata with the sizes of files that have been removed from the server. This will allow us to serve the correct size for media items and the total space used in Multisite subsites.', 'as3cf' );
|
38 |
+
|
39 |
+
parent::__construct( $as3cf );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Get the total file sizes for an attachment and associated files.
|
44 |
+
*
|
45 |
+
* @param $attachment
|
46 |
+
*
|
47 |
+
* @return bool
|
48 |
+
*/
|
49 |
+
function upgrade_attachment( $attachment ) {
|
50 |
+
$s3object = unserialize( $attachment->s3object );
|
51 |
+
if ( false === $s3object ) {
|
52 |
+
error_log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
|
53 |
+
$this->error_count++;
|
54 |
+
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
|
58 |
+
$region = $this->as3cf->get_s3object_region( $s3object );
|
59 |
+
if ( is_wp_error( $region ) ) {
|
60 |
+
error_log( 'Failed to get the region for the bucket of the attachment ' . $attachment->ID );
|
61 |
+
$this->error_count++;
|
62 |
+
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
|
66 |
+
$s3client = $this->as3cf->get_s3client( $region, true );
|
67 |
+
$main_file = $s3object['key'];
|
68 |
+
|
69 |
+
$path_parts = pathinfo( $main_file );
|
70 |
+
$prefix = trailingslashit( dirname( $s3object['key'] ) );
|
71 |
+
|
72 |
+
// Used to search S3 for all files related to an attachment
|
73 |
+
$search_prefix = $prefix . basename( $main_file, '.' . $path_parts['extension'] );
|
74 |
+
|
75 |
+
$args = array(
|
76 |
+
'Bucket' => $s3object['bucket'],
|
77 |
+
'Prefix' => $search_prefix,
|
78 |
+
);
|
79 |
+
|
80 |
+
try {
|
81 |
+
// List objects for the attachment
|
82 |
+
$result = $s3client->ListObjects( $args );
|
83 |
+
} catch ( Exception $e ) {
|
84 |
+
error_log( 'Error listing objects of prefix ' . $search_prefix . ' for attachment ' . $attachment->ID . ' from S3: ' . $e->getMessage() );
|
85 |
+
$this->error_count ++;
|
86 |
+
|
87 |
+
return false;
|
88 |
+
}
|
89 |
+
|
90 |
+
$file_size_total = 0;
|
91 |
+
$main_file_size = 0;
|
92 |
+
|
93 |
+
foreach ( $result->get( 'Contents' ) as $object ) {
|
94 |
+
if ( ! isset( $object['Size'] ) ) {
|
95 |
+
continue;
|
96 |
+
}
|
97 |
+
|
98 |
+
$size = $object['Size'];
|
99 |
+
|
100 |
+
// Increment the total size of files for the attachment
|
101 |
+
$file_size_total += $size;
|
102 |
+
|
103 |
+
if ( $object['Key'] === $main_file ) {
|
104 |
+
// Record the size of the main file
|
105 |
+
$main_file_size = $size;
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
if ( 0 === $file_size_total ) {
|
110 |
+
error_log( 'Total file size for the attachment is 0: ' . $attachment->ID );
|
111 |
+
$this->error_count ++;
|
112 |
+
|
113 |
+
return false;
|
114 |
+
}
|
115 |
+
|
116 |
+
// Update the main file size for the attachment
|
117 |
+
$meta = get_post_meta( $attachment->ID, '_wp_attachment_metadata', true );
|
118 |
+
$meta['filesize'] = $main_file_size;
|
119 |
+
update_post_meta( $attachment->ID, '_wp_attachment_metadata', $meta );
|
120 |
+
|
121 |
+
// Add the total file size for all image sizes
|
122 |
+
update_post_meta( $attachment->ID, 'wpos3_filesize_total', $file_size_total );
|
123 |
+
|
124 |
+
return true;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Get a count of all attachments without region in their S3 metadata
|
129 |
+
* for the whole site
|
130 |
+
*
|
131 |
+
* @return int
|
132 |
+
*/
|
133 |
+
function count_attachments_to_process() {
|
134 |
+
// get the table prefixes for all the blogs
|
135 |
+
$table_prefixes = $this->as3cf->get_all_blog_table_prefixes();
|
136 |
+
$all_count = 0;
|
137 |
+
|
138 |
+
foreach ( $table_prefixes as $blog_id => $table_prefix ) {
|
139 |
+
$count = $this->get_attachments_removed_from_server( $table_prefix, true );
|
140 |
+
$all_count += $count;
|
141 |
+
}
|
142 |
+
|
143 |
+
return $all_count;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Get all attachments that don't have region in their S3 meta data for a blog
|
148 |
+
*
|
149 |
+
* @param string $prefix
|
150 |
+
* @param int $limit
|
151 |
+
*
|
152 |
+
* @return mixed
|
153 |
+
*/
|
154 |
+
function get_attachments_to_process( $prefix, $limit ) {
|
155 |
+
$attachments = $this->get_attachments_removed_from_server( $prefix, false, $limit );
|
156 |
+
|
157 |
+
return $attachments;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Wrapper for database call to get attachments uploaded to S3,
|
162 |
+
* that don't have the file size meta added already
|
163 |
+
*
|
164 |
+
* @param string $prefix
|
165 |
+
* @param null|int $limit
|
166 |
+
*
|
167 |
+
* @return mixed
|
168 |
+
*/
|
169 |
+
function get_s3_attachments( $prefix, $limit = null ) {
|
170 |
+
global $wpdb;
|
171 |
+
|
172 |
+
$sql = "SELECT pm1.`post_id` as `ID`, pm1.`meta_value` AS 's3object'
|
173 |
+
FROM `{$prefix}postmeta` pm1
|
174 |
+
LEFT OUTER JOIN `{$prefix}postmeta` pm2
|
175 |
+
ON pm1.`post_id` = pm2.`post_id`
|
176 |
+
AND pm2.`meta_key` = 'wpos3_filesize_total'
|
177 |
+
WHERE pm1.`meta_key` = 'amazonS3_info'
|
178 |
+
AND pm2.`post_id` is null";
|
179 |
+
|
180 |
+
if ( ! is_null( $limit ) ) {
|
181 |
+
$sql .= ' LIMIT %d';
|
182 |
+
|
183 |
+
$sql = $wpdb->prepare( $sql, $limit );
|
184 |
+
}
|
185 |
+
|
186 |
+
return $wpdb->get_results( $sql, OBJECT );
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Get S3 attachments that have had their local file removed from the server
|
191 |
+
*
|
192 |
+
* @param string $prefix
|
193 |
+
* @param bool|false $count
|
194 |
+
* @param null|int $limit
|
195 |
+
*
|
196 |
+
* @return array|int
|
197 |
+
*/
|
198 |
+
function get_attachments_removed_from_server( $prefix, $count = false, $limit = null ) {
|
199 |
+
$all_attachments = $this->get_s3_attachments( $prefix, $limit );
|
200 |
+
$attachments = array();
|
201 |
+
|
202 |
+
foreach ( $all_attachments as $attachment ) {
|
203 |
+
if ( ! file_exists( get_attached_file( $attachment->ID, true ) ) ) {
|
204 |
+
$attachments[] = $attachment;
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
if ( $count ) {
|
209 |
+
return count( $attachments );
|
210 |
+
}
|
211 |
+
|
212 |
+
return $attachments;
|
213 |
+
}
|
214 |
+
|
215 |
+
}
|
classes/upgrades/as3cf-region-meta.php
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Upgrade Region in Meta
|
4 |
+
*
|
5 |
+
* @package amazon-s3-and-cloudfront
|
6 |
+
* @subpackage Classes/Upgrades/Region-Meta
|
7 |
+
* @copyright Copyright (c) 2014, Delicious Brains
|
8 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
+
* @since 0.6.2
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* AS3CF_Upgrade_Region_Meta Class
|
19 |
+
*
|
20 |
+
* This class handles updating the region of the attachment's bucket in the meta data
|
21 |
+
*
|
22 |
+
* @since 0.6.2
|
23 |
+
*/
|
24 |
+
class AS3CF_Upgrade_Region_Meta extends AS3CF_Upgrade {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Initiate the upgrade
|
28 |
+
*
|
29 |
+
* @param object $as3cf Instance of calling class
|
30 |
+
*/
|
31 |
+
public function __construct( $as3cf ) {
|
32 |
+
$this->upgrade_id = 1;
|
33 |
+
$this->upgrade_name = 'meta_with_region';
|
34 |
+
$this->upgrade_type = 'metadata';
|
35 |
+
|
36 |
+
$this->running_update_text = __( 'and updating the metadata with the bucket region it is served from. This will allow us to serve your files from the proper S3 region subdomain <span style="white-space:nowrap;">(e.g. s3-us-west-2.amazonaws.com)</span>.', 'as3cf' );
|
37 |
+
|
38 |
+
parent::__construct( $as3cf );
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Get the region for the bucket where an attachment is located, update the S3 meta.
|
43 |
+
*
|
44 |
+
* @param $attachment
|
45 |
+
*
|
46 |
+
* @return bool
|
47 |
+
*/
|
48 |
+
function upgrade_attachment( $attachment ) {
|
49 |
+
$s3object = unserialize( $attachment->s3object );
|
50 |
+
if ( false === $s3object ) {
|
51 |
+
error_log( 'Failed to unserialize S3 meta for attachment ' . $attachment->ID . ': ' . $attachment->s3object );
|
52 |
+
$this->error_count++;
|
53 |
+
|
54 |
+
return false;
|
55 |
+
}
|
56 |
+
// retrieve region and update the attachment metadata
|
57 |
+
$region = $this->as3cf->get_s3object_region( $s3object, $attachment->ID );
|
58 |
+
if ( is_wp_error( $region ) ) {
|
59 |
+
error_log( 'Error updating region: ' . $region->get_error_message() );
|
60 |
+
$this->error_count++;
|
61 |
+
|
62 |
+
return false;
|
63 |
+
}
|
64 |
+
|
65 |
+
return true;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Get a count of all attachments without region in their S3 metadata
|
70 |
+
* for the whole site
|
71 |
+
*
|
72 |
+
* @return int
|
73 |
+
*/
|
74 |
+
function count_attachments_to_process() {
|
75 |
+
// get the table prefixes for all the blogs
|
76 |
+
$table_prefixes = $this->as3cf->get_all_blog_table_prefixes();
|
77 |
+
$all_count = 0;
|
78 |
+
|
79 |
+
foreach ( $table_prefixes as $blog_id => $table_prefix ) {
|
80 |
+
$count = $this->count_attachments_without_region( $table_prefix );
|
81 |
+
$all_count += $count;
|
82 |
+
}
|
83 |
+
|
84 |
+
return $all_count;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Get all attachments that don't have region in their S3 meta data for a blog
|
89 |
+
*
|
90 |
+
* @param string $prefix
|
91 |
+
* @param int $limit
|
92 |
+
*
|
93 |
+
* @return mixed
|
94 |
+
*/
|
95 |
+
function get_attachments_to_process( $prefix, $limit ) {
|
96 |
+
$attachments = $this->get_attachments_without_region_results( $prefix, false, $limit );
|
97 |
+
|
98 |
+
return $attachments;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Get a count of attachments that don't have region in their S3 meta data for a blog
|
103 |
+
* @param $prefix
|
104 |
+
*
|
105 |
+
* @return int
|
106 |
+
*/
|
107 |
+
function count_attachments_without_region( $prefix ) {
|
108 |
+
$count = $this->get_attachments_without_region_results( $prefix, true );
|
109 |
+
|
110 |
+
return $count;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Wrapper for database call to get attachments without region
|
115 |
+
*
|
116 |
+
* @param string $prefix
|
117 |
+
* @param bool $count return count of attachments
|
118 |
+
* @param null|int $limit
|
119 |
+
*
|
120 |
+
* @return mixed
|
121 |
+
*/
|
122 |
+
function get_attachments_without_region_results( $prefix, $count = false, $limit = null ) {
|
123 |
+
global $wpdb;
|
124 |
+
|
125 |
+
$sql = " FROM `{$prefix}postmeta`
|
126 |
+
WHERE `meta_key` = 'amazonS3_info'
|
127 |
+
AND `meta_value` NOT LIKE '%%\"region\"%%'";
|
128 |
+
|
129 |
+
if ( $count ) {
|
130 |
+
$sql = 'SELECT COUNT(*)' . $sql;
|
131 |
+
|
132 |
+
return $wpdb->get_var( $sql );
|
133 |
+
}
|
134 |
+
|
135 |
+
$sql = "SELECT `post_id` as `ID`, `meta_value` AS 's3object'" . $sql;
|
136 |
+
|
137 |
+
if ( ! is_null( $limit ) ) {
|
138 |
+
$sql .= ' LIMIT %d';
|
139 |
+
|
140 |
+
$sql = $wpdb->prepare( $sql, $limit );
|
141 |
+
}
|
142 |
+
|
143 |
+
return $wpdb->get_results( $sql, OBJECT );
|
144 |
+
}
|
145 |
+
}
|
classes/wp-aws-compatibility-check.php
CHANGED
@@ -39,13 +39,18 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
39 |
*/
|
40 |
protected $plugin_file_path;
|
41 |
|
|
|
|
|
|
|
|
|
|
|
42 |
/**
|
43 |
* @var null|string The key of the required parent plugin, e.g. amazon-web-services
|
44 |
*/
|
45 |
protected $parent_plugin_slug;
|
46 |
|
47 |
/**
|
48 |
-
* @var null|
|
49 |
*/
|
50 |
protected $parent_plugin_required_version;
|
51 |
|
@@ -74,6 +79,22 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
74 |
*/
|
75 |
protected $notice_class = 'error';
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
function __construct( $plugin_name, $plugin_slug, $plugin_file_path, $parent_plugin_name = null, $parent_plugin_slug = null, $parent_plugin_required_version = null, $parent_plugin_filename = null, $deactivate_if_not_compatible = false, $parent_plugin_url = null ) {
|
78 |
$this->plugin_name = $plugin_name;
|
79 |
$this->plugin_slug = $plugin_slug;
|
@@ -117,7 +138,7 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
117 |
* @return string
|
118 |
*/
|
119 |
function get_parent_plugin_name() {
|
120 |
-
if ( $this->parent_plugin_name ) {
|
121 |
return $this->parent_plugin_name;
|
122 |
}
|
123 |
|
@@ -127,10 +148,10 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
127 |
/**
|
128 |
* Get the class of the parent plugin
|
129 |
*
|
130 |
-
* @return
|
131 |
*/
|
132 |
function get_parent_plugin_class() {
|
133 |
-
if ( $this->parent_plugin_slug ) {
|
134 |
$class = ucwords( str_replace( '-', ' ', $this->parent_plugin_slug ) );
|
135 |
|
136 |
return str_replace( ' ', '_', $class );
|
@@ -175,7 +196,7 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
175 |
/**
|
176 |
* Get the URL for the parent plugin. Defaults to a wordpress.org URL.
|
177 |
*
|
178 |
-
* @return
|
179 |
*/
|
180 |
function get_parent_plugin_url() {
|
181 |
if ( ! is_null( $this->parent_plugin_slug ) ) {
|
@@ -399,10 +420,8 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
399 |
return;
|
400 |
}
|
401 |
|
402 |
-
|
403 |
-
|
404 |
-
if ( 'update.php' === $pagenow && isset( $_GET['action'] ) && 'install-plugin' === $_GET['action'] ) {
|
405 |
-
// Don't show notice when installing plugins
|
406 |
return;
|
407 |
}
|
408 |
|
@@ -415,7 +434,7 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
415 |
function get_admin_notice() {
|
416 |
$error_msg = $this->get_error_msg();
|
417 |
|
418 |
-
if (
|
419 |
return;
|
420 |
}
|
421 |
|
@@ -447,24 +466,37 @@ if ( ! class_exists( 'WP_AWS_Compatibility_Check' ) ) {
|
|
447 |
* @return bool
|
448 |
*/
|
449 |
public static function is_installing_or_updating_plugins() {
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
global $pagenow;
|
451 |
|
452 |
if ( 'update.php' === $pagenow && isset( $_GET['action'] ) && 'install-plugin' === $_GET['action'] ) {
|
453 |
// We are installing a plugin
|
454 |
-
|
455 |
}
|
456 |
|
457 |
-
if ( 'plugins.php' === $pagenow && isset( $_POST['action'] )
|
458 |
-
|
459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
}
|
461 |
|
462 |
if ( 'update-core.php' === $pagenow && isset( $_GET['action'] ) && 'do-plugin-upgrade' === $_GET['action'] ) {
|
463 |
// We are updating plugins from the updates page
|
464 |
-
|
465 |
}
|
466 |
|
467 |
-
return
|
468 |
}
|
469 |
}
|
470 |
}
|
39 |
*/
|
40 |
protected $plugin_file_path;
|
41 |
|
42 |
+
/**
|
43 |
+
* @var null|string The name of the required parent plugin
|
44 |
+
*/
|
45 |
+
protected $parent_plugin_name;
|
46 |
+
|
47 |
/**
|
48 |
* @var null|string The key of the required parent plugin, e.g. amazon-web-services
|
49 |
*/
|
50 |
protected $parent_plugin_slug;
|
51 |
|
52 |
/**
|
53 |
+
* @var null|string The required version of the parent plugin
|
54 |
*/
|
55 |
protected $parent_plugin_required_version;
|
56 |
|
79 |
*/
|
80 |
protected $notice_class = 'error';
|
81 |
|
82 |
+
/**
|
83 |
+
* @var bool Used to store if we are installing or updating plugins once per page request
|
84 |
+
*/
|
85 |
+
protected static $is_installing_or_updating_plugins;
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param string $plugin_name
|
89 |
+
* @param string $plugin_slug
|
90 |
+
* @param string $plugin_file_path
|
91 |
+
* @param string|null $parent_plugin_name
|
92 |
+
* @param string|null $parent_plugin_slug
|
93 |
+
* @param string|null $parent_plugin_required_version
|
94 |
+
* @param string|null $parent_plugin_filename
|
95 |
+
* @param bool|false $deactivate_if_not_compatible
|
96 |
+
* @param string|null $parent_plugin_url
|
97 |
+
*/
|
98 |
function __construct( $plugin_name, $plugin_slug, $plugin_file_path, $parent_plugin_name = null, $parent_plugin_slug = null, $parent_plugin_required_version = null, $parent_plugin_filename = null, $deactivate_if_not_compatible = false, $parent_plugin_url = null ) {
|
99 |
$this->plugin_name = $plugin_name;
|
100 |
$this->plugin_slug = $plugin_slug;
|
138 |
* @return string
|
139 |
*/
|
140 |
function get_parent_plugin_name() {
|
141 |
+
if ( ! is_null( $this->parent_plugin_name ) ) {
|
142 |
return $this->parent_plugin_name;
|
143 |
}
|
144 |
|
148 |
/**
|
149 |
* Get the class of the parent plugin
|
150 |
*
|
151 |
+
* @return string
|
152 |
*/
|
153 |
function get_parent_plugin_class() {
|
154 |
+
if ( ! is_null( $this->parent_plugin_slug ) ) {
|
155 |
$class = ucwords( str_replace( '-', ' ', $this->parent_plugin_slug ) );
|
156 |
|
157 |
return str_replace( ' ', '_', $class );
|
196 |
/**
|
197 |
* Get the URL for the parent plugin. Defaults to a wordpress.org URL.
|
198 |
*
|
199 |
+
* @return string
|
200 |
*/
|
201 |
function get_parent_plugin_url() {
|
202 |
if ( ! is_null( $this->parent_plugin_slug ) ) {
|
420 |
return;
|
421 |
}
|
422 |
|
423 |
+
if ( self::is_installing_or_updating_plugins() ) {
|
424 |
+
// Don't show notice when installing or updating plugins
|
|
|
|
|
425 |
return;
|
426 |
}
|
427 |
|
434 |
function get_admin_notice() {
|
435 |
$error_msg = $this->get_error_msg();
|
436 |
|
437 |
+
if ( false === $error_msg || '' === $error_msg ) {
|
438 |
return;
|
439 |
}
|
440 |
|
466 |
* @return bool
|
467 |
*/
|
468 |
public static function is_installing_or_updating_plugins() {
|
469 |
+
if ( ! is_null( self::$is_installing_or_updating_plugins ) ) {
|
470 |
+
return self::$is_installing_or_updating_plugins;
|
471 |
+
}
|
472 |
+
|
473 |
+
self::$is_installing_or_updating_plugins = false;
|
474 |
+
|
475 |
global $pagenow;
|
476 |
|
477 |
if ( 'update.php' === $pagenow && isset( $_GET['action'] ) && 'install-plugin' === $_GET['action'] ) {
|
478 |
// We are installing a plugin
|
479 |
+
self::$is_installing_or_updating_plugins = true;
|
480 |
}
|
481 |
|
482 |
+
if ( 'plugins.php' === $pagenow && isset( $_POST['action'] ) ) {
|
483 |
+
$action = $_POST['action'];
|
484 |
+
if ( isset( $_POST['action2'] ) && '-1' !== $_POST['action2'] ) {
|
485 |
+
$action = $_POST['action2'];
|
486 |
+
}
|
487 |
+
|
488 |
+
if ( 'update-selected' === $action ) {
|
489 |
+
// We are updating plugins from the plugin page
|
490 |
+
self::$is_installing_or_updating_plugins = true;
|
491 |
+
}
|
492 |
}
|
493 |
|
494 |
if ( 'update-core.php' === $pagenow && isset( $_GET['action'] ) && 'do-plugin-upgrade' === $_GET['action'] ) {
|
495 |
// We are updating plugins from the updates page
|
496 |
+
self::$is_installing_or_updating_plugins = true;
|
497 |
}
|
498 |
|
499 |
+
return self::$is_installing_or_updating_plugins;
|
500 |
}
|
501 |
}
|
502 |
}
|
classes/wp-aws-uninstall.php
CHANGED
@@ -26,37 +26,45 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
|
|
26 |
class WP_AWS_Uninstall {
|
27 |
|
28 |
/**
|
29 |
-
* @var array Options to be deleted
|
30 |
*/
|
31 |
protected $options;
|
32 |
|
33 |
/**
|
34 |
-
* @var array Post meta to be deleted
|
35 |
*/
|
36 |
protected $postmeta;
|
37 |
|
38 |
/**
|
39 |
-
* @var array Cron hooks to be unscheduled
|
40 |
*/
|
41 |
protected $crons;
|
42 |
|
43 |
/**
|
44 |
-
* @var array Transients to be deleted
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
*/
|
46 |
protected $transients;
|
47 |
|
48 |
/**
|
49 |
-
* @var Blog(s) in site
|
50 |
*/
|
51 |
protected $blog_ids;
|
52 |
|
53 |
/**
|
54 |
* WP_AWS_Uninstall constructor.
|
55 |
*
|
56 |
-
* @param array $options
|
57 |
-
* @param array $postmeta
|
58 |
-
* @param array $crons
|
59 |
-
* @param array $transients
|
60 |
*/
|
61 |
public function __construct(
|
62 |
$options = array(),
|
@@ -64,10 +72,10 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
|
|
64 |
$crons = array(),
|
65 |
$transients = array()
|
66 |
) {
|
67 |
-
$this->options = $options;
|
68 |
-
$this->postmeta = $postmeta;
|
69 |
-
$this->crons = $crons;
|
70 |
-
$this->transients = $transients;
|
71 |
|
72 |
$this->set_blog_ids();
|
73 |
|
@@ -81,7 +89,7 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
|
|
81 |
* Set the blog id(s) for a site
|
82 |
*/
|
83 |
private function set_blog_ids() {
|
84 |
-
$blog_ids
|
85 |
if ( function_exists( 'is_multisite' ) && is_multisite() ) {
|
86 |
$args = array(
|
87 |
'limit' => false,
|
@@ -97,33 +105,42 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
|
|
97 |
}
|
98 |
|
99 |
/**
|
100 |
-
*
|
101 |
*
|
102 |
-
* @param
|
103 |
*
|
104 |
* @return bool
|
105 |
*/
|
106 |
-
private function
|
107 |
-
|
108 |
-
|
|
|
|
|
109 |
}
|
110 |
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
|
116 |
-
return
|
117 |
}
|
118 |
|
119 |
/**
|
120 |
* Delete site wide options
|
121 |
*/
|
122 |
public function delete_options() {
|
123 |
-
if ( ! $this->check_property( 'options' ) ) {
|
124 |
-
return;
|
125 |
-
}
|
126 |
-
|
127 |
foreach ( $this->options as $option ) {
|
128 |
delete_site_option( $option );
|
129 |
}
|
@@ -133,10 +150,6 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
|
|
133 |
* Delete post meta data for all blogs
|
134 |
*/
|
135 |
public function delete_postmeta() {
|
136 |
-
if ( ! $this->check_property( 'postmeta' ) ) {
|
137 |
-
return;
|
138 |
-
}
|
139 |
-
|
140 |
global $wpdb;
|
141 |
|
142 |
foreach ( $this->blog_ids as $blog_id ) {
|
@@ -153,10 +166,6 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
|
|
153 |
* Clear any scheduled cron jobs
|
154 |
*/
|
155 |
public function clear_crons() {
|
156 |
-
if ( ! $this->check_property( 'crons' ) ) {
|
157 |
-
return;
|
158 |
-
}
|
159 |
-
|
160 |
foreach ( $this->crons as $cron ) {
|
161 |
$timestamp = wp_next_scheduled( $cron );
|
162 |
if ( $timestamp ) {
|
@@ -166,15 +175,44 @@ if ( ! class_exists( 'WP_AWS_Uninstall' ) ) {
|
|
166 |
}
|
167 |
|
168 |
/**
|
169 |
-
* Delete
|
170 |
*/
|
171 |
public function delete_transients() {
|
172 |
-
if ( ! $this->
|
|
|
|
|
|
|
|
|
|
|
173 |
return;
|
174 |
}
|
175 |
|
176 |
-
|
177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
}
|
179 |
}
|
180 |
}
|
26 |
class WP_AWS_Uninstall {
|
27 |
|
28 |
/**
|
29 |
+
* @var array|string Options to be deleted
|
30 |
*/
|
31 |
protected $options;
|
32 |
|
33 |
/**
|
34 |
+
* @var array|string Post meta to be deleted
|
35 |
*/
|
36 |
protected $postmeta;
|
37 |
|
38 |
/**
|
39 |
+
* @var array|string Cron hooks to be unscheduled
|
40 |
*/
|
41 |
protected $crons;
|
42 |
|
43 |
/**
|
44 |
+
* @var array|string Transients to be deleted, this can be site wide and subsite, e.g.
|
45 |
+
*
|
46 |
+
* array(
|
47 |
+
* 'site' => array(...),
|
48 |
+
* 'subsite' => array(...),
|
49 |
+
* )
|
50 |
+
*
|
51 |
+
* By default, an array of transients will be treated as site wide.
|
52 |
+
*
|
53 |
*/
|
54 |
protected $transients;
|
55 |
|
56 |
/**
|
57 |
+
* @var array Blog(s) in site
|
58 |
*/
|
59 |
protected $blog_ids;
|
60 |
|
61 |
/**
|
62 |
* WP_AWS_Uninstall constructor.
|
63 |
*
|
64 |
+
* @param array|string $options
|
65 |
+
* @param array|string $postmeta
|
66 |
+
* @param array|string $crons
|
67 |
+
* @param array|string $transients
|
68 |
*/
|
69 |
public function __construct(
|
70 |
$options = array(),
|
72 |
$crons = array(),
|
73 |
$transients = array()
|
74 |
) {
|
75 |
+
$this->options = $this->maybe_convert_to_array( $options );
|
76 |
+
$this->postmeta = $this->maybe_convert_to_array( $postmeta );
|
77 |
+
$this->crons = $this->maybe_convert_to_array( $crons );
|
78 |
+
$this->transients = $this->maybe_convert_to_array( $transients );
|
79 |
|
80 |
$this->set_blog_ids();
|
81 |
|
89 |
* Set the blog id(s) for a site
|
90 |
*/
|
91 |
private function set_blog_ids() {
|
92 |
+
$blog_ids = array( 1 );
|
93 |
if ( function_exists( 'is_multisite' ) && is_multisite() ) {
|
94 |
$args = array(
|
95 |
'limit' => false,
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
+
* Is the current blog ID that specified in wp-config.php
|
109 |
*
|
110 |
+
* @param int $blog_id
|
111 |
*
|
112 |
* @return bool
|
113 |
*/
|
114 |
+
private function is_current_blog( $blog_id ) {
|
115 |
+
$default = defined( 'BLOG_ID_CURRENT_SITE' ) ? BLOG_ID_CURRENT_SITE : 1;
|
116 |
+
|
117 |
+
if ( $default === $blog_id ) {
|
118 |
+
return true;
|
119 |
}
|
120 |
|
121 |
+
return false;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Helper to ensure a value is an array
|
126 |
+
*
|
127 |
+
* @param array|string $data
|
128 |
+
*
|
129 |
+
* @return array
|
130 |
+
*/
|
131 |
+
private function maybe_convert_to_array( $data ) {
|
132 |
+
if ( ! is_array( $data ) ) {
|
133 |
+
// Convert a string to an array
|
134 |
+
$data = array( $data );
|
135 |
}
|
136 |
|
137 |
+
return $data;
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
* Delete site wide options
|
142 |
*/
|
143 |
public function delete_options() {
|
|
|
|
|
|
|
|
|
144 |
foreach ( $this->options as $option ) {
|
145 |
delete_site_option( $option );
|
146 |
}
|
150 |
* Delete post meta data for all blogs
|
151 |
*/
|
152 |
public function delete_postmeta() {
|
|
|
|
|
|
|
|
|
153 |
global $wpdb;
|
154 |
|
155 |
foreach ( $this->blog_ids as $blog_id ) {
|
166 |
* Clear any scheduled cron jobs
|
167 |
*/
|
168 |
public function clear_crons() {
|
|
|
|
|
|
|
|
|
169 |
foreach ( $this->crons as $cron ) {
|
170 |
$timestamp = wp_next_scheduled( $cron );
|
171 |
if ( $timestamp ) {
|
175 |
}
|
176 |
|
177 |
/**
|
178 |
+
* Delete transients
|
179 |
*/
|
180 |
public function delete_transients() {
|
181 |
+
if ( ! isset( $this->transients['site'] ) && ! isset( $this->transients['subsite'] ) ) {
|
182 |
+
// Single array of site wide transients
|
183 |
+
foreach ( $this->transients as $transient ) {
|
184 |
+
delete_site_transient( $transient );
|
185 |
+
}
|
186 |
+
|
187 |
return;
|
188 |
}
|
189 |
|
190 |
+
// Deal with site wide transients
|
191 |
+
if ( isset( $this->transients['site'] ) ) {
|
192 |
+
$site_transients = $this->maybe_convert_to_array( $this->transients['site'] );
|
193 |
+
|
194 |
+
foreach ( $site_transients as $transient ) {
|
195 |
+
delete_site_transient( $transient );
|
196 |
+
}
|
197 |
+
}
|
198 |
+
|
199 |
+
// Deal with subsite specific transients
|
200 |
+
if ( isset( $this->transients['subsite'] ) ) {
|
201 |
+
$subsite_transients = $this->maybe_convert_to_array( $this->transients['subsite'] );
|
202 |
+
|
203 |
+
foreach ( $this->blog_ids as $blog_id ) {
|
204 |
+
if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
|
205 |
+
switch_to_blog( $blog_id );
|
206 |
+
}
|
207 |
+
|
208 |
+
foreach ( $subsite_transients as $transient ) {
|
209 |
+
delete_transient( $transient );
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
|
214 |
+
restore_current_blog();
|
215 |
+
}
|
216 |
}
|
217 |
}
|
218 |
}
|
composer.lock
DELETED
@@ -1,107 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"_readme": [
|
3 |
-
"This file locks the dependencies of your project to a known state",
|
4 |
-
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
5 |
-
"This file is @generated automatically"
|
6 |
-
],
|
7 |
-
"hash": "4b6bce2aaae303cfd3fc478e7cc55366",
|
8 |
-
"packages": [
|
9 |
-
{
|
10 |
-
"name": "composer/installers",
|
11 |
-
"version": "v1.0.18",
|
12 |
-
"source": {
|
13 |
-
"type": "git",
|
14 |
-
"url": "https://github.com/composer/installers.git",
|
15 |
-
"reference": "74fb0a7a1a23696d9c8cc2fba5903f6711cdd067"
|
16 |
-
},
|
17 |
-
"dist": {
|
18 |
-
"type": "zip",
|
19 |
-
"url": "https://api.github.com/repos/composer/installers/zipball/74fb0a7a1a23696d9c8cc2fba5903f6711cdd067",
|
20 |
-
"reference": "74fb0a7a1a23696d9c8cc2fba5903f6711cdd067",
|
21 |
-
"shasum": ""
|
22 |
-
},
|
23 |
-
"replace": {
|
24 |
-
"roundcube/plugin-installer": "*",
|
25 |
-
"shama/baton": "*"
|
26 |
-
},
|
27 |
-
"require-dev": {
|
28 |
-
"composer/composer": "1.0.*@dev",
|
29 |
-
"phpunit/phpunit": "4.1.*"
|
30 |
-
},
|
31 |
-
"type": "composer-installer",
|
32 |
-
"extra": {
|
33 |
-
"class": "Composer\\Installers\\Installer",
|
34 |
-
"branch-alias": {
|
35 |
-
"dev-master": "1.0-dev"
|
36 |
-
}
|
37 |
-
},
|
38 |
-
"autoload": {
|
39 |
-
"psr-0": {
|
40 |
-
"Composer\\Installers\\": "src/"
|
41 |
-
}
|
42 |
-
},
|
43 |
-
"notification-url": "https://packagist.org/downloads/",
|
44 |
-
"license": [
|
45 |
-
"MIT"
|
46 |
-
],
|
47 |
-
"authors": [
|
48 |
-
{
|
49 |
-
"name": "Kyle Robinson Young",
|
50 |
-
"email": "kyle@dontkry.com",
|
51 |
-
"homepage": "https://github.com/shama"
|
52 |
-
}
|
53 |
-
],
|
54 |
-
"description": "A multi-framework Composer library installer",
|
55 |
-
"homepage": "http://composer.github.com/installers/",
|
56 |
-
"keywords": [
|
57 |
-
"Craft",
|
58 |
-
"Dolibarr",
|
59 |
-
"Hurad",
|
60 |
-
"MODX Evo",
|
61 |
-
"OXID",
|
62 |
-
"WolfCMS",
|
63 |
-
"agl",
|
64 |
-
"annotatecms",
|
65 |
-
"bitrix",
|
66 |
-
"cakephp",
|
67 |
-
"chef",
|
68 |
-
"codeigniter",
|
69 |
-
"concrete5",
|
70 |
-
"croogo",
|
71 |
-
"drupal",
|
72 |
-
"elgg",
|
73 |
-
"fuelphp",
|
74 |
-
"installer",
|
75 |
-
"joomla",
|
76 |
-
"kohana",
|
77 |
-
"laravel",
|
78 |
-
"lithium",
|
79 |
-
"magento",
|
80 |
-
"mako",
|
81 |
-
"mediawiki",
|
82 |
-
"modulework",
|
83 |
-
"moodle",
|
84 |
-
"phpbb",
|
85 |
-
"piwik",
|
86 |
-
"ppi",
|
87 |
-
"puppet",
|
88 |
-
"roundcube",
|
89 |
-
"shopware",
|
90 |
-
"silverstripe",
|
91 |
-
"symfony",
|
92 |
-
"typo3",
|
93 |
-
"wordpress",
|
94 |
-
"zend",
|
95 |
-
"zikula"
|
96 |
-
],
|
97 |
-
"time": "2014-08-18 20:00:12"
|
98 |
-
}
|
99 |
-
],
|
100 |
-
"packages-dev": [],
|
101 |
-
"aliases": [],
|
102 |
-
"minimum-stability": "stable",
|
103 |
-
"stability-flags": [],
|
104 |
-
"prefer-stable": false,
|
105 |
-
"platform": [],
|
106 |
-
"platform-dev": []
|
107 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
languages/amazon-s3-and-cloudfront-en.pot
CHANGED
@@ -8,7 +8,7 @@ msgid ""
|
|
8 |
msgstr ""
|
9 |
"Project-Id-Version: amazon-s3-and-cloudfront\n"
|
10 |
"Report-Msgid-Bugs-To: nom@deliciousbrains.com\n"
|
11 |
-
"POT-Creation-Date: 2015-08-
|
12 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
@@ -17,116 +17,120 @@ msgstr ""
|
|
17 |
"Content-Type: text/plain; charset=UTF-8\n"
|
18 |
"Content-Transfer-Encoding: 8bit\n"
|
19 |
|
20 |
-
#:
|
21 |
msgid "Offload S3"
|
22 |
msgstr ""
|
23 |
|
24 |
-
#:
|
25 |
msgid "S3 and CloudFront"
|
26 |
msgstr ""
|
27 |
|
28 |
-
#:
|
29 |
#, php-format
|
30 |
msgid "File %s does not exist"
|
31 |
msgstr ""
|
32 |
|
33 |
-
#:
|
34 |
#, php-format
|
35 |
msgid "Mime type %s is not allowed"
|
36 |
msgstr ""
|
37 |
|
38 |
-
#:
|
39 |
#, php-format
|
40 |
msgid "Error uploading %s to S3: %s"
|
41 |
msgstr ""
|
42 |
|
43 |
-
#:
|
44 |
msgid "Cheatin’ eh?"
|
45 |
msgstr ""
|
46 |
|
47 |
-
#:
|
48 |
msgid "You do not have sufficient permissions to access this page."
|
49 |
msgstr ""
|
50 |
|
51 |
-
#:
|
52 |
msgid "No bucket name provided."
|
53 |
msgstr ""
|
54 |
|
55 |
-
#:
|
|
|
|
|
|
|
|
|
56 |
#, php-format
|
57 |
msgid "There was an error attempting to get the region of the bucket %s: %s"
|
58 |
msgstr ""
|
59 |
|
60 |
-
#:
|
61 |
msgid ""
|
62 |
"This is a test file to check if the user has write permission to S3. Delete "
|
63 |
"me if found."
|
64 |
msgstr ""
|
65 |
|
66 |
-
#:
|
67 |
#, php-format
|
68 |
msgid ""
|
69 |
"There was an error attempting to check the permissions of the bucket %s: %s"
|
70 |
msgstr ""
|
71 |
|
72 |
-
#:
|
73 |
msgid "Error creating bucket"
|
74 |
msgstr ""
|
75 |
|
76 |
-
#:
|
77 |
msgid "Bucket name too short."
|
78 |
msgstr ""
|
79 |
|
80 |
-
#:
|
81 |
msgid "Bucket name too long."
|
82 |
msgstr ""
|
83 |
|
84 |
-
#:
|
85 |
msgid ""
|
86 |
"Invalid character. Bucket names can contain lowercase letters, numbers, "
|
87 |
"periods and hyphens."
|
88 |
msgstr ""
|
89 |
|
90 |
-
#:
|
91 |
msgid "Error saving bucket"
|
92 |
msgstr ""
|
93 |
|
94 |
-
#:
|
95 |
msgid "Error fetching buckets"
|
96 |
msgstr ""
|
97 |
|
98 |
-
#:
|
99 |
msgid "Error getting URL preview: "
|
100 |
msgstr ""
|
101 |
|
102 |
-
#:
|
103 |
msgid "The changes you made will be lost if you navigate away from this page"
|
104 |
msgstr ""
|
105 |
|
106 |
-
#:
|
107 |
msgid "Cheatin' eh?"
|
108 |
msgstr ""
|
109 |
|
110 |
-
#:
|
111 |
msgctxt "Show the media library tab"
|
112 |
msgid "Media Library"
|
113 |
msgstr ""
|
114 |
|
115 |
-
#:
|
116 |
msgctxt "Show the support tab"
|
117 |
msgid "Support"
|
118 |
msgstr ""
|
119 |
|
120 |
-
#:
|
121 |
#, php-format
|
122 |
msgid "The file %s has been given %s permissions on Amazon S3."
|
123 |
msgstr ""
|
124 |
|
125 |
-
#:
|
126 |
msgid "Quick Start Guide"
|
127 |
msgstr ""
|
128 |
|
129 |
-
#:
|
130 |
#, php-format
|
131 |
msgid ""
|
132 |
"Looks like we don't have write access to this bucket. It's likely that the "
|
@@ -135,7 +139,7 @@ msgid ""
|
|
135 |
"correctly."
|
136 |
msgstr ""
|
137 |
|
138 |
-
#:
|
139 |
#, php-format
|
140 |
msgid ""
|
141 |
"Looks like we don't have access to the buckets. It's likely that the user "
|
@@ -143,370 +147,392 @@ msgid ""
|
|
143 |
"Please see our %s for instructions on setting up permissions correctly."
|
144 |
msgstr ""
|
145 |
|
146 |
-
#:
|
147 |
#, php-format
|
148 |
msgid "There was an error attempting to download the file %s from S3: %s"
|
149 |
msgstr ""
|
150 |
|
151 |
-
#:
|
152 |
#, php-format
|
153 |
msgid ""
|
154 |
-
"<strong>Running
|
155 |
-
"
|
156 |
-
"the bucket region it is served from. This will allow us to serve your files "
|
157 |
-
"from the proper S3 region subdomain <span style=\"white-space:nowrap;\">(e."
|
158 |
-
"g. s3-us-west-2.amazonaws.com)</span>. This will be done quietly in the "
|
159 |
"background, processing a small batch of Media Library items every %d "
|
160 |
"minutes. There should be no noticeable impact on your server’s "
|
161 |
"performance."
|
162 |
msgstr ""
|
163 |
|
164 |
-
#:
|
165 |
msgid "Pause Update"
|
166 |
msgstr ""
|
167 |
|
168 |
-
#:
|
|
|
169 |
msgid ""
|
170 |
-
"<strong
|
171 |
-
"
|
172 |
msgstr ""
|
173 |
|
174 |
-
#:
|
175 |
msgid "Restart Update"
|
176 |
msgstr ""
|
177 |
|
178 |
-
#:
|
|
|
179 |
msgid ""
|
180 |
-
"<strong>Error Updating
|
181 |
-
"attempting to update the
|
182 |
-
"
|
183 |
msgstr ""
|
184 |
|
185 |
-
#:
|
186 |
msgid "Try Run It Again"
|
187 |
msgstr ""
|
188 |
|
189 |
-
#:
|
190 |
#, php-format
|
191 |
msgid "Every %d Minutes"
|
192 |
msgstr ""
|
193 |
|
194 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
msgid "deactivate"
|
196 |
msgstr ""
|
197 |
|
198 |
-
#:
|
199 |
#, php-format
|
200 |
msgid "You can %s the %s plugin to get rid of this notice."
|
201 |
msgstr ""
|
202 |
|
203 |
-
#:
|
204 |
#, php-format
|
205 |
msgid "%s has been disabled as it requires the %s plugin."
|
206 |
msgstr ""
|
207 |
|
208 |
-
#:
|
209 |
msgid "which is currently disabled."
|
210 |
msgstr ""
|
211 |
|
212 |
-
#:
|
213 |
msgid "It appears to be installed already."
|
214 |
msgstr ""
|
215 |
|
216 |
-
#:
|
217 |
msgctxt "Activate plugin"
|
218 |
msgid "Activate it now."
|
219 |
msgstr ""
|
220 |
|
221 |
-
#:
|
222 |
#, php-format
|
223 |
msgid "<a href=\"%s\">Install</a> and activate it."
|
224 |
msgstr ""
|
225 |
|
226 |
-
#:
|
227 |
#, php-format
|
228 |
msgid ""
|
229 |
"%s has been disabled as it requires version %s or later of the %s plugin."
|
230 |
msgstr ""
|
231 |
|
232 |
-
#:
|
233 |
#, php-format
|
234 |
msgid "You currently have version %s installed."
|
235 |
msgstr ""
|
236 |
|
237 |
-
#:
|
238 |
#, php-format
|
239 |
msgid "A valid license for %s is required to update."
|
240 |
msgstr ""
|
241 |
|
242 |
-
#:
|
243 |
msgid "Update to the latest version"
|
244 |
msgstr ""
|
245 |
|
246 |
-
#:
|
247 |
#, php-format
|
248 |
msgid ""
|
249 |
"%1$s has been disabled because it is not a supported addon of the %2$s "
|
250 |
"plugin."
|
251 |
msgstr ""
|
252 |
|
253 |
-
#:
|
254 |
#, php-format
|
255 |
msgid ""
|
256 |
"%1$s has been disabled because it will not work with the version of the %2$s "
|
257 |
"plugin installed. %1$s %3$s or later is required."
|
258 |
msgstr ""
|
259 |
|
260 |
-
#:
|
261 |
#, php-format
|
262 |
msgid "Update %s to the latest version"
|
263 |
msgstr ""
|
264 |
|
265 |
-
#:
|
266 |
#, php-format
|
267 |
msgid "The %s plugin has been deactivated."
|
268 |
msgstr ""
|
269 |
|
270 |
-
#:
|
271 |
msgid "Change bucket"
|
272 |
msgstr ""
|
273 |
|
274 |
-
#:
|
275 |
msgid "What bucket would you like to use?"
|
276 |
msgstr ""
|
277 |
|
278 |
-
#:
|
279 |
msgid "Existing bucket name"
|
280 |
msgstr ""
|
281 |
|
282 |
-
#:
|
283 |
-
#:
|
284 |
msgid "Saving..."
|
285 |
msgstr ""
|
286 |
|
287 |
-
#:
|
288 |
-
#:
|
289 |
msgid "Save Bucket"
|
290 |
msgstr ""
|
291 |
|
292 |
-
#:
|
293 |
msgid "Browse existing buckets"
|
294 |
msgstr ""
|
295 |
|
296 |
-
#:
|
297 |
-
#:
|
298 |
-
#:
|
299 |
msgid "Create new bucket"
|
300 |
msgstr ""
|
301 |
|
302 |
-
#:
|
303 |
-
#:
|
304 |
-
#:
|
305 |
msgid "Cancel"
|
306 |
msgstr ""
|
307 |
|
308 |
-
#:
|
309 |
msgid "Select bucket"
|
310 |
msgstr ""
|
311 |
|
312 |
-
#:
|
313 |
msgid "Loading..."
|
314 |
msgstr ""
|
315 |
|
316 |
-
#:
|
317 |
-
#:
|
318 |
msgid "Refresh"
|
319 |
msgstr ""
|
320 |
|
321 |
-
#:
|
322 |
msgid "Enter bucket name"
|
323 |
msgstr ""
|
324 |
|
325 |
-
#:
|
326 |
msgid "Bucket Name:"
|
327 |
msgstr ""
|
328 |
|
329 |
-
#:
|
330 |
msgid "Bucket Name"
|
331 |
msgstr ""
|
332 |
|
333 |
-
#:
|
334 |
msgid "Region:"
|
335 |
msgstr ""
|
336 |
|
337 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
338 |
msgid "Creating..."
|
339 |
msgstr ""
|
340 |
|
341 |
-
#:
|
342 |
msgid "Create New Bucket"
|
343 |
msgstr ""
|
344 |
|
345 |
-
#:
|
346 |
msgid "Bucket"
|
347 |
msgstr ""
|
348 |
|
349 |
-
#:
|
350 |
msgid "Change"
|
351 |
msgstr ""
|
352 |
|
353 |
-
#:
|
|
|
|
|
|
|
|
|
354 |
msgid "Diagnostic Info"
|
355 |
msgstr ""
|
356 |
|
357 |
-
#:
|
358 |
msgctxt "Download to your computer"
|
359 |
msgid "Download"
|
360 |
msgstr ""
|
361 |
|
362 |
-
#:
|
363 |
msgid "Domain:"
|
364 |
msgstr ""
|
365 |
|
366 |
-
#:
|
367 |
msgid "Bucket name as subdomain"
|
368 |
msgstr ""
|
369 |
|
370 |
-
#:
|
371 |
msgid "Bucket name in path"
|
372 |
msgstr ""
|
373 |
|
374 |
-
#:
|
375 |
msgid "Bucket name as domain"
|
376 |
msgstr ""
|
377 |
|
378 |
-
#:
|
379 |
msgid "CloudFront or custom domain"
|
380 |
msgstr ""
|
381 |
|
382 |
-
#:
|
383 |
msgid "Access Denied to Bucket"
|
384 |
msgstr ""
|
385 |
|
386 |
-
#:
|
387 |
msgid "Settings saved."
|
388 |
msgstr ""
|
389 |
|
390 |
-
#:
|
391 |
msgid "Enable/Disable the Plugin"
|
392 |
msgstr ""
|
393 |
|
394 |
-
#:
|
395 |
msgid "Copy Files to S3"
|
396 |
msgstr ""
|
397 |
|
398 |
-
#:
|
399 |
msgid ""
|
400 |
"When a file is uploaded to the Media Library, copy it to S3. Existing files "
|
401 |
"are <em>not</em> copied to S3."
|
402 |
msgstr ""
|
403 |
|
404 |
-
#:
|
405 |
msgid "Rewrite File URLs"
|
406 |
msgstr ""
|
407 |
|
408 |
-
#:
|
409 |
msgid ""
|
410 |
"For Media Library files that have been copied to S3, rewrite the URLs so "
|
411 |
"that they are served from S3/CloudFront instead of your server."
|
412 |
msgstr ""
|
413 |
|
414 |
-
#:
|
415 |
msgid "Configure File URLs"
|
416 |
msgstr ""
|
417 |
|
418 |
-
#:
|
419 |
msgid "Path"
|
420 |
msgstr ""
|
421 |
|
422 |
-
#:
|
423 |
msgid "By default the path is the same as your local WordPress files:"
|
424 |
msgstr ""
|
425 |
|
426 |
-
#:
|
427 |
msgid "Year/Month"
|
428 |
msgstr ""
|
429 |
|
430 |
-
#:
|
431 |
msgid "Add the Year/Month in the URL."
|
432 |
msgstr ""
|
433 |
|
434 |
-
#:
|
435 |
msgid "SSL:"
|
436 |
msgstr ""
|
437 |
|
438 |
-
#:
|
439 |
msgid "Same as request"
|
440 |
msgstr ""
|
441 |
|
442 |
-
#:
|
443 |
msgid "When the request is https://, use https:// for the file URL as well."
|
444 |
msgstr ""
|
445 |
|
446 |
-
#:
|
447 |
msgid "Always SSL"
|
448 |
msgstr ""
|
449 |
|
450 |
-
#:
|
451 |
msgid "Forces https:// to be used."
|
452 |
msgstr ""
|
453 |
|
454 |
-
#:
|
455 |
msgid ""
|
456 |
"You cannot use the \"Bucket as a subdomain\" domain option when using SSL."
|
457 |
msgstr ""
|
458 |
|
459 |
-
#:
|
460 |
msgid "Always non-SSL"
|
461 |
msgstr ""
|
462 |
|
463 |
-
#:
|
464 |
msgid "Forces http:// to be used."
|
465 |
msgstr ""
|
466 |
|
467 |
-
#:
|
468 |
msgid "Advanced Options"
|
469 |
msgstr ""
|
470 |
|
471 |
-
#:
|
472 |
msgid "Remove Files From Server"
|
473 |
msgstr ""
|
474 |
|
475 |
-
#:
|
476 |
msgid "Once a file has been copied to S3, remove it from the local server."
|
477 |
msgstr ""
|
478 |
|
479 |
-
#:
|
480 |
msgid "Object Versioning"
|
481 |
msgstr ""
|
482 |
|
483 |
-
#:
|
484 |
msgid ""
|
485 |
"Append a timestamp to the S3 file path. Recommended when using CloudFront so "
|
486 |
"you don't have to worry about cache invalidation."
|
487 |
msgstr ""
|
488 |
|
489 |
-
#:
|
490 |
-
#:
|
491 |
msgid "More info"
|
492 |
msgstr ""
|
493 |
|
494 |
-
#:
|
495 |
msgid "Far Future Expiration Header"
|
496 |
msgstr ""
|
497 |
|
498 |
-
#:
|
499 |
msgid ""
|
500 |
"Implements a \"Never Expire\" caching policy for browsers by setting an "
|
501 |
"Expires header for 10 years in the future. Should be used in conjunction "
|
502 |
"with object versioning above."
|
503 |
msgstr ""
|
504 |
|
505 |
-
#:
|
506 |
msgid "Copy HiDPI (@2x) Images"
|
507 |
msgstr ""
|
508 |
|
509 |
-
#:
|
510 |
#, php-format
|
511 |
msgid ""
|
512 |
"When uploading a file to S3, checks if there's a file of the same name with "
|
@@ -514,80 +540,80 @@ msgid ""
|
|
514 |
"Retina 2x</a> plugin."
|
515 |
msgstr ""
|
516 |
|
517 |
-
#:
|
518 |
msgid "Save Changes"
|
519 |
msgstr ""
|
520 |
|
521 |
-
#:
|
522 |
msgid "Upload existing Media Library to S3"
|
523 |
msgstr ""
|
524 |
|
525 |
-
#:
|
526 |
msgid "Find & replace file URLs in content"
|
527 |
msgstr ""
|
528 |
|
529 |
-
#:
|
530 |
msgid "Manage S3 files in WordPress"
|
531 |
msgstr ""
|
532 |
|
533 |
-
#:
|
534 |
msgid "Assets addon - Serve your CSS & JS from S3/CloudFront"
|
535 |
msgstr ""
|
536 |
|
537 |
-
#:
|
538 |
msgid "WooCommerce addon"
|
539 |
msgstr ""
|
540 |
|
541 |
-
#:
|
542 |
msgid "Easy Digital Downloads addon"
|
543 |
msgstr ""
|
544 |
|
545 |
-
#:
|
546 |
msgid "PriorityExpert™ email support"
|
547 |
msgstr ""
|
548 |
|
549 |
-
#:
|
550 |
msgid "Visit deliciousbrains.com →"
|
551 |
msgstr ""
|
552 |
|
553 |
-
#:
|
554 |
msgid "Get 20% Off!"
|
555 |
msgstr ""
|
556 |
|
557 |
-
#:
|
558 |
#, php-format
|
559 |
msgid ""
|
560 |
"Submit your name and email and we’ll send you a coupon for 20% off your "
|
561 |
"upgrade."
|
562 |
msgstr ""
|
563 |
|
564 |
-
#:
|
565 |
msgid "Your Email"
|
566 |
msgstr ""
|
567 |
|
568 |
-
#:
|
569 |
msgid "First Name"
|
570 |
msgstr ""
|
571 |
|
572 |
-
#:
|
573 |
msgid "Last Name"
|
574 |
msgstr ""
|
575 |
|
576 |
-
#:
|
577 |
msgid "Send me the coupon"
|
578 |
msgstr ""
|
579 |
|
580 |
-
#:
|
581 |
msgid ""
|
582 |
"We promise we will not use your email for anything else and you can "
|
583 |
"unsubscribe with 1-click anytime."
|
584 |
msgstr ""
|
585 |
|
586 |
-
#:
|
587 |
msgid "As this is a free plugin, we do not provide support."
|
588 |
msgstr ""
|
589 |
|
590 |
-
#:
|
591 |
#, php-format
|
592 |
msgid ""
|
593 |
"You may ask the WordPress community for help by posting to the <a href=\"%s"
|
@@ -595,14 +621,14 @@ msgid ""
|
|
595 |
"to a few weeks and will likely be from a non-developer."
|
596 |
msgstr ""
|
597 |
|
598 |
-
#:
|
599 |
#, php-format
|
600 |
msgid ""
|
601 |
"If you want a <strong>timely response via email from a developer</strong> "
|
602 |
"who works on this plugin, <a href=\"%s\">upgrade</a> and send us an email."
|
603 |
msgstr ""
|
604 |
|
605 |
-
#:
|
606 |
#, php-format
|
607 |
msgid ""
|
608 |
"If you've found a bug, please <a href=\"%s\">submit an issue on GitHub</a>."
|
8 |
msgstr ""
|
9 |
"Project-Id-Version: amazon-s3-and-cloudfront\n"
|
10 |
"Report-Msgid-Bugs-To: nom@deliciousbrains.com\n"
|
11 |
+
"POT-Creation-Date: 2015-08-27 20:11+0100\n"
|
12 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
17 |
"Content-Type: text/plain; charset=UTF-8\n"
|
18 |
"Content-Transfer-Encoding: 8bit\n"
|
19 |
|
20 |
+
#: classes/amazon-s3-and-cloudfront.php:84
|
21 |
msgid "Offload S3"
|
22 |
msgstr ""
|
23 |
|
24 |
+
#: classes/amazon-s3-and-cloudfront.php:85
|
25 |
msgid "S3 and CloudFront"
|
26 |
msgstr ""
|
27 |
|
28 |
+
#: classes/amazon-s3-and-cloudfront.php:522
|
29 |
#, php-format
|
30 |
msgid "File %s does not exist"
|
31 |
msgstr ""
|
32 |
|
33 |
+
#: classes/amazon-s3-and-cloudfront.php:531
|
34 |
#, php-format
|
35 |
msgid "Mime type %s is not allowed"
|
36 |
msgstr ""
|
37 |
|
38 |
+
#: classes/amazon-s3-and-cloudfront.php:608
|
39 |
#, php-format
|
40 |
msgid "Error uploading %s to S3: %s"
|
41 |
msgstr ""
|
42 |
|
43 |
+
#: classes/amazon-s3-and-cloudfront.php:1259
|
44 |
msgid "Cheatin’ eh?"
|
45 |
msgstr ""
|
46 |
|
47 |
+
#: classes/amazon-s3-and-cloudfront.php:1263
|
48 |
msgid "You do not have sufficient permissions to access this page."
|
49 |
msgstr ""
|
50 |
|
51 |
+
#: classes/amazon-s3-and-cloudfront.php:1269
|
52 |
msgid "No bucket name provided."
|
53 |
msgstr ""
|
54 |
|
55 |
+
#: classes/amazon-s3-and-cloudfront.php:1544
|
56 |
+
msgid "Error Getting Bucket Region"
|
57 |
+
msgstr ""
|
58 |
+
|
59 |
+
#: classes/amazon-s3-and-cloudfront.php:1545
|
60 |
#, php-format
|
61 |
msgid "There was an error attempting to get the region of the bucket %s: %s"
|
62 |
msgstr ""
|
63 |
|
64 |
+
#: classes/amazon-s3-and-cloudfront.php:1665
|
65 |
msgid ""
|
66 |
"This is a test file to check if the user has write permission to S3. Delete "
|
67 |
"me if found."
|
68 |
msgstr ""
|
69 |
|
70 |
+
#: classes/amazon-s3-and-cloudfront.php:1697
|
71 |
#, php-format
|
72 |
msgid ""
|
73 |
"There was an error attempting to check the permissions of the bucket %s: %s"
|
74 |
msgstr ""
|
75 |
|
76 |
+
#: classes/amazon-s3-and-cloudfront.php:1755
|
77 |
msgid "Error creating bucket"
|
78 |
msgstr ""
|
79 |
|
80 |
+
#: classes/amazon-s3-and-cloudfront.php:1756
|
81 |
msgid "Bucket name too short."
|
82 |
msgstr ""
|
83 |
|
84 |
+
#: classes/amazon-s3-and-cloudfront.php:1757
|
85 |
msgid "Bucket name too long."
|
86 |
msgstr ""
|
87 |
|
88 |
+
#: classes/amazon-s3-and-cloudfront.php:1758
|
89 |
msgid ""
|
90 |
"Invalid character. Bucket names can contain lowercase letters, numbers, "
|
91 |
"periods and hyphens."
|
92 |
msgstr ""
|
93 |
|
94 |
+
#: classes/amazon-s3-and-cloudfront.php:1759
|
95 |
msgid "Error saving bucket"
|
96 |
msgstr ""
|
97 |
|
98 |
+
#: classes/amazon-s3-and-cloudfront.php:1760
|
99 |
msgid "Error fetching buckets"
|
100 |
msgstr ""
|
101 |
|
102 |
+
#: classes/amazon-s3-and-cloudfront.php:1761
|
103 |
msgid "Error getting URL preview: "
|
104 |
msgstr ""
|
105 |
|
106 |
+
#: classes/amazon-s3-and-cloudfront.php:1762
|
107 |
msgid "The changes you made will be lost if you navigate away from this page"
|
108 |
msgstr ""
|
109 |
|
110 |
+
#: classes/amazon-s3-and-cloudfront.php:1820
|
111 |
msgid "Cheatin' eh?"
|
112 |
msgstr ""
|
113 |
|
114 |
+
#: classes/amazon-s3-and-cloudfront.php:1923
|
115 |
msgctxt "Show the media library tab"
|
116 |
msgid "Media Library"
|
117 |
msgstr ""
|
118 |
|
119 |
+
#: classes/amazon-s3-and-cloudfront.php:1924
|
120 |
msgctxt "Show the support tab"
|
121 |
msgid "Support"
|
122 |
msgstr ""
|
123 |
|
124 |
+
#: classes/amazon-s3-and-cloudfront.php:2060
|
125 |
#, php-format
|
126 |
msgid "The file %s has been given %s permissions on Amazon S3."
|
127 |
msgstr ""
|
128 |
|
129 |
+
#: classes/amazon-s3-and-cloudfront.php:2561
|
130 |
msgid "Quick Start Guide"
|
131 |
msgstr ""
|
132 |
|
133 |
+
#: classes/amazon-s3-and-cloudfront.php:2563
|
134 |
#, php-format
|
135 |
msgid ""
|
136 |
"Looks like we don't have write access to this bucket. It's likely that the "
|
139 |
"correctly."
|
140 |
msgstr ""
|
141 |
|
142 |
+
#: classes/amazon-s3-and-cloudfront.php:2565
|
143 |
#, php-format
|
144 |
msgid ""
|
145 |
"Looks like we don't have access to the buckets. It's likely that the user "
|
147 |
"Please see our %s for instructions on setting up permissions correctly."
|
148 |
msgstr ""
|
149 |
|
150 |
+
#: classes/as3cf-plugin-compatibility.php:357
|
151 |
#, php-format
|
152 |
msgid "There was an error attempting to download the file %s from S3: %s"
|
153 |
msgstr ""
|
154 |
|
155 |
+
#: classes/as3cf-upgrade.php:279
|
156 |
#, php-format
|
157 |
msgid ""
|
158 |
+
"<strong>Running %s Update</strong> — We’re going through all the "
|
159 |
+
"Media Library items uploaded to S3 %s This will be done quietly in the "
|
|
|
|
|
|
|
160 |
"background, processing a small batch of Media Library items every %d "
|
161 |
"minutes. There should be no noticeable impact on your server’s "
|
162 |
"performance."
|
163 |
msgstr ""
|
164 |
|
165 |
+
#: classes/as3cf-upgrade.php:280
|
166 |
msgid "Pause Update"
|
167 |
msgstr ""
|
168 |
|
169 |
+
#: classes/as3cf-upgrade.php:284
|
170 |
+
#, php-format
|
171 |
msgid ""
|
172 |
+
"<strong>%s Update Paused</strong> — Updating Media Library %s has been "
|
173 |
+
"paused."
|
174 |
msgstr ""
|
175 |
|
176 |
+
#: classes/as3cf-upgrade.php:285
|
177 |
msgid "Restart Update"
|
178 |
msgstr ""
|
179 |
|
180 |
+
#: classes/as3cf-upgrade.php:288
|
181 |
+
#, php-format
|
182 |
msgid ""
|
183 |
+
"<strong>Error Updating %s</strong> — We ran into some errors "
|
184 |
+
"attempting to update the %s for all your Media Library items that have been "
|
185 |
+
"uploaded to S3. Please check your error log for details."
|
186 |
msgstr ""
|
187 |
|
188 |
+
#: classes/as3cf-upgrade.php:289
|
189 |
msgid "Try Run It Again"
|
190 |
msgstr ""
|
191 |
|
192 |
+
#: classes/as3cf-upgrade.php:391
|
193 |
#, php-format
|
194 |
msgid "Every %d Minutes"
|
195 |
msgstr ""
|
196 |
|
197 |
+
#: classes/upgrades/as3cf-file-sizes.php:37
|
198 |
+
msgid ""
|
199 |
+
"and updating the metadata with the sizes of files that have been removed "
|
200 |
+
"from the server. This will allow us to serve the correct size for media "
|
201 |
+
"items and the total space used in Multisite subsites."
|
202 |
+
msgstr ""
|
203 |
+
|
204 |
+
#: classes/upgrades/as3cf-region-meta.php:36
|
205 |
+
msgid ""
|
206 |
+
"and updating the metadata with the bucket region it is served from. This "
|
207 |
+
"will allow us to serve your files from the proper S3 region subdomain <span "
|
208 |
+
"style=\"white-space:nowrap;\">(e.g. s3-us-west-2.amazonaws.com)</span>."
|
209 |
+
msgstr ""
|
210 |
+
|
211 |
+
#: classes/wp-aws-compatibility-check.php:310
|
212 |
msgid "deactivate"
|
213 |
msgstr ""
|
214 |
|
215 |
+
#: classes/wp-aws-compatibility-check.php:311
|
216 |
#, php-format
|
217 |
msgid "You can %s the %s plugin to get rid of this notice."
|
218 |
msgstr ""
|
219 |
|
220 |
+
#: classes/wp-aws-compatibility-check.php:314
|
221 |
#, php-format
|
222 |
msgid "%s has been disabled as it requires the %s plugin."
|
223 |
msgstr ""
|
224 |
|
225 |
+
#: classes/wp-aws-compatibility-check.php:318
|
226 |
msgid "which is currently disabled."
|
227 |
msgstr ""
|
228 |
|
229 |
+
#: classes/wp-aws-compatibility-check.php:320
|
230 |
msgid "It appears to be installed already."
|
231 |
msgstr ""
|
232 |
|
233 |
+
#: classes/wp-aws-compatibility-check.php:322
|
234 |
msgctxt "Activate plugin"
|
235 |
msgid "Activate it now."
|
236 |
msgstr ""
|
237 |
|
238 |
+
#: classes/wp-aws-compatibility-check.php:329
|
239 |
#, php-format
|
240 |
msgid "<a href=\"%s\">Install</a> and activate it."
|
241 |
msgstr ""
|
242 |
|
243 |
+
#: classes/wp-aws-compatibility-check.php:340
|
244 |
#, php-format
|
245 |
msgid ""
|
246 |
"%s has been disabled as it requires version %s or later of the %s plugin."
|
247 |
msgstr ""
|
248 |
|
249 |
+
#: classes/wp-aws-compatibility-check.php:343
|
250 |
#, php-format
|
251 |
msgid "You currently have version %s installed."
|
252 |
msgstr ""
|
253 |
|
254 |
+
#: classes/wp-aws-compatibility-check.php:350
|
255 |
#, php-format
|
256 |
msgid "A valid license for %s is required to update."
|
257 |
msgstr ""
|
258 |
|
259 |
+
#: classes/wp-aws-compatibility-check.php:358
|
260 |
msgid "Update to the latest version"
|
261 |
msgstr ""
|
262 |
|
263 |
+
#: classes/wp-aws-compatibility-check.php:370
|
264 |
#, php-format
|
265 |
msgid ""
|
266 |
"%1$s has been disabled because it is not a supported addon of the %2$s "
|
267 |
"plugin."
|
268 |
msgstr ""
|
269 |
|
270 |
+
#: classes/wp-aws-compatibility-check.php:379
|
271 |
#, php-format
|
272 |
msgid ""
|
273 |
"%1$s has been disabled because it will not work with the version of the %2$s "
|
274 |
"plugin installed. %1$s %3$s or later is required."
|
275 |
msgstr ""
|
276 |
|
277 |
+
#: classes/wp-aws-compatibility-check.php:382
|
278 |
#, php-format
|
279 |
msgid "Update %s to the latest version"
|
280 |
msgstr ""
|
281 |
|
282 |
+
#: classes/wp-aws-compatibility-check.php:442
|
283 |
#, php-format
|
284 |
msgid "The %s plugin has been deactivated."
|
285 |
msgstr ""
|
286 |
|
287 |
+
#: view/bucket-select.php:3
|
288 |
msgid "Change bucket"
|
289 |
msgstr ""
|
290 |
|
291 |
+
#: view/bucket-select.php:3
|
292 |
msgid "What bucket would you like to use?"
|
293 |
msgstr ""
|
294 |
|
295 |
+
#: view/bucket-select.php:5
|
296 |
msgid "Existing bucket name"
|
297 |
msgstr ""
|
298 |
|
299 |
+
#: view/bucket-select.php:7
|
300 |
+
#: view/bucket-select.php:12
|
301 |
msgid "Saving..."
|
302 |
msgstr ""
|
303 |
|
304 |
+
#: view/bucket-select.php:7
|
305 |
+
#: view/bucket-select.php:12
|
306 |
msgid "Save Bucket"
|
307 |
msgstr ""
|
308 |
|
309 |
+
#: view/bucket-select.php:8
|
310 |
msgid "Browse existing buckets"
|
311 |
msgstr ""
|
312 |
|
313 |
+
#: view/bucket-select.php:9
|
314 |
+
#: view/bucket-select.php:26
|
315 |
+
#: view/bucket-select.php:31
|
316 |
msgid "Create new bucket"
|
317 |
msgstr ""
|
318 |
|
319 |
+
#: view/bucket-select.php:13
|
320 |
+
#: view/bucket-select.php:21
|
321 |
+
#: view/bucket-select.php:67
|
322 |
msgid "Cancel"
|
323 |
msgstr ""
|
324 |
|
325 |
+
#: view/bucket-select.php:18
|
326 |
msgid "Select bucket"
|
327 |
msgstr ""
|
328 |
|
329 |
+
#: view/bucket-select.php:19
|
330 |
msgid "Loading..."
|
331 |
msgstr ""
|
332 |
|
333 |
+
#: view/bucket-select.php:22
|
334 |
+
#: view/bucket-select.php:27
|
335 |
msgid "Refresh"
|
336 |
msgstr ""
|
337 |
|
338 |
+
#: view/bucket-select.php:25
|
339 |
msgid "Enter bucket name"
|
340 |
msgstr ""
|
341 |
|
342 |
+
#: view/bucket-select.php:37
|
343 |
msgid "Bucket Name:"
|
344 |
msgstr ""
|
345 |
|
346 |
+
#: view/bucket-select.php:40
|
347 |
msgid "Bucket Name"
|
348 |
msgstr ""
|
349 |
|
350 |
+
#: view/bucket-select.php:46
|
351 |
msgid "Region:"
|
352 |
msgstr ""
|
353 |
|
354 |
+
#: view/bucket-select.php:60
|
355 |
+
#, php-format
|
356 |
+
msgid "%s (defined in wp-config.php)"
|
357 |
+
msgstr ""
|
358 |
+
|
359 |
+
#: view/bucket-select.php:66
|
360 |
msgid "Creating..."
|
361 |
msgstr ""
|
362 |
|
363 |
+
#: view/bucket-select.php:66
|
364 |
msgid "Create New Bucket"
|
365 |
msgstr ""
|
366 |
|
367 |
+
#: view/bucket-setting.php:7
|
368 |
msgid "Bucket"
|
369 |
msgstr ""
|
370 |
|
371 |
+
#: view/bucket-setting.php:11
|
372 |
msgid "Change"
|
373 |
msgstr ""
|
374 |
|
375 |
+
#: view/bucket-setting.php:13
|
376 |
+
msgid "(defined in wp-config.php)"
|
377 |
+
msgstr ""
|
378 |
+
|
379 |
+
#: view/debug-info.php:2
|
380 |
msgid "Diagnostic Info"
|
381 |
msgstr ""
|
382 |
|
383 |
+
#: view/debug-info.php:11
|
384 |
msgctxt "Download to your computer"
|
385 |
msgid "Download"
|
386 |
msgstr ""
|
387 |
|
388 |
+
#: view/domain-setting.php:5
|
389 |
msgid "Domain:"
|
390 |
msgstr ""
|
391 |
|
392 |
+
#: view/domain-setting.php:23
|
393 |
msgid "Bucket name as subdomain"
|
394 |
msgstr ""
|
395 |
|
396 |
+
#: view/domain-setting.php:28
|
397 |
msgid "Bucket name in path"
|
398 |
msgstr ""
|
399 |
|
400 |
+
#: view/domain-setting.php:33
|
401 |
msgid "Bucket name as domain"
|
402 |
msgstr ""
|
403 |
|
404 |
+
#: view/domain-setting.php:38
|
405 |
msgid "CloudFront or custom domain"
|
406 |
msgstr ""
|
407 |
|
408 |
+
#: view/error-access.php:4
|
409 |
msgid "Access Denied to Bucket"
|
410 |
msgstr ""
|
411 |
|
412 |
+
#: view/settings.php:10
|
413 |
msgid "Settings saved."
|
414 |
msgstr ""
|
415 |
|
416 |
+
#: view/settings.php:44
|
417 |
msgid "Enable/Disable the Plugin"
|
418 |
msgstr ""
|
419 |
|
420 |
+
#: view/settings.php:51
|
421 |
msgid "Copy Files to S3"
|
422 |
msgstr ""
|
423 |
|
424 |
+
#: view/settings.php:52
|
425 |
msgid ""
|
426 |
"When a file is uploaded to the Media Library, copy it to S3. Existing files "
|
427 |
"are <em>not</em> copied to S3."
|
428 |
msgstr ""
|
429 |
|
430 |
+
#: view/settings.php:60
|
431 |
msgid "Rewrite File URLs"
|
432 |
msgstr ""
|
433 |
|
434 |
+
#: view/settings.php:61
|
435 |
msgid ""
|
436 |
"For Media Library files that have been copied to S3, rewrite the URLs so "
|
437 |
"that they are served from S3/CloudFront instead of your server."
|
438 |
msgstr ""
|
439 |
|
440 |
+
#: view/settings.php:65
|
441 |
msgid "Configure File URLs"
|
442 |
msgstr ""
|
443 |
|
444 |
+
#: view/settings.php:83
|
445 |
msgid "Path"
|
446 |
msgstr ""
|
447 |
|
448 |
+
#: view/settings.php:85
|
449 |
msgid "By default the path is the same as your local WordPress files:"
|
450 |
msgstr ""
|
451 |
|
452 |
+
#: view/settings.php:98
|
453 |
msgid "Year/Month"
|
454 |
msgstr ""
|
455 |
|
456 |
+
#: view/settings.php:100
|
457 |
msgid "Add the Year/Month in the URL."
|
458 |
msgstr ""
|
459 |
|
460 |
+
#: view/settings.php:106
|
461 |
msgid "SSL:"
|
462 |
msgstr ""
|
463 |
|
464 |
+
#: view/settings.php:114
|
465 |
msgid "Same as request"
|
466 |
msgstr ""
|
467 |
|
468 |
+
#: view/settings.php:115
|
469 |
msgid "When the request is https://, use https:// for the file URL as well."
|
470 |
msgstr ""
|
471 |
|
472 |
+
#: view/settings.php:119
|
473 |
msgid "Always SSL"
|
474 |
msgstr ""
|
475 |
|
476 |
+
#: view/settings.php:120
|
477 |
msgid "Forces https:// to be used."
|
478 |
msgstr ""
|
479 |
|
480 |
+
#: view/settings.php:121
|
481 |
msgid ""
|
482 |
"You cannot use the \"Bucket as a subdomain\" domain option when using SSL."
|
483 |
msgstr ""
|
484 |
|
485 |
+
#: view/settings.php:125
|
486 |
msgid "Always non-SSL"
|
487 |
msgstr ""
|
488 |
|
489 |
+
#: view/settings.php:126
|
490 |
msgid "Forces http:// to be used."
|
491 |
msgstr ""
|
492 |
|
493 |
+
#: view/settings.php:132
|
494 |
msgid "Advanced Options"
|
495 |
msgstr ""
|
496 |
|
497 |
+
#: view/settings.php:139
|
498 |
msgid "Remove Files From Server"
|
499 |
msgstr ""
|
500 |
|
501 |
+
#: view/settings.php:140
|
502 |
msgid "Once a file has been copied to S3, remove it from the local server."
|
503 |
msgstr ""
|
504 |
|
505 |
+
#: view/settings.php:148
|
506 |
msgid "Object Versioning"
|
507 |
msgstr ""
|
508 |
|
509 |
+
#: view/settings.php:150
|
510 |
msgid ""
|
511 |
"Append a timestamp to the S3 file path. Recommended when using CloudFront so "
|
512 |
"you don't have to worry about cache invalidation."
|
513 |
msgstr ""
|
514 |
|
515 |
+
#: view/settings.php:152
|
516 |
+
#: view/settings.php:165
|
517 |
msgid "More info"
|
518 |
msgstr ""
|
519 |
|
520 |
+
#: view/settings.php:162
|
521 |
msgid "Far Future Expiration Header"
|
522 |
msgstr ""
|
523 |
|
524 |
+
#: view/settings.php:163
|
525 |
msgid ""
|
526 |
"Implements a \"Never Expire\" caching policy for browsers by setting an "
|
527 |
"Expires header for 10 years in the future. Should be used in conjunction "
|
528 |
"with object versioning above."
|
529 |
msgstr ""
|
530 |
|
531 |
+
#: view/settings.php:175
|
532 |
msgid "Copy HiDPI (@2x) Images"
|
533 |
msgstr ""
|
534 |
|
535 |
+
#: view/settings.php:176
|
536 |
#, php-format
|
537 |
msgid ""
|
538 |
"When uploading a file to S3, checks if there's a file of the same name with "
|
540 |
"Retina 2x</a> plugin."
|
541 |
msgstr ""
|
542 |
|
543 |
+
#: view/settings.php:182
|
544 |
msgid "Save Changes"
|
545 |
msgstr ""
|
546 |
|
547 |
+
#: view/sidebar.php:10
|
548 |
msgid "Upload existing Media Library to S3"
|
549 |
msgstr ""
|
550 |
|
551 |
+
#: view/sidebar.php:11
|
552 |
msgid "Find & replace file URLs in content"
|
553 |
msgstr ""
|
554 |
|
555 |
+
#: view/sidebar.php:12
|
556 |
msgid "Manage S3 files in WordPress"
|
557 |
msgstr ""
|
558 |
|
559 |
+
#: view/sidebar.php:13
|
560 |
msgid "Assets addon - Serve your CSS & JS from S3/CloudFront"
|
561 |
msgstr ""
|
562 |
|
563 |
+
#: view/sidebar.php:14
|
564 |
msgid "WooCommerce addon"
|
565 |
msgstr ""
|
566 |
|
567 |
+
#: view/sidebar.php:15
|
568 |
msgid "Easy Digital Downloads addon"
|
569 |
msgstr ""
|
570 |
|
571 |
+
#: view/sidebar.php:16
|
572 |
msgid "PriorityExpert™ email support"
|
573 |
msgstr ""
|
574 |
|
575 |
+
#: view/sidebar.php:19
|
576 |
msgid "Visit deliciousbrains.com →"
|
577 |
msgstr ""
|
578 |
|
579 |
+
#: view/sidebar.php:26
|
580 |
msgid "Get 20% Off!"
|
581 |
msgstr ""
|
582 |
|
583 |
+
#: view/sidebar.php:29
|
584 |
#, php-format
|
585 |
msgid ""
|
586 |
"Submit your name and email and we’ll send you a coupon for 20% off your "
|
587 |
"upgrade."
|
588 |
msgstr ""
|
589 |
|
590 |
+
#: view/sidebar.php:33
|
591 |
msgid "Your Email"
|
592 |
msgstr ""
|
593 |
|
594 |
+
#: view/sidebar.php:37
|
595 |
msgid "First Name"
|
596 |
msgstr ""
|
597 |
|
598 |
+
#: view/sidebar.php:41
|
599 |
msgid "Last Name"
|
600 |
msgstr ""
|
601 |
|
602 |
+
#: view/sidebar.php:48
|
603 |
msgid "Send me the coupon"
|
604 |
msgstr ""
|
605 |
|
606 |
+
#: view/sidebar.php:52
|
607 |
msgid ""
|
608 |
"We promise we will not use your email for anything else and you can "
|
609 |
"unsubscribe with 1-click anytime."
|
610 |
msgstr ""
|
611 |
|
612 |
+
#: view/wordpress-org-support.php:2
|
613 |
msgid "As this is a free plugin, we do not provide support."
|
614 |
msgstr ""
|
615 |
|
616 |
+
#: view/wordpress-org-support.php:4
|
617 |
#, php-format
|
618 |
msgid ""
|
619 |
"You may ask the WordPress community for help by posting to the <a href=\"%s"
|
621 |
"to a few weeks and will likely be from a non-developer."
|
622 |
msgstr ""
|
623 |
|
624 |
+
#: view/wordpress-org-support.php:6
|
625 |
#, php-format
|
626 |
msgid ""
|
627 |
"If you want a <strong>timely response via email from a developer</strong> "
|
628 |
"who works on this plugin, <a href=\"%s\">upgrade</a> and send us an email."
|
629 |
msgstr ""
|
630 |
|
631 |
+
#: view/wordpress-org-support.php:8
|
632 |
#, php-format
|
633 |
msgid ""
|
634 |
"If you've found a bug, please <a href=\"%s\">submit an issue on GitHub</a>."
|
languages/as3cf-pt-br.mo
CHANGED
Binary file
|
readme.txt
CHANGED
@@ -1,10 +1,9 @@
|
|
1 |
=== WP Offload S3 ===
|
2 |
-
Contributors: bradt
|
3 |
-
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
|
4 |
Tags: uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
|
5 |
Requires at least: 3.7
|
6 |
Tested up to: 4.3
|
7 |
-
Stable tag: 0.9.
|
8 |
License: GPLv3
|
9 |
|
10 |
Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
|
@@ -17,19 +16,21 @@ This plugin automatically copies images, videos, documents, and any other media
|
|
17 |
|
18 |
Uploading files *directly* to your S3 account is not currently supported by this plugin. They are uploaded to your server first, then copied to S3. There is an option to automatically remove the files from your server once they are copied to S3 however.
|
19 |
|
20 |
-
If you're adding this plugin to a site that's been around for a while, your existing media files will not be copied or served from S3. Only newly uploaded files will be copied and served from S3.
|
21 |
|
22 |
**PRO Upgrade with Email Support and More Features**
|
23 |
|
24 |
* Upload existing Media Library to S3
|
25 |
* Find & replace file URLs in content
|
26 |
* Control S3 files from the Media Library
|
27 |
-
* [Assets addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=
|
28 |
-
* [WooCommerce addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=
|
29 |
-
* [Easy Digital Downloads addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=
|
30 |
* PriorityExpert™ email support
|
31 |
|
32 |
-
|
|
|
|
|
33 |
|
34 |
https://www.youtube.com/watch?v=55xNGnbJ_CY
|
35 |
|
@@ -62,6 +63,17 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
|
|
62 |
|
63 |
== Changelog ==
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
= 0.9.3 - 2015-08-17 =
|
66 |
* New: Pro upgrade sidebar
|
67 |
* Bug fix: Create buckets in US standard region causing S3 URLs to 404 errors
|
1 |
=== WP Offload S3 ===
|
2 |
+
Contributors: bradt, deliciousbrains
|
|
|
3 |
Tags: uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
|
4 |
Requires at least: 3.7
|
5 |
Tested up to: 4.3
|
6 |
+
Stable tag: 0.9.4
|
7 |
License: GPLv3
|
8 |
|
9 |
Copies files to Amazon S3 as they are uploaded to the Media Library. Optionally configure Amazon CloudFront for faster delivery.
|
16 |
|
17 |
Uploading files *directly* to your S3 account is not currently supported by this plugin. They are uploaded to your server first, then copied to S3. There is an option to automatically remove the files from your server once they are copied to S3 however.
|
18 |
|
19 |
+
If you're adding this plugin to a site that's been around for a while, your existing media files will not be copied or served from S3. Only newly uploaded files will be copied and served from S3. The pro upgrade has an upload tool to handle existing media files.
|
20 |
|
21 |
**PRO Upgrade with Email Support and More Features**
|
22 |
|
23 |
* Upload existing Media Library to S3
|
24 |
* Find & replace file URLs in content
|
25 |
* Control S3 files from the Media Library
|
26 |
+
* [Assets addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin#assets-addon) - Serve your CSS & JS from S3/CloudFront
|
27 |
+
* [WooCommerce addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin#woocommerce-addon)
|
28 |
+
* [Easy Digital Downloads addon](https://deliciousbrains.com/wp-offload-s3/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin#edd-addon)
|
29 |
* PriorityExpert™ email support
|
30 |
|
31 |
+
[Compare pro vs free →](http://deliciousbrains.com/wp-offload-s3/upgrade/?utm_source=wordpress.org&utm_medium=web&utm_content=desc&utm_campaign=os3-free-plugin)
|
32 |
+
|
33 |
+
The video below runs through the pro upgrade features...
|
34 |
|
35 |
https://www.youtube.com/watch?v=55xNGnbJ_CY
|
36 |
|
63 |
|
64 |
== Changelog ==
|
65 |
|
66 |
+
= 0.9.4 - 2015-08-27 =
|
67 |
+
* New: Update all existing attachments with missing file sizes when the 'Remove Files From Server' option is enabled (automatically runs in the background)
|
68 |
+
* Improvement: Show when constants are used to set bucket and region options
|
69 |
+
* Improvement: Don't show compatibility notices on plugin update screen
|
70 |
+
* Improvement: On Multisite installs don't call `restore_current_blog()` on successive loop iterations
|
71 |
+
* Bug fix: 'Error getting URL preview' alert shown when enter key pressed on settings screen
|
72 |
+
* Bug fix: Unable to crop header images when the 'Remove Files From Server' option is enabled
|
73 |
+
* Bug fix: Incorrect storage space shown on Multisite installs when the 'Remove Files From Server' option is enabled
|
74 |
+
* Bug fix: Upload attempted to non existent bucket when defined by constant
|
75 |
+
* Bug fix: 'SignatureDoesNotMatch' error shown when using signed URLs with bucket names containing '.' characters
|
76 |
+
|
77 |
= 0.9.3 - 2015-08-17 =
|
78 |
* New: Pro upgrade sidebar
|
79 |
* Bug fix: Create buckets in US standard region causing S3 URLs to 404 errors
|
uninstall.php
CHANGED
@@ -16,9 +16,28 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
16 |
|
17 |
require dirname( __FILE__ ) . '/classes/wp-aws-uninstall.php';
|
18 |
|
19 |
-
$options
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
$as3cf_uninstall = new WP_AWS_Uninstall( $options, $postmeta, $crons, $transients );
|
16 |
|
17 |
require dirname( __FILE__ ) . '/classes/wp-aws-uninstall.php';
|
18 |
|
19 |
+
$options = array(
|
20 |
+
'tantan_wordpress_s3',
|
21 |
+
'update_meta_with_region_session',
|
22 |
+
'update_file_sizes_session',
|
23 |
+
);
|
24 |
+
|
25 |
+
$postmeta = array(
|
26 |
+
'amazonS3_info',
|
27 |
+
'wpos3_filesize_total',
|
28 |
+
);
|
29 |
+
|
30 |
+
$crons = array(
|
31 |
+
'as3cf_cron_update_meta_with_region',
|
32 |
+
'as3cf_cron_update_file_sizes',
|
33 |
+
);
|
34 |
+
|
35 |
+
$transients = array(
|
36 |
+
'site' => array(
|
37 |
+
'as3cf_notices',
|
38 |
+
'wpos3_attachment_counts',
|
39 |
+
),
|
40 |
+
'subsite' => array( 'wpos3_site_space_used' ),
|
41 |
+
);
|
42 |
|
43 |
$as3cf_uninstall = new WP_AWS_Uninstall( $options, $postmeta, $crons, $transients );
|
view/bucket-select.php
CHANGED
@@ -41,20 +41,26 @@
|
|
41 |
<p class="as3cf-invalid-bucket-name"></p>
|
42 |
</td>
|
43 |
</tr>
|
44 |
-
|
45 |
-
<
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
|
|
|
|
50 |
<select class="bucket-create-region" name="region_name">
|
51 |
-
<?php foreach ( $
|
52 |
<option value="<?php echo $value; ?>"> <?php echo $label; ?></option>
|
53 |
<?php endforeach; ?>
|
54 |
</select>
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
58 |
</table>
|
59 |
<p class="bucket-actions actions">
|
60 |
<button type="submit" class="button button-primary" data-working="<?php _e( 'Creating...', 'as3cf' ); ?>"><?php _e( 'Create New Bucket', 'as3cf' ); ?></button>
|
41 |
<p class="as3cf-invalid-bucket-name"></p>
|
42 |
</td>
|
43 |
</tr>
|
44 |
+
<tr>
|
45 |
+
<td>
|
46 |
+
<?php _e( 'Region:', 'as3cf' ); ?>
|
47 |
+
</td>
|
48 |
+
<td>
|
49 |
+
<?php
|
50 |
+
$aws_regions = $this->get_aws_regions();
|
51 |
+
if ( ! defined( 'AS3CF_REGION' ) ) { ?>
|
52 |
<select class="bucket-create-region" name="region_name">
|
53 |
+
<?php foreach ( $aws_regions as $value => $label ) : ?>
|
54 |
<option value="<?php echo $value; ?>"> <?php echo $label; ?></option>
|
55 |
<?php endforeach; ?>
|
56 |
</select>
|
57 |
+
<?php } else {
|
58 |
+
$region = AS3CF_REGION;
|
59 |
+
$region_name = isset( $aws_regions[ $region ] ) ? $aws_regions[ $region ] : $region;
|
60 |
+
printf( __( '%s (defined in wp-config.php)', 'as3cf' ), $region_name );
|
61 |
+
} ?>
|
62 |
+
</td>
|
63 |
+
</tr>
|
64 |
</table>
|
65 |
<p class="bucket-actions actions">
|
66 |
<button type="submit" class="button button-primary" data-working="<?php _e( 'Creating...', 'as3cf' ); ?>"><?php _e( 'Create New Bucket', 'as3cf' ); ?></button>
|
view/bucket-setting.php
CHANGED
@@ -7,9 +7,11 @@ $tr_class = ( isset( $tr_class ) ) ? $tr_class : '';
|
|
7 |
<td><h3><?php _e( 'Bucket', 'as3cf' ); ?></h3></td>
|
8 |
<td>
|
9 |
<span id="<?php echo $prefix; ?>-active-bucket" class="as3cf-active-bucket"><?php echo $selected_bucket; // xss ok ?></span>
|
10 |
-
<?php if ( ! defined( $constant ) )
|
11 |
<a href="#" class="as3cf-change-bucket" data-as3cf-modal=".as3cf-bucket-container"><?php _e( 'Change', 'as3cf' ); ?></a>
|
12 |
-
<?php
|
|
|
|
|
13 |
<input id="<?php echo $prefix; ?>-bucket" type="hidden" class="no-compare" name="bucket" value="<?php echo esc_attr( $selected_bucket ); ?>">
|
14 |
<?php
|
15 |
$region = $this->get_setting( 'region' );
|
7 |
<td><h3><?php _e( 'Bucket', 'as3cf' ); ?></h3></td>
|
8 |
<td>
|
9 |
<span id="<?php echo $prefix; ?>-active-bucket" class="as3cf-active-bucket"><?php echo $selected_bucket; // xss ok ?></span>
|
10 |
+
<?php if ( ! defined( $constant ) ) { ?>
|
11 |
<a href="#" class="as3cf-change-bucket" data-as3cf-modal=".as3cf-bucket-container"><?php _e( 'Change', 'as3cf' ); ?></a>
|
12 |
+
<?php } else {
|
13 |
+
_e( '(defined in wp-config.php)', 'as3cf' );
|
14 |
+
} ?>
|
15 |
<input id="<?php echo $prefix; ?>-bucket" type="hidden" class="no-compare" name="bucket" value="<?php echo esc_attr( $selected_bucket ); ?>">
|
16 |
<?php
|
17 |
$region = $this->get_setting( 'region' );
|
view/sidebar.php
CHANGED
@@ -56,12 +56,6 @@
|
|
56 |
<div class="block credits">
|
57 |
<h4>Created & maintained by</h4>
|
58 |
<ul>
|
59 |
-
<li>
|
60 |
-
<a href="http://profiles.wordpress.org/bradt/">
|
61 |
-
<img src="//www.gravatar.com/avatar/e538ca4cb34839d4e5e3ccf20c37c67b?size=64" alt="" width="32" height="32">
|
62 |
-
<span>Brad Touesnard</span>
|
63 |
-
</a>
|
64 |
-
</li>
|
65 |
<li>
|
66 |
<a href="https://deliciousbrains.com/?utm_source=insideplugin&utm_medium=web&utm_content=sidebar&utm_campaign=os3-free-plugin">
|
67 |
<img src="//www.gravatar.com/avatar/e62fc2e9c8d9fc6edd4fea5339036a91?size=64" alt="" width="32" height="32">
|
56 |
<div class="block credits">
|
57 |
<h4>Created & maintained by</h4>
|
58 |
<ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
<li>
|
60 |
<a href="https://deliciousbrains.com/?utm_source=insideplugin&utm_medium=web&utm_content=sidebar&utm_campaign=os3-free-plugin">
|
61 |
<img src="//www.gravatar.com/avatar/e62fc2e9c8d9fc6edd4fea5339036a91?size=64" alt="" width="32" height="32">
|
wordpress-s3.php
CHANGED
@@ -3,14 +3,14 @@
|
|
3 |
Plugin Name: WP Offload S3
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/amazon-s3-and-cloudfront/
|
5 |
Description: Automatically copies media uploads to Amazon S3 for storage and delivery. Optionally configure Amazon CloudFront for even faster delivery.
|
6 |
-
Author:
|
7 |
-
Version: 0.9.
|
8 |
-
Author URI: http://
|
9 |
Network: True
|
10 |
Text Domain: as3cf
|
11 |
Domain Path: /languages/
|
12 |
|
13 |
-
// Copyright (c) 2013
|
14 |
//
|
15 |
// Released under the GPL license
|
16 |
// http://www.opensource.org/licenses/gpl-license.php
|
@@ -26,7 +26,7 @@ Domain Path: /languages/
|
|
26 |
// Then completely rewritten.
|
27 |
*/
|
28 |
|
29 |
-
$GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '0.9.
|
30 |
|
31 |
$GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['supported_addon_versions'] = array(
|
32 |
'amazon-s3-and-cloudfront-pro' => '1.0b1',
|
@@ -55,6 +55,8 @@ function as3cf_init( $aws ) {
|
|
55 |
$abspath = dirname( __FILE__ );
|
56 |
require_once $abspath . '/include/functions.php';
|
57 |
require_once $abspath . '/classes/as3cf-upgrade.php';
|
|
|
|
|
58 |
require_once $abspath . '/classes/as3cf-plugin-compatibility.php';
|
59 |
require_once $abspath . '/classes/amazon-s3-and-cloudfront.php';
|
60 |
$as3cf = new Amazon_S3_And_CloudFront( __FILE__, $aws );
|
3 |
Plugin Name: WP Offload S3
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/amazon-s3-and-cloudfront/
|
5 |
Description: Automatically copies media uploads to Amazon S3 for storage and delivery. Optionally configure Amazon CloudFront for even faster delivery.
|
6 |
+
Author: Delicious Brains
|
7 |
+
Version: 0.9.4
|
8 |
+
Author URI: http://deliciousbrains.com/
|
9 |
Network: True
|
10 |
Text Domain: as3cf
|
11 |
Domain Path: /languages/
|
12 |
|
13 |
+
// Copyright (c) 2013 Delicious Brains. All rights reserved.
|
14 |
//
|
15 |
// Released under the GPL license
|
16 |
// http://www.opensource.org/licenses/gpl-license.php
|
26 |
// Then completely rewritten.
|
27 |
*/
|
28 |
|
29 |
+
$GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['version'] = '0.9.4';
|
30 |
|
31 |
$GLOBALS['aws_meta']['amazon-s3-and-cloudfront']['supported_addon_versions'] = array(
|
32 |
'amazon-s3-and-cloudfront-pro' => '1.0b1',
|
55 |
$abspath = dirname( __FILE__ );
|
56 |
require_once $abspath . '/include/functions.php';
|
57 |
require_once $abspath . '/classes/as3cf-upgrade.php';
|
58 |
+
require_once $abspath . '/classes/upgrades/as3cf-region-meta.php';
|
59 |
+
require_once $abspath . '/classes/upgrades/as3cf-file-sizes.php';
|
60 |
require_once $abspath . '/classes/as3cf-plugin-compatibility.php';
|
61 |
require_once $abspath . '/classes/amazon-s3-and-cloudfront.php';
|
62 |
$as3cf = new Amazon_S3_And_CloudFront( __FILE__, $aws );
|