WP Offload S3 Lite - Version 1.0

Version Description

= 0.6 = This version requires PHP 5.3.3+ and the Amazon Web Services plugin

= 0.6.1 = This version requires PHP 5.3.3+ and the Amazon Web Services plugin

= 0.6.2 = This version requires PHP 5.3.3+ and the Amazon Web Services plugin

Download this release

Release Info

Developer deliciousbrains
Plugin Icon 128x128 WP Offload S3 Lite
Version 1.0
Comparing to
See all releases

Code changes from version 0.9.11 to 1.0

README.md CHANGED
@@ -1,9 +1,9 @@
1
- # WP Offload S3 #
2
**Contributors:** bradt, deliciousbrains
3
**Tags:** uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
**Requires at least:** 3.7
5
**Tested up to:** 4.4
6
- **Stable tag:** 0.9.11
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.
@@ -54,10 +54,10 @@ You can see the minimum requirements [here](https://deliciousbrains.com/wp-offlo
54
## Screenshots ##
55
56
### 1. Choosing/creating a bucket ###
57
- ![Choosing/creating a bucket](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3/assets/screenshot-1.png)
58
59
### 2. Settings screen ###
60
- ![Settings screen](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3/assets/screenshot-2.png)
61
62
63
## Upgrade Notice ##
@@ -73,6 +73,25 @@ This version requires PHP 5.3.3+ and the Amazon Web Services plugin
73
74
## Changelog ##
75
76
### WP Offload S3 0.9.11 - 2015-12-19 ###
77
* Bug fix: Responsive images in post content not working when served from S3
78
* Bug fix: Responsive images using wrong image size when there are multiple images with the same width
1
+ # WP Offload S3 Lite #
2
**Contributors:** bradt, deliciousbrains
3
**Tags:** uploads, amazon, s3, amazon s3, mirror, admin, media, cdn, cloudfront
4
**Requires at least:** 3.7
5
**Tested up to:** 4.4
6
+ **Stable tag:** 1.0
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.
54
## Screenshots ##
55
56
### 1. Choosing/creating a bucket ###
57
+ ![Choosing/creating a bucket](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3-lite/assets/screenshot-1.png)
58
59
### 2. Settings screen ###
60
+ ![Settings screen](https://raw.githubusercontent.com/deliciousbrains/wp-wp-offload-s3-lite/assets/screenshot-2.png)
61
62
63
## Upgrade Notice ##
73
74
## Changelog ##
75
76
+ ### WP Offload S3 Lite 1.0 - 2016-03-07 ###
77
+ * New: Plugin renamed to "WP Offload S3 Lite"
78
+ * New: Define any and all settings with a constant in wp-config.php
79
+ * New: Documentation links for each setting
80
+ * Improvement: Simplified domain setting UI
81
+ * Improvement: Far future expiration header set by default
82
+ * Improvement: Newly created bucket now immediately appears in the bucket list
83
+ * Improvement: Cleanup user meta on uninstall
84
+ * Improvement: WP Retina 2x integration [removed](https://deliciousbrains.com/wp-offload-s3/doc/copy-hidpi-2x-images-support/)
85
+ * Bug fix: Year/Month folder structure on S3 not created if the 'Organise my uploads into month and year-based folders' WordPress setting is disabled
86
+ * Bug fix: Responsive srcset PHP notices
87
+ * Bug fix: Compatibility addon notices displayed to non-admin users
88
+ * Bug fix: Potential PHP fatal error in MySQL version check in diagnostic log
89
+ * Bug fix: Missing image library notices displaying before plugin is setup
90
+
91
+ ### WP Offload S3 0.9.12 - 2016-02-03 ###
92
+ * Improvement: Compatibility with WP Offload S3 Assets 1.1
93
+ * Bug fix: Object versioned responsive images in post content not working when served from S3 on WordPress 4.4+
94
+
95
### WP Offload S3 0.9.11 - 2015-12-19 ###
96
* Bug fix: Responsive images in post content not working when served from S3
97
* Bug fix: Responsive images using wrong image size when there are multiple images with the same width
assets/css/styles.css CHANGED
@@ -1 +1 @@
1
- .aws-main.wrap>h1{float:left}.aws-main.wrap .as3cf-notice,.aws-main.wrap .as3cf-updated,.aws-main.wrap .as3cf-error{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-error.fatal{clear:both;float:left}.aws-main.wrap h2.nav-tab-wrapper{float:none;margin-bottom:15px;width:650px;margin-top:10px;padding:9px 0 0 5px}.aws-main.wrap h2.nav-tab-wrapper a.nav-tab-active{color:#464646;cursor:default}.aws-main.wrap h2.nav-tab-wrapper a:focus{-webkit-box-shadow:none;box-shadow:none}.aws-main.wrap .error pre{background:#eaeaea;background:rgba(0,0,0,0.07);display:block;padding:10px 15px}.aws-main.wrap .error pre code{padding:0;background:none}.aws-main.wrap[data-tab="support"] .as3cf-notice,.aws-main.wrap[data-tab="support"] .error,.aws-main.wrap[data-tab="support"] .updated,.aws-main.wrap[data-tab="support"] .updated.show{display:none}.aws-main.wrap[data-tab="support"] .fatal .error,.aws-main.wrap[data-tab="support"] .as3cf-notice.important,.aws-main.wrap[data-tab="support"] .dbrains-api-down{display:block}.aws-main.wrap .as3cf-notice,.aws-main.wrap .error,.aws-main.wrap .updated{max-width:650px;margin-top:15px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-updated{display:none}.aws-main.wrap .as3cf-updated.as3cf-notice,.aws-main.wrap .as3cf-updated.show{display:block}.as3cf-tab .as3cf-main-settings{display:none}.as3cf-tab .as3cf-bucket-container{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-main-settings{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-tab{display:none;position:relative;width:650px}.as3cf-tab .as3cf-main-settings p{font-size:13px}.as3cf-tab .as3cf-main-settings p a{color:#444}.as3cf-tab .object-prefix-desc em{white-space:nowrap}.as3cf-tab .as3cf-url-preview-wrap{background:#fff;text-align:center;padding:20px 0 0;max-width:650px;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.as3cf-tab .as3cf-url-preview-wrap .as3cf-url-preview{margin-top:10px;padding:0 20px 10px;overflow-x:scroll}.as3cf-tab .as3cf-url-preview-wrap span{color:#aaa;text-transform:uppercase;font-weight:bold}.as3cf-tab .as3cf-ssl p.info{margin-top:10px;padding:0}.as3cf-tab .as3cf-radio-group label{display:block;margin-bottom:10px}.as3cf-tab .as3cf-radio-group label.disabled,.as3cf-tab .as3cf-radio-group label.disabled p{color:#bbbbbb;cursor:default}.as3cf-tab .as3cf-radio-group p{padding-left:25px;color:#6b6b6b;margin:0;font-size:12px}.as3cf-tab .as3cf-radio-group p.as3cf-setting{margin-top:5px}.as3cf-tab .as3cf-switch{position:relative;display:inline-block;padding:2px;overflow:hidden;border-radius:2px;-webkit-border-radius:2px;background-color:#d4d3d3;cursor:pointer}.as3cf-tab .as3cf-switch.on{background-color:#ade7b5}.as3cf-tab .as3cf-switch span{visibility:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;display:inline-block;height:100%;font-size:12px;line-height:20px;border-radius:2px;-webkit-border-radius:2px;font-weight:bold;padding:4px 8px;background:#fff;color:#8d8d8d;z-index:1}.as3cf-tab .as3cf-switch span.on{color:#82d78b}.as3cf-tab .as3cf-switch span.checked{visibility:visible}.as3cf-tab .as3cf-switch.disabled{cursor:default;background:#e6e6e6}.as3cf-tab .as3cf-switch.disabled span{background:#f1f1f1;color:#d6d6d6}.as3cf-tab .as3cf-switch input[type="checkbox"]{position:absolute !important;top:0;left:0;opacity:0;filter:alpha(opacity=0);z-index:-1}.as3cf-tab .as3cf-setting.hide{display:none}.as3cf-tab h3{font-weight:normal;text-transform:uppercase;margin:15px 0}.as3cf-tab .form-table{margin:0}.as3cf-tab .form-table tr.as3cf-border-bottom td{border-bottom:1px solid #ddd;padding:20px 0px}.as3cf-tab .form-table tr.as3cf-setting-title td{padding-bottom:0}.as3cf-tab .form-table tr.as3cf-setting-title:first-child td{padding-top:20px}.as3cf-tab .form-table tr td{padding:15px 0}.as3cf-tab .form-table tr td:first-child{vertical-align:top;min-width:120px}.as3cf-tab .form-table tr td .as3cf-notice:last-child{margin-bottom:0}.as3cf-tab .form-table tr:first-of-type td{padding-top:5px}.as3cf-tab .form-table h3{padding:0;margin:0}.as3cf-tab .form-table h4{margin:0}.as3cf-tab .as3cf-active-bucket{font-weight:bold;margin-right:10px}.as3cf-tab .as3cf-view-bucket{color:#444;text-decoration:none;margin-right:10px}.as3cf-tab .as3cf-view-bucket:hover,.as3cf-tab .as3cf-view-bucket:active{color:#00a0d2}.as3cf-tab .as3cf-view-bucket .dashicons-external{margin-top:-2px}.as3cf-tab .tooltip{position:relative;z-index:2;cursor:pointer}.as3cf-tab .tooltip:before,.as3cf-tab .tooltip:after{visibility:hidden;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;pointer-events:none}.as3cf-tab .tooltip:before{position:absolute;bottom:150%;left:50%;margin-bottom:5px;margin-left:-250px;padding:10px;width:500px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background-color:#000;background-color:rgba(51,51,51,0.9);color:#fff;content:attr(data-tooltip);text-align:center;font-size:14px;line-height:1.3}.as3cf-tab .tooltip:after{position:absolute;bottom:150%;left:50%;margin-left:-5px;width:0;border-top:5px solid #000;border-top:5px solid rgba(51,51,51,0.9);border-right:5px solid transparent;border-left:5px solid transparent;content:" ";font-size:0;line-height:0}.as3cf-tab .tooltip:hover:before,.as3cf-tab .tooltip:hover:after{visibility:visible;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1}#tab-media{display:block}#tab-media .as3cf-main-settings{display:none}#tab-media .as3cf-bucket-container{display:block}#tab-media.as3cf-has-bucket .as3cf-main-settings{display:block}#tab-media.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-bucket-container h3{line-height:1.3;text-transform:none}.as3cf-bucket-container a:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.as3cf-bucket-container input[type=text]{box-sizing:border-box;width:100%}.as3cf-bucket-container select{box-sizing:border-box;width:50%}.as3cf-bucket-container .form-table td{padding:5px 0}.as3cf-bucket-container .form-table td:first-child{width:100px;line-height:30px;vertical-align:top}.as3cf-bucket-container .bucket-actions{margin:15px 0;border-top:1px solid #ccc;padding-top:15px;overflow:hidden}.as3cf-bucket-container .bucket-actions button,.as3cf-bucket-container .bucket-actions .right{float:right;margin-right:0}.as3cf-bucket-container .bucket-actions span{display:inline-block;margin-right:20px;line-height:28px}.as3cf-bucket-container .bucket-actions .bucket-action-cancel{color:#a00;text-decoration:none}.as3cf-bucket-container .bucket-actions .bucket-action-cancel:hover{color:red}.as3cf-bucket-container .as3cf-bucket-list{padding:15px;max-height:200px;overflow-x:hidden;overflow-y:auto;background-color:#fff;font-size:14px}.as3cf-bucket-container .as3cf-bucket-list li:last-of-type{margin-bottom:0}.as3cf-bucket-container .as3cf-bucket-list a{color:#444;text-decoration:none}.as3cf-bucket-container .as3cf-bucket-list a:hover{color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a.selected{font-weight:bold;color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a .dashicons{margin-right:5px}.as3cf-bucket-container .as3cf-bucket-select,.as3cf-bucket-container .as3cf-bucket-create{display:none}.as3cf-bucket-container .bucket-actions.select{display:none}.as3cf-tab{display:none}#tab-media{display:block}#tab-support{min-height:900px}#tab-support .as3cf-sidebar{top:11px}#tab-support .support-section{border-bottom:1px solid #ccc;padding-bottom:20px;margin-bottom:20px}#tab-support .debug textarea{width:100%;min-height:200px;font-family:Consolas, Monaco, monospace;margin-bottom:5px}.as3cf-sidebar{position:absolute;top:25px;left:670px;width:292px}.as3cf-sidebar .block{padding:20px;border:1px solid #ccc}.as3cf-sidebar .subscribe{border-top:none}.as3cf-sidebar .subscribe h2{padding:0;margin:0;margin-bottom:0.5em;color:#666;font-size:20px;line-height:1.2em;float:none}.as3cf-sidebar .subscribe h3{font-size:16px;margin:0}.as3cf-sidebar .subscribe p{margin:0}.as3cf-sidebar .subscribe .intro{margin-bottom:1em;line-height:1.4}.as3cf-sidebar .subscribe li{line-height:1.4}.as3cf-sidebar .subscribe .links{margin-bottom:2em}.as3cf-sidebar .subscribe .links a{text-decoration:none}.as3cf-sidebar .subscribe .promise{color:#999;font-size:12px;line-height:1.4em}.as3cf-sidebar .subscribe .field{margin-bottom:0.5em}.as3cf-sidebar .subscribe .field p{margin-bottom:0.3em}.as3cf-sidebar .subscribe .field input[type=text],.as3cf-sidebar .subscribe .field input[type=email]{width:100%}.as3cf-sidebar .subscribe .field.submit-button{margin-bottom:1em}.as3cf-sidebar .credits{border-top:0}.as3cf-sidebar .credits h4{font-size:16px;margin-top:0;margin-bottom:10px}.as3cf-sidebar .credits ul{margin:0}.as3cf-sidebar .credits li{overflow:hidden}.as3cf-sidebar .credits li:last-child{margin-bottom:0}.as3cf-sidebar .credits img{float:left;margin-right:10px}.as3cf-sidebar .credits span{float:left;display:block;line-height:32px}.as3cf-sidebar .credits a{display:block;text-decoration:none;color:#444;font-size:16px;text-align:center}.as3cf-sidebar .credits a:hover{color:#888}@media (min--moz-device-pixel-ratio: 1.3), (-o-min-device-pixel-ratio: 2.6 / 2), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx){.as3cf-sidebar .as3cf-banner{background-image:url(../img/snail-banner@2x.jpg);background-size:292px 156px}}@media screen and (max-width: 1052px){.as3cf-sidebar{position:relative;top:auto;right:auto;margin-top:50px}}.as3cf-banner{margin-top:28px;width:292px;height:156px;display:block;background-image:url(../img/snail-banner.jpg);position:relative}.as3cf-banner h1{font-size:28px;color:#fff;font-weight:200;margin:0;position:absolute;bottom:25px;left:20px;text-decoration:none}.as3cf-upgrade-details{background-color:#73833b;padding:20px;color:#fff;font-size:13px;margin:0;display:block;text-decoration:none}.as3cf-upgrade-details p{margin:0}.as3cf-upgrade-details a{color:#fff;font-weight:bold;text-decoration:none;font-size:16px}.as3cf-upgrade-details a:hover{color:#fff;opacity:0.9}.as3cf-upgrade-details ul{margin-top:0;margin-left:16px;list-style-type:disc}.aws-compatibility-notice.error{clear:both;margin:5px 20px 5px 0}.as3cf-bucket-error span.title{font-weight:bold}.as3cf-invalid-bucket-name,.as3cf-validation-error{display:block;margin-top:2px;font-size:12px;color:#a00}
1
+ .aws-main.wrap>h1{float:left}.aws-main.wrap .as3cf-notice,.aws-main.wrap .as3cf-updated,.aws-main.wrap .as3cf-error{-webkit-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-error.fatal{clear:both;float:left}.aws-main.wrap h2.nav-tab-wrapper{float:none;margin-bottom:15px;width:650px;margin-top:10px;padding:9px 0 0 5px}.aws-main.wrap h2.nav-tab-wrapper a.nav-tab-active{color:#464646;cursor:default}.aws-main.wrap h2.nav-tab-wrapper a:focus{-webkit-box-shadow:none;box-shadow:none}.aws-main.wrap .more-info{white-space:nowrap}.aws-main.wrap .error pre{background:#eaeaea;background:rgba(0,0,0,0.07);display:block;padding:10px 15px}.aws-main.wrap .error pre code{padding:0;background:none}.aws-main.wrap[data-tab="support"] .as3cf-notice,.aws-main.wrap[data-tab="support"] .error,.aws-main.wrap[data-tab="support"] .updated,.aws-main.wrap[data-tab="support"] .updated.show{display:none}.aws-main.wrap[data-tab="support"] .fatal .error,.aws-main.wrap[data-tab="support"] .as3cf-notice.important,.aws-main.wrap[data-tab="support"] .dbrains-api-down{display:block}.aws-main.wrap .as3cf-notice,.aws-main.wrap .error,.aws-main.wrap .updated{max-width:650px;margin-top:15px;-webkit-box-sizing:border-box;box-sizing:border-box}.aws-main.wrap .as3cf-updated{display:none}.aws-main.wrap .as3cf-updated.as3cf-notice,.aws-main.wrap .as3cf-updated.show{display:block}.as3cf-tab .as3cf-main-settings{display:none}.as3cf-tab .as3cf-bucket-container{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-main-settings{display:block}.as3cf-tab.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-tab{display:none;position:relative;width:650px}.as3cf-tab .as3cf-main-settings p{font-size:13px}.as3cf-tab .as3cf-main-settings p a{color:#444}.as3cf-tab .object-prefix-desc em{white-space:nowrap}.as3cf-tab .as3cf-url-preview-wrap{background:#fff;text-align:center;padding:20px 0 0;max-width:650px;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.as3cf-tab .as3cf-url-preview-wrap .as3cf-url-preview{margin-top:10px;padding:0 20px 10px;overflow-x:scroll}.as3cf-tab .as3cf-url-preview-wrap span{color:#aaa;text-transform:uppercase;font-weight:bold}.as3cf-tab .as3cf-ssl{margin-top:10px}.as3cf-tab .as3cf-ssl p.info{margin-top:10px;padding:0}.as3cf-tab .as3cf-radio-group label{display:block;margin-bottom:10px}.as3cf-tab .as3cf-radio-group label.disabled,.as3cf-tab .as3cf-radio-group label.disabled p{color:#bbbbbb;cursor:default}.as3cf-tab .as3cf-radio-group p{padding-left:25px;color:#6b6b6b;margin:0;font-size:12px}.as3cf-tab .as3cf-radio-group p.as3cf-setting{margin-top:5px}.as3cf-tab .as3cf-switch{position:relative;display:inline-block;padding:2px;overflow:hidden;border-radius:2px;-webkit-border-radius:2px;background-color:#d4d3d3;cursor:pointer}.as3cf-tab .as3cf-switch.on{background-color:#ade7b5}.as3cf-tab .as3cf-switch span{visibility:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;float:left;display:inline-block;height:100%;font-size:12px;line-height:20px;border-radius:2px;-webkit-border-radius:2px;font-weight:bold;padding:4px 8px;background:#fff;color:#8d8d8d;z-index:1}.as3cf-tab .as3cf-switch span.on{color:#82d78b}.as3cf-tab .as3cf-switch span.checked{visibility:visible}.as3cf-tab .as3cf-switch.disabled{cursor:default;background:#e6e6e6}.as3cf-tab .as3cf-switch.disabled span{background:#f1f1f1;color:#d6d6d6}.as3cf-tab .as3cf-switch input[type="checkbox"]{position:absolute !important;top:0;left:0;opacity:0;filter:alpha(opacity=0);z-index:-1}.as3cf-tab .as3cf-setting.hide{display:none}.as3cf-tab h3{font-weight:normal;text-transform:uppercase;margin:15px 0}.as3cf-tab .form-table{margin:0}.as3cf-tab .form-table tr.as3cf-border-bottom td{border-bottom:1px solid #ddd;padding:20px 0px}.as3cf-tab .form-table tr.as3cf-setting-title td{padding-bottom:0}.as3cf-tab .form-table tr.as3cf-setting-title:first-child td{padding-top:20px}.as3cf-tab .form-table tr td{padding:15px 0}.as3cf-tab .form-table tr td:first-child{vertical-align:top;min-width:120px}.as3cf-tab .form-table tr td .as3cf-notice:last-child{margin-bottom:0}.as3cf-tab .form-table tr td>p:first-child{margin-top:0}.as3cf-tab .form-table tr:first-of-type td{padding-top:5px}.as3cf-tab .form-table tr.as3cf-bucket-setting .as3cf-defined-in-config{float:none}.as3cf-tab .form-table h3{padding:0;margin:0}.as3cf-tab .form-table h4{margin:0}.as3cf-tab .as3cf-active-bucket{font-weight:bold;margin-right:10px}.as3cf-tab .as3cf-view-bucket{color:#444;text-decoration:none;margin-right:10px}.as3cf-tab .as3cf-view-bucket:hover,.as3cf-tab .as3cf-view-bucket:active{color:#00a0d2}.as3cf-tab .as3cf-view-bucket:focus{-webkit-box-shadow:none;box-shadow:none}.as3cf-tab .as3cf-view-bucket .dashicons-external{margin-top:-2px}.as3cf-tab .tooltip{position:relative;z-index:2;cursor:pointer}.as3cf-tab .tooltip:before,.as3cf-tab .tooltip:after{visibility:hidden;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;pointer-events:none}.as3cf-tab .tooltip:before{position:absolute;bottom:150%;left:50%;margin-bottom:5px;margin-left:-250px;padding:10px;width:500px;-webkit-border-radius:3px;border-radius:3px;background-color:#000;background-color:rgba(51,51,51,0.9);color:#fff;content:attr(data-tooltip);text-align:center;font-size:14px;line-height:1.3}.as3cf-tab .tooltip:after{position:absolute;bottom:150%;left:50%;margin-left:-5px;width:0;border-top:5px solid #000;border-top:5px solid rgba(51,51,51,0.9);border-right:5px solid transparent;border-left:5px solid transparent;content:" ";font-size:0;line-height:0}.as3cf-tab .tooltip:hover:before,.as3cf-tab .tooltip:hover:after{visibility:visible;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);opacity:1}.as3cf-tab .as3cf-defined-in-config{background:#ccc;color:#fff;padding:2px 5px;margin:0 0 5px 5px;float:right}.as3cf-tab .as3cf-defined-setting{color:#bbb}.as3cf-tab .as3cf-defined-setting label{cursor:default}.as3cf-tab .as3cf-defined-setting p .more-info a{color:#bbb}.as3cf-tab .as3cf-defined-setting .as3cf-radio-group p{color:#bbb}.as3cf-tab .as3cf-defined-setting .as3cf-notice{display:none !important}#tab-media{display:block}#tab-media .as3cf-main-settings{display:none}#tab-media .as3cf-bucket-container{display:block}#tab-media.as3cf-has-bucket .as3cf-main-settings{display:block}#tab-media.as3cf-has-bucket .as3cf-bucket-container{display:none}.as3cf-bucket-container h3{line-height:1.3;text-transform:none}.as3cf-bucket-container a:focus{-webkit-box-shadow:none;box-shadow:none;outline:none}.as3cf-bucket-container input[type=text]{-webkit-box-sizing:border-box;box-sizing:border-box;width:100%}.as3cf-bucket-container select{-webkit-box-sizing:border-box;box-sizing:border-box;width:50%}.as3cf-bucket-container .form-table td{padding:5px 0}.as3cf-bucket-container .form-table td:first-child{width:100px;line-height:30px;vertical-align:top}.as3cf-bucket-container .bucket-actions{margin:15px 0;border-top:1px solid #ccc;padding-top:15px;overflow:hidden}.as3cf-bucket-container .bucket-actions button,.as3cf-bucket-container .bucket-actions .right{float:right;margin-right:0}.as3cf-bucket-container .bucket-actions span{display:inline-block;margin-right:20px;line-height:28px}.as3cf-bucket-container .bucket-actions .bucket-action-cancel{color:#a00;text-decoration:none}.as3cf-bucket-container .bucket-actions .bucket-action-cancel:hover{color:red}.as3cf-bucket-container .as3cf-bucket-list{padding:15px;max-height:200px;overflow-x:hidden;overflow-y:auto;background-color:#fff;font-size:14px}.as3cf-bucket-container .as3cf-bucket-list li:last-of-type{margin-bottom:0}.as3cf-bucket-container .as3cf-bucket-list a{color:#444;text-decoration:none}.as3cf-bucket-container .as3cf-bucket-list a:hover{color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a.selected{font-weight:bold;color:#0074A2}.as3cf-bucket-container .as3cf-bucket-list a .dashicons{margin-right:5px}.as3cf-bucket-container .as3cf-bucket-select,.as3cf-bucket-container .as3cf-bucket-create{display:none}.as3cf-bucket-container .bucket-actions.select{display:none}.as3cf-tab{display:none}#tab-media{display:block}#tab-support{min-height:900px}#tab-support .as3cf-sidebar{top:11px}#tab-support .support-section{border-bottom:1px solid #ccc;padding-bottom:20px;margin-bottom:20px}#tab-support .debug textarea{width:100%;min-height:200px;font-family:Consolas, Monaco, monospace;margin-bottom:5px}.as3cf-sidebar{position:absolute;top:25px;left:670px;width:292px}.as3cf-sidebar .block{padding:20px;border:1px solid #ccc}.as3cf-sidebar .subscribe{border-top:none}.as3cf-sidebar .subscribe h2{padding:0;margin:0;margin-bottom:0.5em;color:#666;font-size:20px;line-height:1.2em;float:none}.as3cf-sidebar .subscribe h3{font-size:16px;margin:0}.as3cf-sidebar .subscribe p{margin:0}.as3cf-sidebar .subscribe .intro{margin-bottom:1em;line-height:1.4}.as3cf-sidebar .subscribe li{line-height:1.4}.as3cf-sidebar .subscribe .links{margin-bottom:2em}.as3cf-sidebar .subscribe .links a{text-decoration:none}.as3cf-sidebar .subscribe .promise{color:#999;font-size:12px;line-height:1.4em}.as3cf-sidebar .subscribe .field{margin-bottom:0.5em}.as3cf-sidebar .subscribe .field p{margin-bottom:0.3em}.as3cf-sidebar .subscribe .field input[type=text],.as3cf-sidebar .subscribe .field input[type=email]{width:100%}.as3cf-sidebar .subscribe .field.submit-button{margin-bottom:1em}.as3cf-sidebar .credits{border-top:0}.as3cf-sidebar .credits h4{font-size:16px;margin-top:0;margin-bottom:10px}.as3cf-sidebar .credits ul{margin:0}.as3cf-sidebar .credits li{overflow:hidden}.as3cf-sidebar .credits li:last-child{margin-bottom:0}.as3cf-sidebar .credits img{float:left;margin-right:10px}.as3cf-sidebar .credits span{float:left;display:block;line-height:32px}.as3cf-sidebar .credits a{display:block;text-decoration:none;color:#444;font-size:16px;text-align:center}.as3cf-sidebar .credits a:hover{color:#888}@media (min--moz-device-pixel-ratio: 1.3), (-webkit-min-device-pixel-ratio: 1.3), (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx){.as3cf-sidebar .as3cf-banner{background-image:url(../img/snail-banner@2x.jpg);background-size:292px 156px}}@media screen and (max-width: 1052px){.as3cf-sidebar{position:relative;top:auto;right:auto;margin-top:50px}}.as3cf-banner{margin-top:28px;width:292px;height:156px;display:block;background-image:url(../img/snail-banner.jpg);position:relative}.as3cf-banner h1{font-size:28px;color:#fff;font-weight:200;margin:0;position:absolute;bottom:25px;left:20px;text-decoration:none}.as3cf-upgrade-details{background-color:#73833b;padding:20px;color:#fff;font-size:13px;margin:0;display:block;text-decoration:none}.as3cf-upgrade-details p{margin:0}.as3cf-upgrade-details a{color:#fff;font-weight:bold;text-decoration:none;font-size:16px}.as3cf-upgrade-details a:hover{color:#fff;opacity:0.9}.as3cf-upgrade-details ul{margin-top:0;margin-left:16px;list-style-type:disc}.aws-compatibility-notice.error{clear:both;margin:5px 20px 5px 0}.as3cf-bucket-error span.title{font-weight:bold}.as3cf-invalid-bucket-name,.as3cf-validation-error{display:block;margin-top:2px;font-size:12px;color:#a00}.as3cf-notice-toggle-content{max-height:100px;overflow-y:scroll}.as3cf-notice-toggle-content .as3cf-notice-toggle-list{margin-top:0;margin-left:0;padding-left:26px;color:#dc3232}
assets/js/modal.js CHANGED
@@ -1,4 +1,4 @@
1
- var as3cfModal = (function ( $ ) {
2
3
var modal = {
4
prefix: 'as3cf',
@@ -18,6 +18,27 @@ var as3cfModal = (function ( $ ) {
18
return target.replace( /[^a-z]/g, '' );
19
}
20
21
/**
22
* Open modal
23
*
@@ -25,7 +46,7 @@ var as3cfModal = (function ( $ ) {
25
* @param {function} callback
26
* @param {string} customClass
27
*/
28
- modal.open = function ( target, callback, customClass ) {
29
var key = targetToKey( target );
30
31
// Overlay
@@ -66,14 +87,14 @@ var as3cfModal = (function ( $ ) {
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 () {
77
if ( 'function' === typeof callback ) {
78
callback( target );
79
}
@@ -91,19 +112,19 @@ var as3cfModal = (function ( $ ) {
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
101
- $( 'body' ).on( 'click', '[data-as3cf-modal]', function ( e ) {
102
e.preventDefault();
103
modal.open( $( this ).data( 'as3cf-modal' ) + '.' + modal.prefix );
104
} );
105
106
- $( 'body' ).on( 'click', '#as3cf-overlay, .close-as3cf-modal', function ( e ) {
107
e.preventDefault();
108
109
// Don't allow children to bubble up click event
@@ -118,4 +139,4 @@ var as3cfModal = (function ( $ ) {
118
119
return modal;
120
121
- })( jQuery );
1
+ var as3cfModal = (function( $ ) {
2
3
var modal = {
4
prefix: 'as3cf',
18
return target.replace( /[^a-z]/g, '' );
19
}
20
21
+ /**
22
+ * Check if modal exists in DOM or in Memory.
23
+ *
24
+ * @param {string} target
25
+ *
26
+ * @return {boolean}
27
+ */
28
+ modal.exists = function( target ) {
29
+ var key = targetToKey( target );
30
+
31
+ if ( undefined !== modals[ key ] ) {
32
+ return true;
33
+ }
34
+
35
+ if ( $( target ).length ) {
36
+ return true;
37
+ }
38
+
39
+ return false;
40
+ };
41
+
42
/**
43
* Open modal
44
*
46
* @param {function} callback
47
* @param {string} customClass
48
*/
49
+ modal.open = function( target, callback, customClass ) {
50
var key = targetToKey( target );
51
52
// Overlay
87
*
88
* @param {function} callback
89
*/
90
+ modal.close = function( callback ) {
91
if ( modal.loading ) {
92
return;
93
}
94
95
var target = $( '#as3cf-modal' ).data( 'as3cf-modal-target' );
96
97
+ $( '#as3cf-overlay' ).fadeOut( 150, function() {
98
if ( 'function' === typeof callback ) {
99
callback( target );
100
}
112
*
113
* @param {bool} state
114
*/
115
+ modal.setLoadingState = function( state ) {
116
modal.loading = state;
117
};
118
119
// Setup click handlers
120
+ $( document ).ready( function() {
121
122
+ $( 'body' ).on( 'click', '[data-as3cf-modal]', function( e ) {
123
e.preventDefault();
124
modal.open( $( this ).data( 'as3cf-modal' ) + '.' + modal.prefix );
125
} );
126
127
+ $( 'body' ).on( 'click', '#as3cf-overlay, .close-as3cf-modal', function( e ) {
128
e.preventDefault();
129
130
// Don't allow children to bubble up click event
139
140
return modal;
141
142
+ })( 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",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);
1
+ var as3cfModal=function(a){function b(a){return a.replace(/[^a-z]/g,"")}var c={prefix:"as3cf",loading:!1},d={};return c.exists=function(c){var e=b(c);return void 0!==d[e]?!0:!!a(c).length},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/notice.js CHANGED
@@ -1,24 +1,37 @@
1
(function( $ ) {
2
3
- $( 'body' ).on( 'click', '.as3cf-notice .notice-dismiss', function( e ) {
4
var id = $( this ).parents( '.as3cf-notice' ).attr( 'id' );
5
if ( id ) {
6
var data = {
7
- action : 'as3cf-dismiss-notice',
8
notice_id: id,
9
- _nonce : as3cf_notice.nonces.dismiss_notice
10
};
11
12
$.ajax( {
13
- url : ajaxurl,
14
- type : 'POST',
15
dataType: 'JSON',
16
- data : data,
17
- error : function( jqXHR, textStatus, errorThrown ) {
18
alert( as3cf_notice.strings.dismiss_notice_error + errorThrown );
19
}
20
} );
21
}
22
} );
23
24
- })( jQuery );
1
(function( $ ) {
2
3
+ var $body = $( 'body' );
4
+
5
+ $body.on( 'click', '.as3cf-notice .notice-dismiss', function( e ) {
6
var id = $( this ).parents( '.as3cf-notice' ).attr( 'id' );
7
if ( id ) {
8
var data = {
9
+ action: 'as3cf-dismiss-notice',
10
notice_id: id,
11
+ _nonce: as3cf_notice.nonces.dismiss_notice
12
};
13
14
$.ajax( {
15
+ url: ajaxurl,
16
+ type: 'POST',
17
dataType: 'JSON',
18
+ data: data,
19
+ error: function( jqXHR, textStatus, errorThrown ) {
20
alert( as3cf_notice.strings.dismiss_notice_error + errorThrown );
21
}
22
} );
23
}
24
} );
25
26
+ $body.on( 'click', '.as3cf-notice-toggle', function( e ) {
27
+ e.preventDefault();
28
+ var $link = $( this );
29
+ var label = $link.data( 'hide' );
30
+
31
+ $link.data( 'hide', $link.html() );
32
+ $link.html( label );
33
+
34
+ $link.closest( '.as3cf-notice' ).find( '.as3cf-notice-toggle-content' ).toggle();
35
+ } );
36
+
37
+ })( jQuery );
assets/js/notice.min.js CHANGED
@@ -1 +1 @@
1
- !function(a){a("body").on("click",".as3cf-notice .notice-dismiss",function(b){var c=a(this).parents(".as3cf-notice").attr("id");if(c){var d={action:"as3cf-dismiss-notice",notice_id:c,_nonce:as3cf_notice.nonces.dismiss_notice};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:d,error:function(a,b,c){alert(as3cf_notice.strings.dismiss_notice_error+c)}})}})}(jQuery);
1
+ !function(a){var b=a("body");b.on("click",".as3cf-notice .notice-dismiss",function(b){var c=a(this).parents(".as3cf-notice").attr("id");if(c){var d={action:"as3cf-dismiss-notice",notice_id:c,_nonce:as3cf_notice.nonces.dismiss_notice};a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:d,error:function(a,b,c){alert(as3cf_notice.strings.dismiss_notice_error+c)}})}}),b.on("click",".as3cf-notice-toggle",function(b){b.preventDefault();var c=a(this),d=c.data("hide");c.data("hide",c.html()),c.html(d),c.closest(".as3cf-notice").find(".as3cf-notice-toggle-content").toggle()})}(jQuery);
assets/js/script.js CHANGED
@@ -2,6 +2,7 @@
2
3
var savedSettings = {};
4
var bucketNamePattern = /[^a-z0-9.-]/;
5
6
var $tabs = $( '.as3cf-tab' );
7
var $activeTab;
@@ -24,7 +25,7 @@
24
* @param string checkbox_wrap
25
*/
26
function setCheckbox( checkbox_wrap ) {
27
- var $switch = $( '#' + checkbox_wrap );
28
var $checkbox = $switch.find( 'input[type=checkbox]' );
29
30
$switch.toggleClass( 'on' ).find( 'span' ).toggleClass( 'checked' );
@@ -38,7 +39,7 @@
38
* @param {object} $input
39
*/
40
function validateCustomDomain( $input ) {
41
- var $error = $input.next( '.as3cf-validation-error' );
42
var $submit = $( '#' + $activeTab.attr( 'id' ) + ' form button[type="submit"]' );
43
var pattern = /[^a-zA-Z0-9\.\-]/;
44
@@ -69,7 +70,7 @@
69
if ( $activeTab.attr( 'data-prefix' ) ) {
70
as3cfModal.prefix = $activeTab.attr( 'data-prefix' );
71
}
72
- if ( !persist_updated_notice ) {
73
$( '.as3cf-updated' ).removeClass( 'show' );
74
}
75
}
@@ -121,18 +122,18 @@
121
var that = this;
122
123
$.ajax( {
124
- url : ajaxurl,
125
- type : 'POST',
126
dataType: 'JSON',
127
- data : data,
128
- error : function( jqXHR, textStatus, errorThrown ) {
129
$bucketList.html( '' );
130
that.showError( as3cf.strings.get_buckets_error, errorThrown, 'as3cf-bucket-select' );
131
},
132
- success : function( data, textStatus, jqXHR ) {
133
$bucketList.html( '' );
134
135
- if ( typeof data[ 'success' ] !== 'undefined' ) {
136
$( '.as3cf-bucket-error' ).hide();
137
138
$( data[ 'buckets' ] ).each( function( idx, bucket ) {
@@ -176,7 +177,9 @@
176
$bucketContainer.find( '.as3cf-bucket-select' ).show().siblings().hide();
177
$bucketContainer.find( '.bucket-actions.select' ).show().siblings( '.bucket-actions' ).hide();
178
179
- this.loadList();
180
}
181
182
$bucketContainer.find( '.as3cf-bucket-error' ).hide();
@@ -210,29 +213,32 @@
210
$manualBucketButton.prop( 'disabled', true );
211
212
var data = {
213
- action : as3cfModal.prefix + '-manual-save-bucket',
214
bucket_name: bucketName,
215
- _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.manual_bucket
216
};
217
218
var that = this;
219
220
$.ajax( {
221
- url : ajaxurl,
222
- type : 'POST',
223
dataType: 'JSON',
224
- data : data,
225
- error : function( jqXHR, textStatus, errorThrown ) {
226
$manualBucketButton.text( originalBucketText );
227
that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-manual' );
228
},
229
- success : function( data, textStatus, jqXHR ) {
230
$manualBucketButton.text( originalBucketText );
231
$manualBucketButton.prop( 'disabled', false );
232
- if ( typeof data[ 'success' ] !== 'undefined' ) {
233
that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
234
$( '#' + as3cfModal.prefix + '-bucket-select' ).val( 'manual' );
235
$( '.as3cf-bucket-list a' ).removeClass( 'selected' ).filter( '[data-bucket="' + bucketName + '"]' ).addClass( 'selected' );
236
} else {
237
that.showError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-manual' );
238
}
@@ -249,6 +255,7 @@
249
var $bucketList = $( '.as3cf-bucket-list' );
250
251
if ( this.bucketSelectLock ) {
252
// Bail if a bucket has already been clicked
253
return;
254
}
@@ -272,28 +279,28 @@
272
var bucketName = $link.attr( 'data-bucket' );
273
274
var data = {
275
- action : as3cfModal.prefix + '-save-bucket',
276
bucket_name: bucketName,
277
- _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.save_bucket
278
};
279
280
var that = this;
281
282
$.ajax( {
283
- url : ajaxurl,
284
- type : 'POST',
285
dataType: 'JSON',
286
- data : data,
287
- error : function( jqXHR, textStatus, errorThrown ) {
288
$bucketList.removeClass( 'saving' );
289
that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-select' );
290
$( '.as3cf-bucket-list a' ).removeClass( 'selected' );
291
$( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
292
},
293
- success : function( data, textStatus, jqXHR ) {
294
$link.find( '.spinner' ).hide().css( 'visibility', 'hidden' );
295
$bucketList.removeClass( 'saving' );
296
- if ( typeof data[ 'success' ] !== 'undefined' ) {
297
that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
298
$( '#' + as3cfModal.prefix + '-bucket-select' ).val( '' );
299
} else {
@@ -318,15 +325,13 @@
318
319
if ( $createBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
320
$createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
321
- }
322
- else {
323
$createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
324
}
325
326
if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
327
$manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
328
- }
329
- else {
330
$manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
331
}
332
},
@@ -342,7 +347,7 @@
342
var $activeView = $( '.as3cf-bucket-container' ).children( ':visible' );
343
var $bucketError = $activeView.find( '.as3cf-bucket-error' );
344
345
- context = ('undefined' === typeof context) ? null : context;
346
347
if ( context && ! $activeView.hasClass( context ) ) {
348
return;
@@ -368,11 +373,12 @@
368
var $activeBucket = $( '#' + as3cfModal.prefix + '-active-bucket' );
369
370
if ( 'as3cf' === as3cfModal.prefix && 0 === $activeBucket.text().trim().length ) {
371
- // first time bucket select - enable main options by default
372
setCheckbox( 'copy-to-s3-wrap' );
373
setCheckbox( 'serve-from-s3-wrap' );
374
375
- // update the saved settings string so we don't trigger the navigation alert
376
var id = $activeTab.attr( 'id' );
377
savedSettings[ id ] = serializedForm( id );
378
}
@@ -387,7 +393,8 @@
387
$( '.updated' ).not( '.as3cf-notice' ).show();
388
389
$activeTab.addClass( 'as3cf-has-bucket' );
390
- // check permission on bucket
391
$activeTab.find( '.as3cf-can-write-error' ).toggle( ! canWrite );
392
$activeTab.find( '.as3cf-bucket-error' ).hide();
393
@@ -417,9 +424,9 @@
417
$createBucketButton.prop( 'disabled', true );
418
419
var data = {
420
- action : as3cfModal.prefix + '-create-bucket',
421
bucket_name: bucketName,
422
- _nonce : window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.create_bucket
423
};
424
425
if ( $createBucketSelect.val() ) {
@@ -429,24 +436,28 @@
429
var that = this;
430
431
$.ajax( {
432
- url : ajaxurl,
433
- type : 'POST',
434
dataType: 'JSON',
435
- data : data,
436
- error : function( jqXHR, textStatus, errorThrown ) {
437
$createBucketButton.text( origButtonText );
438
that.showError( as3cf.strings.create_bucket_error, errorThrown, 'as3cf-bucket-create' );
439
},
440
- success : function( data, textStatus, jqXHR ) {
441
$createBucketButton.text( origButtonText );
442
$createBucketButton.prop( 'disabled', false );
443
- if ( typeof data[ 'success' ] !== 'undefined' ) {
444
that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
445
- // tidy up create bucket form
446
$( '.as3cf-bucket-select-region' ).hide();
447
$( '.as3cf-bucket-select-region' ).removeAttr( 'selected' );
448
$createBucketInput.val( '' );
449
$createBucketButton.attr( 'disabled', true );
450
} else {
451
that.showError( as3cf.strings.create_bucket_error, data[ 'error' ], 'as3cf-bucket-create' );
452
}
@@ -533,10 +544,10 @@
533
var n = o.name,
534
v = o.value;
535
n = n.replace( '[]', '' );
536
- data[ n ] = data[ n ] === undefined ? v : $.isArray( data[ n ] ) ? data[ n ].concat( v ) : [ data[ n ], v ];
537
} );
538
539
- // overwrite the save action stored in the form
540
data[ 'action' ] = 'as3cf-get-url-preview';
541
542
$.ajax( {
@@ -548,7 +559,7 @@
548
alert( as3cf.strings.get_url_preview_error + errorThrown );
549
},
550
success: function( data, textStatus, jqXHR ) {
551
- if ( typeof data[ 'success' ] !== 'undefined' ) {
552
$( '.as3cf-url-preview' ).html( data[ 'url' ] );
553
} else {
554
alert( as3cf.strings.get_url_preview_error + data[ 'error' ] );
@@ -561,6 +572,7 @@
561
* Reset the bucket select lock
562
*/
563
function unlockBucketSelect( target ) {
564
// Unlock setting the bucket
565
as3cf.buckets.bucketSelectLock = false;
566
}
@@ -596,12 +608,13 @@
596
var $navTabs = $( '.wrap.aws-main .nav-tab-wrapper' );
597
$( '.aws-compatibility-notice, div.updated, div.error, div.notice' ).not( '.below-h2, .inline' ).insertAfter( $navTabs );
598
599
- // check for hash in url and switch tabs accordingly
600
if ( window.location.hash ) {
601
var hash = window.location.hash.substring( 1 );
602
as3cf.tabs.toggle( hash, true );
603
} else {
604
- // default settings tab
605
$activeTab = $( '#tab-' + as3cf.tabs.defaultTab );
606
$( '.aws-main' ).attr( 'data-tab', as3cf.tabs.defaultTab );
607
}
@@ -614,9 +627,11 @@
614
var nextTab = $( this ).attr( 'data-tab' );
615
as3cf.tabs.toggle( nextTab );
616
if ( 'media' === nextTab ) {
617
// As it's the default remove the hash
618
window.location.hash = '';
619
- if ( typeof window.history.replaceState === 'function' && '#' === window.location.href.slice( -1 ) ) {
620
// Strip the # if still on the end of the URL
621
history.replaceState( {}, '', window.location.href.slice( 0, -1 ) );
622
}
@@ -628,14 +643,14 @@
628
// Settings
629
// --------------------
630
631
- // save the original state of the forms for comparison later
632
if ( $tabs.length ) {
633
$tabs.each( function( i, tab ) {
634
savedSettings[ tab.id ] = serializedForm( tab.id );
635
} );
636
}
637
638
- // prompt user with dialog if leaving the settings page with unsaved changes
639
$( window ).on( 'beforeunload.as3cf-settings', function() {
640
if ( $.isEmptyObject( savedSettings ) ) {
641
return;
@@ -648,14 +663,15 @@
648
}
649
} );
650
651
- // let the save settings submit happen as normal
652
$( document ).on( 'submit', '.as3cf-main-settings form', function( e ) {
653
- // disable unload warning
654
$( window ).off( 'beforeunload.as3cf-settings' );
655
} );
656
657
$( '.as3cf-switch' ).on( 'click', function( e ) {
658
- if ( !$( this ).hasClass( 'disabled' ) ) {
659
setCheckbox( $( this ).attr( 'id' ) );
660
}
661
} );
@@ -670,15 +686,19 @@
670
var domain = $selected.val();
671
var $cloudfront = $( this ).parents( '.as3cf-domain' ).find( '.as3cf-setting.cloudfront' );
672
var cloudfrontSelected = ( 'cloudfront' === domain );
673
- $cloudfront.toggleClass( 'hide', !cloudfrontSelected );
674
} );
675
676
$( '.as3cf-ssl' ).on( 'change', 'input[type="radio"]', function( e ) {
677
var ssl = $( 'input:radio[name="ssl"]:checked' ).val();
678
if ( 'https' === ssl ) {
679
var domain = $( 'input:radio[name="domain"]:checked' ).val();
680
if ( 'subdomain' === domain ) {
681
- $( 'input[name="domain"][value="path"]' ).attr( "checked", true );
682
}
683
$( '.subdomain-wrap input' ).attr( 'disabled', true );
684
$( '.subdomain-wrap' ).addClass( 'disabled' );
@@ -709,7 +729,6 @@
709
710
return false;
711
}
712
-
713
} );
714
715
// Validate custom domain
@@ -748,7 +767,8 @@
748
$( 'body' ).on( 'click', '.bucket-action-browse', function( e ) {
749
e.preventDefault();
750
$( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-select' ).show().siblings().hide();
751
- as3cf.buckets.loadList();
752
} );
753
$( 'body' ).on( 'click', '.bucket-action-create', function( e ) {
754
e.preventDefault();
@@ -795,11 +815,14 @@
795
// Modal open
796
$( 'body' ).on( 'as3cf-modal-open', function( e, target ) {
797
if ( '.as3cf-bucket-container.' + as3cfModal.prefix === target ) {
798
// Reset modal
799
as3cf.buckets.resetModal();
800
// Change manual title text
801
var title = $( '.as3cf-bucket-manual h3' ).data( 'modal-title' );
802
$( '.as3cf-bucket-manual h3' ).text( title );
803
// Hide buttons
804
as3cf.buckets.disabledButtons();
805
}
2
3
var savedSettings = {};
4
var bucketNamePattern = /[^a-z0-9.-]/;
5
+ var refreshBucketListOnLoad = false;
6
7
var $tabs = $( '.as3cf-tab' );
8
var $activeTab;
25
* @param string checkbox_wrap
26
*/
27
function setCheckbox( checkbox_wrap ) {
28
+ var $switch = $activeTab.find( '#' + checkbox_wrap );
29
var $checkbox = $switch.find( 'input[type=checkbox]' );
30
31
$switch.toggleClass( 'on' ).find( 'span' ).toggleClass( 'checked' );
39
* @param {object} $input
40
*/
41
function validateCustomDomain( $input ) {
42
+ var $error = $input.next( '.as3cf-validation-error' );
43
var $submit = $( '#' + $activeTab.attr( 'id' ) + ' form button[type="submit"]' );
44
var pattern = /[^a-zA-Z0-9\.\-]/;
45
70
if ( $activeTab.attr( 'data-prefix' ) ) {
71
as3cfModal.prefix = $activeTab.attr( 'data-prefix' );
72
}
73
+ if ( ! persist_updated_notice ) {
74
$( '.as3cf-updated' ).removeClass( 'show' );
75
}
76
}
122
var that = this;
123
124
$.ajax( {
125
+ url: ajaxurl,
126
+ type: 'POST',
127
dataType: 'JSON',
128
+ data: data,
129
+ error: function( jqXHR, textStatus, errorThrown ) {
130
$bucketList.html( '' );
131
that.showError( as3cf.strings.get_buckets_error, errorThrown, 'as3cf-bucket-select' );
132
},
133
+ success: function( data, textStatus, jqXHR ) {
134
$bucketList.html( '' );
135
136
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
137
$( '.as3cf-bucket-error' ).hide();
138
139
$( data[ 'buckets' ] ).each( function( idx, bucket ) {
177
$bucketContainer.find( '.as3cf-bucket-select' ).show().siblings().hide();
178
$bucketContainer.find( '.bucket-actions.select' ).show().siblings( '.bucket-actions' ).hide();
179
180
+ this.loadList( refreshBucketListOnLoad );
181
+
182
+ refreshBucketListOnLoad = false;
183
}
184
185
$bucketContainer.find( '.as3cf-bucket-error' ).hide();
213
$manualBucketButton.prop( 'disabled', true );
214
215
var data = {
216
+ action: as3cfModal.prefix + '-manual-save-bucket',
217
bucket_name: bucketName,
218
+ _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.manual_bucket
219
};
220
221
var that = this;
222
223
$.ajax( {
224
+ url: ajaxurl,
225
+ type: 'POST',
226
dataType: 'JSON',
227
+ data: data,
228
+ error: function( jqXHR, textStatus, errorThrown ) {
229
$manualBucketButton.text( originalBucketText );
230
that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-manual' );
231
},
232
+ success: function( data, textStatus, jqXHR ) {
233
$manualBucketButton.text( originalBucketText );
234
$manualBucketButton.prop( 'disabled', false );
235
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
236
that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
237
$( '#' + as3cfModal.prefix + '-bucket-select' ).val( 'manual' );
238
$( '.as3cf-bucket-list a' ).removeClass( 'selected' ).filter( '[data-bucket="' + bucketName + '"]' ).addClass( 'selected' );
239
+
240
+ // Make sure the bucket list will refresh the next time the modal loads
241
+ refreshBucketListOnLoad = true;
242
} else {
243
that.showError( as3cf.strings.save_bucket_error, data[ 'error' ], 'as3cf-bucket-manual' );
244
}
255
var $bucketList = $( '.as3cf-bucket-list' );
256
257
if ( this.bucketSelectLock ) {
258
+
259
// Bail if a bucket has already been clicked
260
return;
261
}
279
var bucketName = $link.attr( 'data-bucket' );
280
281
var data = {
282
+ action: as3cfModal.prefix + '-save-bucket',
283
bucket_name: bucketName,
284
+ _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.save_bucket
285
};
286
287
var that = this;
288
289
$.ajax( {
290
+ url: ajaxurl,
291
+ type: 'POST',
292
dataType: 'JSON',
293
+ data: data,
294
+ error: function( jqXHR, textStatus, errorThrown ) {
295
$bucketList.removeClass( 'saving' );
296
that.showError( as3cf.strings.save_bucket_error, errorThrown, 'as3cf-bucket-select' );
297
$( '.as3cf-bucket-list a' ).removeClass( 'selected' );
298
$( '.as3cf-bucket-list a[data-bucket="' + previousBucket + '"]' ).addClass( 'selected' );
299
},
300
+ success: function( data, textStatus, jqXHR ) {
301
$link.find( '.spinner' ).hide().css( 'visibility', 'hidden' );
302
$bucketList.removeClass( 'saving' );
303
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
304
that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
305
$( '#' + as3cfModal.prefix + '-bucket-select' ).val( '' );
306
} else {
325
326
if ( $createBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
327
$createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
328
+ } else {
329
$createBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
330
}
331
332
if ( $manualBucketForm.find( '.as3cf-bucket-name' ).val().length < 3 ) {
333
$manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', true );
334
+ } else {
335
$manualBucketForm.find( 'button[type=submit]' ).attr( 'disabled', false );
336
}
337
},
347
var $activeView = $( '.as3cf-bucket-container' ).children( ':visible' );
348
var $bucketError = $activeView.find( '.as3cf-bucket-error' );
349
350
+ context = ( 'undefined' === typeof context ) ? null : context;
351
352
if ( context && ! $activeView.hasClass( context ) ) {
353
return;
373
var $activeBucket = $( '#' + as3cfModal.prefix + '-active-bucket' );
374
375
if ( 'as3cf' === as3cfModal.prefix && 0 === $activeBucket.text().trim().length ) {
376
+
377
+ // First time bucket select - enable main options by default
378
setCheckbox( 'copy-to-s3-wrap' );
379
setCheckbox( 'serve-from-s3-wrap' );
380
381
+ // Update the saved settings string so we don't trigger the navigation alert
382
var id = $activeTab.attr( 'id' );
383
savedSettings[ id ] = serializedForm( id );
384
}
393
$( '.updated' ).not( '.as3cf-notice' ).show();
394
395
$activeTab.addClass( 'as3cf-has-bucket' );
396
+
397
+ // Check permission on bucket
398
$activeTab.find( '.as3cf-can-write-error' ).toggle( ! canWrite );
399
$activeTab.find( '.as3cf-bucket-error' ).hide();
400
424
$createBucketButton.prop( 'disabled', true );
425
426
var data = {
427
+ action: as3cfModal.prefix + '-create-bucket',
428
bucket_name: bucketName,
429
+ _nonce: window[ as3cfModal.prefix.replace( /-/g, '_' ) ].nonces.create_bucket
430
};
431
432
if ( $createBucketSelect.val() ) {
436
var that = this;
437
438
$.ajax( {
439
+ url: ajaxurl,
440
+ type: 'POST',
441
dataType: 'JSON',
442
+ data: data,
443
+ error: function( jqXHR, textStatus, errorThrown ) {
444
$createBucketButton.text( origButtonText );
445
that.showError( as3cf.strings.create_bucket_error, errorThrown, 'as3cf-bucket-create' );
446
},
447
+ success: function( data, textStatus, jqXHR ) {
448
$createBucketButton.text( origButtonText );
449
$createBucketButton.prop( 'disabled', false );
450
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
451
that.set( bucketName, data[ 'region' ], data[ 'can_write' ] );
452
+
453
+ // Tidy up create bucket form
454
$( '.as3cf-bucket-select-region' ).hide();
455
$( '.as3cf-bucket-select-region' ).removeAttr( 'selected' );
456
$createBucketInput.val( '' );
457
$createBucketButton.attr( 'disabled', true );
458
+
459
+ // Make sure the bucket list will refresh the next time the modal loads
460
+ refreshBucketListOnLoad = true;
461
} else {
462
that.showError( as3cf.strings.create_bucket_error, data[ 'error' ], 'as3cf-bucket-create' );
463
}
544
var n = o.name,
545
v = o.value;
546
n = n.replace( '[]', '' );
547
+ data[ n ] = undefined === data[ n ] ? v : $.isArray( data[ n ] ) ? data[ n ].concat( v ) : [ data[ n ], v ];
548
} );
549
550
+ // Overwrite the save action stored in the form
551
data[ 'action' ] = 'as3cf-get-url-preview';
552
553
$.ajax( {
559
alert( as3cf.strings.get_url_preview_error + errorThrown );
560
},
561
success: function( data, textStatus, jqXHR ) {
562
+ if ( 'undefined' !== typeof data[ 'success' ] ) {
563
$( '.as3cf-url-preview' ).html( data[ 'url' ] );
564
} else {
565
alert( as3cf.strings.get_url_preview_error + data[ 'error' ] );
572
* Reset the bucket select lock
573
*/
574
function unlockBucketSelect( target ) {
575
+
576
// Unlock setting the bucket
577
as3cf.buckets.bucketSelectLock = false;
578
}
608
var $navTabs = $( '.wrap.aws-main .nav-tab-wrapper' );
609
$( '.aws-compatibility-notice, div.updated, div.error, div.notice' ).not( '.below-h2, .inline' ).insertAfter( $navTabs );
610
611
+ // Check for hash in url and switch tabs accordingly
612
if ( window.location.hash ) {
613
var hash = window.location.hash.substring( 1 );
614
as3cf.tabs.toggle( hash, true );
615
} else {
616
+
617
+ // Default settings tab
618
$activeTab = $( '#tab-' + as3cf.tabs.defaultTab );
619
$( '.aws-main' ).attr( 'data-tab', as3cf.tabs.defaultTab );
620
}
627
var nextTab = $( this ).attr( 'data-tab' );
628
as3cf.tabs.toggle( nextTab );
629
if ( 'media' === nextTab ) {
630
+
631
// As it's the default remove the hash
632
window.location.hash = '';
633
+ if ( 'function' === typeof window.history.replaceState && '#' === window.location.href.slice( -1 ) ) {
634
+
635
// Strip the # if still on the end of the URL
636
history.replaceState( {}, '', window.location.href.slice( 0, -1 ) );
637
}
643
// Settings
644
// --------------------
645
646
+ // Save the original state of the forms for comparison later
647
if ( $tabs.length ) {
648
$tabs.each( function( i, tab ) {
649
savedSettings[ tab.id ] = serializedForm( tab.id );
650
} );
651
}
652
653
+ // Prompt user with dialog if leaving the settings page with unsaved changes
654
$( window ).on( 'beforeunload.as3cf-settings', function() {
655
if ( $.isEmptyObject( savedSettings ) ) {
656
return;
663
}
664
} );
665
666
+ // Let the save settings submit happen as normal
667
$( document ).on( 'submit', '.as3cf-main-settings form', function( e ) {
668
+
669
+ // Disable unload warning
670
$( window ).off( 'beforeunload.as3cf-settings' );
671
} );
672
673
$( '.as3cf-switch' ).on( 'click', function( e ) {
674
+ if ( ! $( this ).hasClass( 'disabled' ) ) {
675
setCheckbox( $( this ).attr( 'id' ) );
676
}
677
} );
686
var domain = $selected.val();
687
var $cloudfront = $( this ).parents( '.as3cf-domain' ).find( '.as3cf-setting.cloudfront' );
688
var cloudfrontSelected = ( 'cloudfront' === domain );
689
+ $cloudfront.toggleClass( 'hide', ! cloudfrontSelected );
690
} );
691
692
$( '.as3cf-ssl' ).on( 'change', 'input[type="radio"]', function( e ) {
693
+ if ( ! $( '#' + $activeTab.attr( 'id' ) + ' .deprecated-domain' ).length ) {
694
+ return;
695
+ }
696
+
697
var ssl = $( 'input:radio[name="ssl"]:checked' ).val();
698
if ( 'https' === ssl ) {
699
var domain = $( 'input:radio[name="domain"]:checked' ).val();
700
if ( 'subdomain' === domain ) {
701
+ $( 'input[name="domain"][value="path"]' ).attr( 'checked', true );
702
}
703
$( '.subdomain-wrap input' ).attr( 'disabled', true );
704
$( '.subdomain-wrap' ).addClass( 'disabled' );
729
730
return false;
731
}
732
} );
733
734
// Validate custom domain
767
$( 'body' ).on( 'click', '.bucket-action-browse', function( e ) {
768
e.preventDefault();
769
$( '.as3cf-bucket-container.' + as3cfModal.prefix + ' .as3cf-bucket-select' ).show().siblings().hide();
770
+ as3cf.buckets.loadList( refreshBucketListOnLoad );
771
+ refreshBucketListOnLoad = false;
772
} );
773
$( 'body' ).on( 'click', '.bucket-action-create', function( e ) {
774
e.preventDefault();
815
// Modal open
816
$( 'body' ).on( 'as3cf-modal-open', function( e, target ) {
817
if ( '.as3cf-bucket-container.' + as3cfModal.prefix === target ) {
818
+
819
// Reset modal
820
as3cf.buckets.resetModal();
821
+
822
// Change manual title text
823
var title = $( '.as3cf-bucket-manual h3' ).data( 'modal-title' );
824
$( '.as3cf-bucket-manual h3' ).text( title );
825
+
826
// Hide buttons
827
as3cf.buckets.disabledButtons();
828
}
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(b){var c=b.next(".as3cf-validation-error"),d=a("#"+k.attr("id")+' form button[type="submit"]'),e=/[^a-zA-Z0-9\.\-]/;e.test(b.val())?(c.show(),d.attr("disabled",!0)):(c.hide(),d.attr("disabled",!1))}function f(){var c=a("#"+b.prefix+"-bucket").val(),d=k.find('input[name="object-prefix"]'),e=d.val();""!==e&&(e="&prefix="+encodeURIComponent(e));var f=as3cf.aws_bucket_link+c+e;a("#"+b.prefix+"-view-bucket").attr("href",f)}function g(){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,c,d){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function h(a){as3cf.buckets.bucketSelectLock=!1}function i(){a("#remove-local-file").is(":checked")&&a("#serve-from-s3").is(":not(:checked)")?a("#as3cf-lost-files-notice").show():a("#as3cf-lost-files-notice").hide()}function j(){a("#remove-local-file").is(":checked")?a("#as3cf-remove-local-notice").show():a("#as3cf-remove-local-notice").hide()}var k,l={},m=/[^a-z0-9.-]/,n=a(".as3cf-tab");as3cf.tabs={defaultTab:"media",toggle:function(c,d){n.hide(),k=a("#tab-"+c),k.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),k.attr("data-prefix")&&(b.prefix=k.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,c,f){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===k.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(),g=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),k.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.attr("data-working")),e.prop("disabled",!0);var h={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(a,b,c){e.text(g),i.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c,d,h){e.text(g),e.prop("disabled",!1),"undefined"!=typeof c.success?(i.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")):i.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 k.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"),g={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},h=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(b,c,f){d.removeClass("saving"),h.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,i,j){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(h.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(h.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+" &mdash;"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(e,i,j){var m=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),n=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&0===n.text().trim().length){d("copy-to-s3-wrap"),d("serve-from-s3-wrap");var o=k.attr("id");l[o]=c(o)}a(".as3cf-error.fatal").hide(),n.text(e),m.find(".as3cf-bucket-name").val(e),a("#"+b.prefix+"-bucket").val(e),a("#"+b.prefix+"-region").val(i),a(".updated").not(".as3cf-notice").show(),k.addClass("as3cf-has-bucket"),k.find(".as3cf-can-write-error").toggle(!j),k.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&g(),f(),b.close(h)},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,c,e){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===m.test(a)?!1:!0},updateNameNotice:function(b){var c=null;!0===m.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),c&&b.length>0?a(".as3cf-invalid-bucket-name").html(c):a(".as3cf-invalid-bucket-name").html("")}},a(document).ready(function(){var h=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(h),window.location.hash){var m=window.location.hash.substring(1);as3cf.tabs.toggle(m,!0)}else k=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}}),n.length&&n.each(function(a,b){l[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(l)){var b=k.attr("id");return c(b)!==l[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(b){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(b){a(this).hasClass("disabled")||d(a(this).attr("id"))}),n.on("change",".sub-toggle",function(b){var c=a(this).attr("id");a(".as3cf-setting."+c).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(b){var c=a(this).closest('input:radio[name="domain"]:checked'),d=c.val(),e=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),f="cloudfront"===d;e.toggleClass("hide",!f)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(b){var c=a('input:radio[name="ssl"]:checked').val();if("https"===c){var d=a('input:radio[name="domain"]:checked').val();"subdomain"===d&&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(a){g()}),i(),a("#serve-from-s3,#remove-local-file").on("change",function(a){i()}),j(),a("#remove-local-file").on("change",function(a){j()}),a('.as3cf-setting input[type="text"]').keypress(function(a){return 13===a.which?(a.preventDefault(),!1):void 0}),a('input[name="cloudfront"]').on("keyup",function(b){e(a(this))}),a('input[name="domain"]').on("change",function(b){var c=a(this),d=a("#"+k.attr("id")+' form button[type="submit"]');"cloudfront"!==c.val()?d.attr("disabled",!1):e(c.next(".as3cf-setting").find('input[name="cloudfront"]'))}),a('input[name="object-prefix"]').on("change",function(a){f()}),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(c){var d=a(this).val(),e=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(d)?e.find("button[type=submit]").removeAttr("disabled"):e.find("button[type=submit]").attr("disabled",!0),as3cf.buckets.updateNameNotice(d)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(c){var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");d.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?d.find("button[type=submit]").attr("disabled",!0):d.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(a){var b=k.find("#"+a),c=b.find("input[type=checkbox]");b.toggleClass("on").find("span").toggleClass("checked");var d=b.find("span.on").hasClass("checked");c.attr("checked",d).trigger("change")}function e(b){var c=b.next(".as3cf-validation-error"),d=a("#"+k.attr("id")+' form button[type="submit"]'),e=/[^a-zA-Z0-9\.\-]/;e.test(b.val())?(c.show(),d.attr("disabled",!0)):(c.hide(),d.attr("disabled",!1))}function f(){var c=a("#"+b.prefix+"-bucket").val(),d=k.find('input[name="object-prefix"]'),e=d.val();""!==e&&(e="&prefix="+encodeURIComponent(e));var f=as3cf.aws_bucket_link+c+e;a("#"+b.prefix+"-view-bucket").attr("href",f)}function g(){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,c,d){"undefined"!=typeof b.success?a(".as3cf-url-preview").html(b.url):alert(as3cf.strings.get_url_preview_error+b.error)}})}function h(a){as3cf.buckets.bucketSelectLock=!1}function i(){a("#remove-local-file").is(":checked")&&a("#serve-from-s3").is(":not(:checked)")?a("#as3cf-lost-files-notice").show():a("#as3cf-lost-files-notice").hide()}function j(){a("#remove-local-file").is(":checked")?a("#as3cf-remove-local-notice").show():a("#as3cf-remove-local-notice").hide()}var k,l={},m=/[^a-z0-9.-]/,n=!1,o=a(".as3cf-tab");as3cf.tabs={defaultTab:"media",toggle:function(c,d){o.hide(),k=a("#tab-"+c),k.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),k.attr("data-prefix")&&(b.prefix=k.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,c,f){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===k.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(n),n=!1),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(),g=e.first().text();if(f===a("#"+b.prefix+"-active-bucket").text())return a(".as3cf-bucket-error").hide(),k.addClass("as3cf-has-bucket"),void b.close();a(".as3cf-bucket-error").hide(),e.text(e.attr("data-working")),e.prop("disabled",!0);var h={action:b.prefix+"-manual-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.manual_bucket},i=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:h,error:function(a,b,c){e.text(g),i.showError(as3cf.strings.save_bucket_error,c,"as3cf-bucket-manual")},success:function(c,d,h){e.text(g),e.prop("disabled",!1),"undefined"!=typeof c.success?(i.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"),n=!0):i.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 k.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"),g={action:b.prefix+"-save-bucket",bucket_name:f,_nonce:window[b.prefix.replace(/-/g,"_")].nonces.save_bucket},h=this;a.ajax({url:ajaxurl,type:"POST",dataType:"JSON",data:g,error:function(b,c,f){d.removeClass("saving"),h.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,i,j){c.find(".spinner").hide().css("visibility","hidden"),d.removeClass("saving"),"undefined"!=typeof g.success?(h.set(f,g.region,g.can_write),a("#"+b.prefix+"-bucket-select").val("")):(h.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+" &mdash;"),f.find("span.message").html(c),f.show(),this.bucketSelectLock=!1)},set:function(e,i,j){var m=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form"),n=a("#"+b.prefix+"-active-bucket");if("as3cf"===b.prefix&&0===n.text().trim().length){d("copy-to-s3-wrap"),d("serve-from-s3-wrap");var o=k.attr("id");l[o]=c(o)}a(".as3cf-error.fatal").hide(),n.text(e),m.find(".as3cf-bucket-name").val(e),a("#"+b.prefix+"-bucket").val(e),a("#"+b.prefix+"-region").val(i),a(".updated").not(".as3cf-notice").show(),k.addClass("as3cf-has-bucket"),k.find(".as3cf-can-write-error").toggle(!j),k.find(".as3cf-bucket-error").hide(),"as3cf"===b.prefix&&g(),f(),b.close(h)},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,c,e){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),n=!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!==m.test(a)},updateNameNotice:function(b){var c=null;!0===m.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),c&&b.length>0?a(".as3cf-invalid-bucket-name").html(c):a(".as3cf-invalid-bucket-name").html("")}},a(document).ready(function(){var h=a(".wrap.aws-main .nav-tab-wrapper");if(a(".aws-compatibility-notice, div.updated, div.error, div.notice").not(".below-h2, .inline").insertAfter(h),window.location.hash){var m=window.location.hash.substring(1);as3cf.tabs.toggle(m,!0)}else k=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}}),o.length&&o.each(function(a,b){l[b.id]=c(b.id)}),a(window).on("beforeunload.as3cf-settings",function(){if(!a.isEmptyObject(l)){var b=k.attr("id");return c(b)!==l[b]?as3cf.strings.save_alert:void 0}}),a(document).on("submit",".as3cf-main-settings form",function(b){a(window).off("beforeunload.as3cf-settings")}),a(".as3cf-switch").on("click",function(b){a(this).hasClass("disabled")||d(a(this).attr("id"))}),o.on("change",".sub-toggle",function(b){var c=a(this).attr("id");a(".as3cf-setting."+c).toggleClass("hide")}),a(".as3cf-domain").on("change",'input[type="radio"]',function(b){var c=a(this).closest('input:radio[name="domain"]:checked'),d=c.val(),e=a(this).parents(".as3cf-domain").find(".as3cf-setting.cloudfront"),f="cloudfront"===d;e.toggleClass("hide",!f)}),a(".as3cf-ssl").on("change",'input[type="radio"]',function(b){if(a("#"+k.attr("id")+" .deprecated-domain").length){var c=a('input:radio[name="ssl"]:checked').val();if("https"===c){var d=a('input:radio[name="domain"]:checked').val();"subdomain"===d&&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(a){g()}),i(),a("#serve-from-s3,#remove-local-file").on("change",function(a){i()}),j(),a("#remove-local-file").on("change",function(a){j()}),a('.as3cf-setting input[type="text"]').keypress(function(a){return 13===a.which?(a.preventDefault(),!1):void 0}),a('input[name="cloudfront"]').on("keyup",function(b){e(a(this))}),a('input[name="domain"]').on("change",function(b){var c=a(this),d=a("#"+k.attr("id")+' form button[type="submit"]');"cloudfront"!==c.val()?d.attr("disabled",!1):e(c.next(".as3cf-setting").find('input[name="cloudfront"]'))}),a('input[name="object-prefix"]').on("change",function(a){f()}),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(n),n=!1}),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(c){var d=a(this).val(),e=a(".as3cf-bucket-container."+b.prefix+" .as3cf-create-bucket-form");as3cf.buckets.isValidName(d)?e.find("button[type=submit]").removeAttr("disabled"):e.find("button[type=submit]").attr("disabled",!0),as3cf.buckets.updateNameNotice(d)}),a("body").on("input keyup",".as3cf-manual-save-bucket-form .as3cf-bucket-name",function(c){var d=a(".as3cf-bucket-container."+b.prefix+" .as3cf-manual-save-bucket-form");d.find(".as3cf-bucket-name").val().length<as3cf.buckets.validLength?d.find("button[type=submit]").attr("disabled",!0):d.find("button[type=submit]").removeAttr("disabled")})})}(jQuery,as3cfModal);
assets/sass/styles.scss CHANGED
@@ -36,6 +36,10 @@
36
}
37
}
38
39
.error {
40
pre {
41
background: #eaeaea;
@@ -142,12 +146,13 @@
142
}
143
}
144
145
- .as3cf-ssl {
146
- p.info {
147
- margin-top: 10px;
148
- padding: 0;
149
}
150
- }
151
152
.as3cf-radio-group {
153
label {
@@ -267,6 +272,10 @@
267
.as3cf-notice:last-child {
268
margin-bottom: 0;
269
}
270
}
271
272
&:first-of-type {
@@ -275,6 +284,11 @@
275
}
276
}
277
}
278
h3 {
279
padding: 0;
280
margin: 0;
@@ -295,6 +309,9 @@
295
&:hover, &:active {
296
color: #00a0d2;
297
}
298
.dashicons-external {
299
margin-top: -2px;
300
}
@@ -361,6 +378,34 @@
361
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
362
opacity: 1;
363
}
364
}
365
366
/**
@@ -737,4 +782,16 @@
737
margin-top: 2px;
738
font-size: 12px;
739
color: #a00;
740
}
36
}
37
}
38
39
+ .more-info {
40
+ white-space: nowrap;
41
+ }
42
+
43
.error {
44
pre {
45
background: #eaeaea;
146
}
147
}
148
149
+ .as3cf-ssl {
150
+ margin-top: 10px;
151
+ p.info {
152
+ margin-top: 10px;
153
+ padding: 0;
154
+ }
155
}
156
157
.as3cf-radio-group {
158
label {
272
.as3cf-notice:last-child {
273
margin-bottom: 0;
274
}
275
+
276
+ & > p:first-child {
277
+ margin-top: 0;
278
+ }
279
}
280
281
&:first-of-type {
284
}
285
}
286
}
287
+
288
+ tr.as3cf-bucket-setting .as3cf-defined-in-config {
289
+ float: none;
290
+ }
291
+
292
h3 {
293
padding: 0;
294
margin: 0;
309
&:hover, &:active {
310
color: #00a0d2;
311
}
312
+ &:focus {
313
+ box-shadow: none;
314
+ }
315
.dashicons-external {
316
margin-top: -2px;
317
}
378
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
379
opacity: 1;
380
}
381
+
382
+ .as3cf-defined-in-config {
383
+ background: #ccc;
384
+ color: #fff;
385
+ padding: 2px 5px;
386
+ margin: 0 0 5px 5px;
387
+ float: right;
388
+ }
389
+
390
+ .as3cf-defined-setting {
391
+ color: #bbb;
392
+
393
+ label {
394
+ cursor: default;
395
+ }
396
+
397
+ p .more-info a {
398
+ color: #bbb;
399
+ }
400
+
401
+ .as3cf-radio-group p {
402
+ color: #bbb;
403
+ }
404
+
405
+ .as3cf-notice {
406
+ display: none !important;
407
+ }
408
+ }
409
}
410
411
/**
782
margin-top: 2px;
783
font-size: 12px;
784
color: #a00;
785
+ }
786
+
787
+ .as3cf-notice-toggle-content {
788
+ max-height: 100px;
789
+ overflow-y: scroll;
790
+
791
+ .as3cf-notice-toggle-list {
792
+ margin-top: 0;
793
+ margin-left: 0;
794
+ padding-left: 26px;
795
+ color: #dc3232;
796
+ }
797
}
classes/amazon-s3-and-cloudfront.php CHANGED
@@ -73,6 +73,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
73
const DEFAULT_REGION = 'us-east-1';
74
75
const SETTINGS_KEY = 'tantan_wordpress_s3';
76
77
/**
78
* @param string $plugin_file_path
@@ -97,17 +98,20 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
97
*/
98
function init( $plugin_file_path ) {
99
self::$plugin_page = $this->plugin_slug;
100
- $this->plugin_title = __( 'Offload S3', 'amazon-s3-and-cloudfront' );
101
$this->plugin_menu_title = __( 'S3 and CloudFront', 'amazon-s3-and-cloudfront' );
102
103
new AS3CF_Upgrade_Region_Meta( $this );
104
new AS3CF_Upgrade_File_Sizes( $this );
105
new AS3CF_Upgrade_Meta_WP_Error( $this );
106
107
// Plugin setup
108
add_action( 'aws_admin_menu', array( $this, 'admin_menu' ) );
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
// UI AJAX
113
add_action( 'wp_ajax_as3cf-get-buckets', array( $this, 'ajax_get_buckets' ) );
@@ -166,6 +170,34 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
166
return $this->get_plugin_prefix_slug() . '-save-settings';
167
}
168
169
/**
170
* Accessor for a plugin setting with conditions to defaults and upgrades
171
*
@@ -182,7 +214,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
182
$value = $_POST[ $key ]; // input var okay
183
if ( is_array( $value ) ) {
184
// checkbox is checked
185
- $value = 1;
186
}
187
}
188
@@ -218,48 +250,37 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
218
}
219
220
if ( isset( $settings['object-prefix'] ) && '' == trim( $settings['object-prefix'] ) ) {
221
- return 0;
222
} else {
223
return 1;
224
}
225
}
226
227
- // Region of bucket if not already retrieved
228
- if ( 'region' == $key && ! isset( $settings['region'] ) ) {
229
- $bucket = $this->get_setting( 'bucket' );
230
- $region = $default;
231
- if ( $bucket ) {
232
- $region = $this->get_bucket_region( $bucket );
233
- }
234
-
235
- // Store the region for future use
236
- parent::set_setting( 'region', $region );
237
- $this->save_settings();
238
-
239
return $region;
240
}
241
242
- // Region of bucket translation
243
- if ( 'region' == $key && isset( $settings['region'] ) ) {
244
-
245
- return $this->translate_region( $settings['region'] );
246
- }
247
-
248
// Domain setting since 0.8
249
- if ( 'domain' == $key && ! isset( $settings['domain'] ) ) {
250
if ( $this->get_setting( 'cloudfront' ) ) {
251
$domain = 'cloudfront';
252
} elseif ( $this->get_setting( 'virtual-host' ) ) {
253
- $domain = 'virtual-host';
254
- } elseif ( $this->use_ssl() ) {
255
- $domain = 'path';
256
} else {
257
- $domain = 'subdomain';
258
}
259
260
return $domain;
261
}
262
263
// SSL radio buttons since 0.8
264
if ( 'ssl' == $key && ! isset( $settings['ssl'] ) ) {
265
if ( $this->get_setting( 'force-ssl', false ) ) {
@@ -273,8 +294,60 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
273
274
$value = parent::get_setting( $key, $default );
275
276
- if ( 'bucket' == $key && defined( 'AS3CF_BUCKET' ) ) {
277
- $bucket = AS3CF_BUCKET;
278
279
if ( $bucket !== $value ) {
280
// Save the defined bucket
@@ -287,7 +360,67 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
287
return $bucket;
288
}
289
290
- return apply_filters( 'as3cf_setting_' . $key, $value );
291
}
292
293
/**
@@ -324,6 +457,50 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
324
return $domain;
325
}
326
327
/**
328
* Return the default object prefix
329
*
@@ -357,13 +534,19 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
357
* @param null|string $interval Defaults to hook if not supplied
358
* @param array $args
359
*/
360
- function schedule_event( $hook, $interval = null, $args = array() ) {
361
if ( is_null( $interval ) ) {
362
$interval = $hook;
363
}
364
if ( ! wp_next_scheduled( $hook ) ) {
365
wp_schedule_event( time(), $interval, $hook, $args );
366
}
367
}
368
369
/**
@@ -371,11 +554,23 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
371
*
372
* @param string $hook
373
*/
374
- function clear_scheduled_event( $hook ) {
375
$timestamp = wp_next_scheduled( $hook );
376
if ( $timestamp ) {
377
wp_unschedule_event( $timestamp, $hook );
378
}
379
}
380
381
/**
@@ -433,21 +628,28 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
433
* @param bool $return_on_error
434
* @param bool $force_new_s3_client if we are deleting in bulk, force new S3 client
435
* to cope with possible different regions
436
*/
437
function delete_s3_objects( $region, $bucket, $objects, $log_error = false, $return_on_error = false, $force_new_s3_client = false ) {
438
try {
439
- $this->get_s3client( $region, $force_new_s3_client )->deleteObjects( array(
440
- 'Bucket' => $bucket,
441
- 'Objects' => $objects,
442
- ) );
443
} catch ( Exception $e ) {
444
if ( $log_error ) {
445
- error_log( 'Error removing files from S3: ' . $e->getMessage() );
446
- }
447
- if ( $return_on_error ) {
448
- return;
449
}
450
}
451
}
452
453
/**
@@ -617,7 +819,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
617
$time = date( 'Y/m', $time );
618
}
619
620
- $prefix = $this->get_file_prefix( $time, $post_id );
621
622
// use bucket from settings
623
$bucket = $this->get_setting( 'bucket' );
@@ -644,17 +846,23 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
644
$s3client = $this->get_s3client( $region, $force_new_s3_client );
645
646
$args = array(
647
- 'Bucket' => $bucket,
648
- 'Key' => $prefix . $file_name,
649
- 'SourceFile' => $file_path,
650
- 'ACL' => $acl,
651
);
652
653
- // If far future expiration checked (10 years)
654
- if ( $this->get_setting( 'expires' ) ) {
655
- $args['CacheControl'] = 'max-age=315360000';
656
- $args['Expires'] = date( 'D, d M Y H:i:s O', time() + 315360000 );
657
}
658
$args = apply_filters( 'as3cf_object_meta', $args, $post_id );
659
660
do_action( 'as3cf_upload_attachment_pre_remove', $post_id, $s3object, $prefix, $args );
@@ -725,7 +933,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
725
$s3client->putObject( $args );
726
}
727
catch ( Exception $e ) {
728
- error_log( 'Error uploading ' . $args['SourceFile'] . ' to S3: ' . $e->getMessage() );
729
}
730
}
731
@@ -771,6 +979,51 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
771
return $s3object;
772
}
773
774
/**
775
* Helper to return meta data on upload error
776
*
@@ -784,7 +1037,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
784
return new WP_Error( 'exception', $error_msg );
785
}
786
787
- error_log( $error_msg );
788
789
return $return;
790
}
@@ -796,25 +1049,16 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
796
*/
797
function remove_local_files( $file_paths ) {
798
foreach ( $file_paths as $path ) {
799
if ( ! @unlink( $path ) ) {
800
- error_log( 'Error removing local file ' . $path );
801
}
802
}
803
}
804
805
- /**
806
- * Add HiDPi suffix to a file path
807
- *
808
- * @param string $orig_path
809
- *
810
- * @return string
811
- */
812
- function get_hidpi_file_path( $orig_path ) {
813
- $hidpi_suffix = apply_filters( 'as3cf_hidpi_suffix', '@2x' );
814
-
815
- return $this->apply_file_suffix( $orig_path, $hidpi_suffix );
816
- }
817
-
818
/**
819
* Helper to apply a suffix to a file path
820
*
@@ -832,18 +1076,17 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
832
/**
833
* Get the object versioning string prefix
834
*
835
- * @param int $post_id
836
- *
837
* @return string
838
*/
839
- function get_object_version_string( $post_id ) {
840
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
841
$date_format = 'dHis';
842
} else {
843
$date_format = 'YmdHis';
844
}
845
846
- $time = $this->get_attachment_folder_time( $post_id );
847
848
$object_version = date( $date_format, $time ) . '/';
849
$object_version = apply_filters( 'as3cf_get_object_version_string', $object_version );
@@ -1090,7 +1333,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1090
* @return mixed
1091
*/
1092
function get_attachment_s3_info( $post_id ) {
1093
- return get_post_meta( $post_id, 'amazonS3_info', true );
1094
}
1095
1096
/**
@@ -1199,16 +1442,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1199
* Get the file prefix
1200
*
1201
* @param null|string $time
1202
- * @param null|int $post_id
1203
*
1204
* @return string
1205
*/
1206
- function get_file_prefix( $time = null, $post_id = null ) {
1207
$prefix = ltrim( trailingslashit( $this->get_object_prefix() ), '/' );
1208
$prefix .= ltrim( trailingslashit( $this->get_dynamic_prefix( $time ) ), '/' );
1209
1210
if ( $this->get_setting( 'object-versioning' ) ) {
1211
- $prefix .= $this->get_object_version_string( $post_id );
1212
}
1213
1214
return $prefix;
@@ -1362,7 +1604,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1362
}
1363
}
1364
1365
- $file = $this->encode_filename_in_path( $s3object['key'] );
1366
$url = $scheme . '://' . $domain_bucket . '/' . $file;
1367
1368
return apply_filters( 'as3cf_get_attachment_url', $url, $s3object, $post_id, $expires, $headers );
@@ -1393,7 +1635,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1393
}
1394
1395
$img_src = $matches[1];
1396
- $encoded_src = $this->encode_filename_in_path( $img_src );
1397
1398
return str_replace( $img_src, $encoded_src, $html );
1399
}
@@ -1414,7 +1656,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1414
}
1415
1416
if ( isset( $image[0] ) ) {
1417
- $image[0] = $this->encode_filename_in_path( $image[0] );
1418
}
1419
1420
return $image;
@@ -1435,12 +1677,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1435
}
1436
1437
if ( isset( $response['url'] ) ) {
1438
- $response['url'] = $this->encode_filename_in_path( $response['url'] );
1439
}
1440
1441
if ( isset( $response['sizes'] ) && is_array( $response['sizes'] ) ) {
1442
foreach ( $response['sizes'] as $key => $value ) {
1443
- $response['sizes'][ $key ]['url'] = $this->encode_filename_in_path( $value['url'] );
1444
}
1445
}
1446
@@ -1462,7 +1704,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1462
}
1463
1464
if ( isset( $data['url'] ) ) {
1465
- $data['url'] = $this->encode_filename_in_path( $data['url'] );
1466
}
1467
1468
return $data;
@@ -1494,11 +1736,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1494
* Encode file names according to RFC 3986 when generating urls
1495
* As per Amazon https://forums.aws.amazon.com/thread.jspa?threadID=55746#jive-message-244233
1496
*
1497
- * @param string $file
1498
*
1499
* @return string Encoded filename with path prefix untouched
1500
*/
1501
- function encode_filename_in_path( $file ) {
1502
$url = parse_url( $file );
1503
1504
if ( ! isset( $url['path'] ) ) {
@@ -1506,7 +1749,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1506
return $file;
1507
}
1508
1509
- if ( in_array( $this->normalize_file_path( $url['path'] ), $this->encode_files ) ) {
1510
// Already encoded, return original
1511
return $file;
1512
}
@@ -1522,7 +1765,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1522
return $file;
1523
}
1524
1525
- $normalized_file_path = $this->normalize_file_path( $encoded_file_path );
1526
1527
if ( ! in_array( $normalized_file_path, $this->encode_files ) ) {
1528
$this->encode_files[] = $normalized_file_path;
@@ -1534,15 +1777,30 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1534
/**
1535
* Normalize file path
1536
*
1537
- * @param string $path
1538
*
1539
* @return string mixed
1540
*/
1541
- function normalize_file_path( $path ) {
1542
$url = parse_url( $path );
1543
1544
if ( isset( $url['scheme'] ) ) {
1545
$path = str_replace( $url['scheme'] . '://', '', $path );
1546
}
1547
1548
return '/' . ltrim( $path, '/' );
@@ -1902,7 +2160,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1902
} catch ( Exception $e ) {
1903
$error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'amazon-s3-and-cloudfront' ) . '</strong> &mdash;';
1904
$error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
1905
- error_log( $error_msg );
1906
1907
return new WP_Error( 'exception', $error_msg_title . $error_msg );
1908
}
@@ -2054,7 +2312,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2054
// if we encounter an error that isn't access denied, throw that error
2055
if ( ! $e instanceof Aws\Common\Exception\ServiceResponseException || 'AccessDenied' !== $e->getExceptionCode() ) {
2056
$error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2057
- error_log( $error_msg );
2058
2059
return new WP_Error( 'exception', $error_msg );
2060
}
@@ -2086,8 +2344,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2086
* Register modal scripts and styles so they can be enqueued later
2087
*/
2088
function register_modal_assets() {
2089
- $version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->plugin_version;
2090
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
2091
2092
$src = plugins_url( 'assets/css/modal.css', $this->plugin_file_path );
2093
wp_register_style( 'as3cf-modal', $src, array(), $version );
@@ -2097,8 +2355,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2097
}
2098
2099
function plugin_load() {
2100
- $version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->plugin_version;
2101
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
2102
2103
$src = plugins_url( 'assets/css/styles.css', $this->plugin_file_path );
2104
wp_enqueue_style( 'as3cf-styles', $src, array( 'as3cf-modal' ), $version );
@@ -2149,7 +2407,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2149
'region',
2150
'domain',
2151
'virtual-host',
2152
- 'expires',
2153
'permissions',
2154
'cloudfront',
2155
'object-prefix',
@@ -2157,7 +2414,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2157
'serve-from-s3',
2158
'remove-local-file',
2159
'ssl',
2160
- 'hidpi-images',
2161
'object-versioning',
2162
'use-yearmonth-folders',
2163
'enable-object-prefix',
@@ -2217,7 +2473,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2217
'page' => self::$plugin_page,
2218
);
2219
2220
- $args = array_merge( $args, $default_args );
2221
2222
switch ( $url_method ) {
2223
case 'self':
@@ -2288,7 +2544,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2288
}
2289
2290
/**
2291
- * Get the prefix path for the files
2292
*
2293
* @param string $time
2294
*
@@ -2296,9 +2553,50 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2296
*/
2297
function get_dynamic_prefix( $time = null ) {
2298
$prefix = '';
2299
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
2300
- $uploads = wp_upload_dir( $time );
2301
- $prefix = str_replace( $this->get_base_upload_path(), '', $uploads['path'] );
2302
}
2303
2304
// support legacy MS installs (<3.5 since upgraded) for subsites
@@ -2306,33 +2604,38 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2306
$details = get_blog_details( get_current_blog_id() );
2307
$legacy_ms_prefix = 'sites/' . $details->blog_id . '/';
2308
$legacy_ms_prefix = apply_filters( 'as3cf_legacy_ms_subsite_prefix', $legacy_ms_prefix, $details );
2309
- $prefix = '/' . trailingslashit( ltrim( $legacy_ms_prefix, '/' ) ) . ltrim( $prefix, '/' );
2310
}
2311
2312
return $prefix;
2313
}
2314
2315
/**
2316
- * Get the base upload path
2317
- * without the multisite subdirectory
2318
*
2319
* @return string
2320
*/
2321
- function get_base_upload_path() {
2322
- if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
2323
- return ABSPATH . UPLOADS;
2324
}
2325
2326
- $upload_path = trim( get_option( 'upload_path' ) );
2327
2328
- if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
2329
- return WP_CONTENT_DIR . '/uploads';
2330
- } elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
2331
- // $dir is absolute, $upload_path is (maybe) relative to ABSPATH
2332
- return path_join( ABSPATH, $upload_path );
2333
- } else {
2334
- return $upload_path;
2335
}
2336
}
2337
2338
/**
@@ -2392,9 +2695,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2392
* @param int $post_id
2393
* @param array $s3object
2394
* @param string $acl
2395
*/
2396
function set_attachment_acl_on_s3( $post_id, $s3object, $acl ) {
2397
- // set ACL as private
2398
$args = array(
2399
'ACL' => $acl,
2400
'Bucket' => $s3object['bucket'],
@@ -2408,49 +2717,84 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2408
$s3client->PutObjectAcl( $args );
2409
$s3object['acl'] = $acl;
2410
2411
- // Add attachment to ACL update notice
2412
- $message = $this->make_acl_admin_notice_text( $s3object );
2413
- $this->notices->add_notice( $message );
2414
-
2415
// update S3 meta data
2416
if ( $acl == self::DEFAULT_ACL ) {
2417
unset( $s3object['acl'] );
2418
}
2419
update_post_meta( $post_id, 'amazonS3_info', $s3object );
2420
} catch ( Exception $e ) {
2421
- error_log( 'Error setting ACL to ' . $acl . ' for ' . $s3object['key'] . ': ' . $e->getMessage() );
2422
}
2423
}
2424
2425
/**
2426
- * Make admin notice text for when object ACL has changed
2427
*
2428
* @param array $s3object
2429
- *
2430
- * @return string
2431
*/
2432
- function make_acl_admin_notice_text( $s3object ) {
2433
$filename = basename( $s3object['key'] );
2434
- $acl = $this->get_acl_display_name( $s3object['acl'] );
2435
2436
- return sprintf( __( 'The file %s has been given %s permissions on Amazon S3.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl}</strong>" );
2437
}
2438
2439
/**
2440
* Check if PHP GD and Imagick is installed
2441
*/
2442
function check_for_gd_imagick() {
2443
$gd_enabled = $this->gd_enabled();
2444
$imagick_enabled = $this->imagick_enabled();
2445
2446
if( ! $gd_enabled && ! $imagick_enabled ) {
2447
$this->notices->add_notice(
2448
- __( '<strong>Image Manipulation Library Missing</strong> &mdash; Looks like you don\'t have an image manipulation library installed on this server and configured with PHP. You may run into trouble if you try to edit images. Please setup GD or ImageMagick.', 'amazon-s3-and-cloudfront' ),
2449
array( 'flash' => false, 'only_show_to_user' => false, 'only_show_in_settings' => true )
2450
);
2451
}
2452
}
2453
2454
/**
2455
* Diagnostic information for the support tab
2456
*
@@ -2480,6 +2824,9 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2480
echo bloginfo( 'version' );
2481
if ( is_multisite() ) {
2482
echo ' Multisite';
2483
}
2484
echo "\r\n";
2485
@@ -2494,7 +2841,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2494
echo "\r\n";
2495
2496
echo 'MySQL: ';
2497
- echo esc_html( empty( $wpdb->use_mysqli ) ? mysql_get_server_info() : mysqli_get_server_info( $wpdb->dbh ) );
2498
echo "\r\n";
2499
2500
echo 'ext/mysqli: ';
@@ -2529,10 +2876,26 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2529
echo esc_html( get_locale() );
2530
echo "\r\n";
2531
2532
- echo 'Debug Mode: ';
2533
echo esc_html( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No' );
2534
echo "\r\n";
2535
2536
echo 'WP Max Upload Size: ';
2537
echo esc_html( size_format( wp_max_upload_size() ) );
2538
echo "\r\n";
@@ -2617,6 +2980,48 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2617
echo number_format_i18n( $sizes );
2618
echo "\r\n\r\n";
2619
2620
echo 'Bucket: ';
2621
echo $this->get_setting( 'bucket' );
2622
echo "\r\n";
@@ -2659,12 +3064,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2659
echo "\r\n";
2660
echo 'Object Versioning: ';
2661
echo $this->on_off( 'object-versioning' );
2662
- echo "\r\n";
2663
- echo 'Far Future Expiration Header: ';
2664
- echo $this->on_off( 'expires' );
2665
- echo "\r\n";
2666
- echo 'Copy HiDPI (@2x) Images: ';
2667
- echo $this->on_off( 'hidpi-images' );
2668
echo "\r\n\r\n";
2669
2670
do_action( 'as3cf_diagnostic_info' );
@@ -2672,6 +3071,18 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2672
echo "\r\n";
2673
}
2674
2675
echo "Active Plugins:\r\n";
2676
$active_plugins = (array) get_option( 'active_plugins', array() );
2677
$plugin_details = array();
@@ -2777,6 +3188,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2777
* @return string
2778
*/
2779
function get_acl_display_name( $acl ) {
2780
return ucwords( str_replace( '-', ' ', $acl ) );
2781
}
2782
@@ -2841,23 +3254,27 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2841
* - If the site is MS
2842
* - If the blog is not the current blog defined
2843
*
2844
- * @param $blog_id
2845
*/
2846
- function switch_to_blog( $blog_id ) {
2847
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
2848
switch_to_blog( $blog_id );
2849
}
2850
}
2851
2852
/**
2853
* Helper to restore to the current Multisite blog
2854
- * - If the site is MS
2855
- * - If the blog is not the current blog defined
2856
- *
2857
- * @param $blog_id
2858
*/
2859
- function restore_current_blog( $blog_id ) {
2860
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
2861
restore_current_blog();
2862
}
2863
}
@@ -2942,13 +3359,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2942
}
2943
}
2944
2945
- // HiDPI
2946
- if ( $this->get_setting( 'hidpi-images' ) ) {
2947
- foreach ( $paths as $path ) {
2948
- $paths[] = $this->get_hidpi_file_path( $path );
2949
- }
2950
- }
2951
-
2952
// Allow other processes to add files to be uploaded
2953
$paths = apply_filters( 'as3cf_attachment_file_paths', $paths, $attachment_id, $meta );
2954
@@ -2975,7 +3385,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2975
* @return string
2976
*/
2977
function get_access_denied_notice_message( $single = true ) {
2978
- $quick_start = sprintf( '<a class="js-link" href="%s">%s</a>', 'https://deliciousbrains.com/wp-offload-s3/doc/quick-start-guide/', __( 'Quick Start Guide', 'amazon-s3-and-cloudfront' ) );
2979
2980
$message = sprintf( __( "Looks like we don't have write access to this bucket. It's likely that the user you've provided access keys for hasn't been granted the correct permissions. Please see our %s for instructions on setting up permissions correctly.", 'amazon-s3-and-cloudfront' ), $quick_start );
2981
if ( ! $single ) {
@@ -3123,4 +3533,155 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
3123
3124
return $attachment_counts;
3125
}
3126
}
73
const DEFAULT_REGION = 'us-east-1';
74
75
const SETTINGS_KEY = 'tantan_wordpress_s3';
76
+ const SETTINGS_CONSTANT = 'WPOS3_SETTINGS';
77
78
/**
79
* @param string $plugin_file_path
98
*/
99
function init( $plugin_file_path ) {
100
self::$plugin_page = $this->plugin_slug;
101
+ $this->plugin_title = __( 'Offload S3 Lite', 'amazon-s3-and-cloudfront' );
102
$this->plugin_menu_title = __( 'S3 and CloudFront', 'amazon-s3-and-cloudfront' );
103
104
new AS3CF_Upgrade_Region_Meta( $this );
105
new AS3CF_Upgrade_File_Sizes( $this );
106
new AS3CF_Upgrade_Meta_WP_Error( $this );
107
+ $this->maybe_display_deprecated_retina_notice();
108
109
// Plugin setup
110
add_action( 'aws_admin_menu', array( $this, 'admin_menu' ) );
111
add_filter( 'plugin_action_links', array( $this, 'plugin_actions_settings_link' ), 10, 2 );
112
add_filter( 'pre_get_space_used', array( $this, 'multisite_get_spaced_used' ) );
113
+ // display a notice when either lite or pro is automatically deactivated
114
+ add_action( 'pre_current_active_plugins', array( $this, 'plugin_deactivated_notice' ) );
115
116
// UI AJAX
117
add_action( 'wp_ajax_as3cf-get-buckets', array( $this, 'ajax_get_buckets' ) );
170
return $this->get_plugin_prefix_slug() . '-save-settings';
171
}
172
173
+ /**
174
+ * Gets arguements used to render a setting view.
175
+ *
176
+ * @param string $key
177
+ *
178
+ * @return array
179
+ */
180
+ function get_setting_args( $key ) {
181
+ $is_defined = $this->get_defined_setting( $key, false );
182
+
183
+ $args = array(
184
+ 'key' => $key,
185
+ 'disabled' => false,
186
+ 'disabled_attr' => '',
187
+ 'tr_class' => '',
188
+ 'setting_msg' => '',
189
+ );
190
+
191
+ if ( false !== $is_defined ) {
192
+ $args['disabled'] = true;
193
+ $args['disabled_attr'] = 'disabled="disabled"';
194
+ $args['tr_class'] = 'as3cf-defined-setting';
195
+ $args['setting_msg'] = '<span class="as3cf-defined-in-config">' . __( 'defined in wp-config.php', 'as3cf' ) . '</span>';
196
+ }
197
+
198
+ return $args;
199
+ }
200
+
201
/**
202
* Accessor for a plugin setting with conditions to defaults and upgrades
203
*
214
$value = $_POST[ $key ]; // input var okay
215
if ( is_array( $value ) ) {
216
// checkbox is checked
217
+ $value = $value[1];
218
}
219
}
220
250
}
251
252
if ( isset( $settings['object-prefix'] ) && '' == trim( $settings['object-prefix'] ) ) {
253
+ if ( false === $this->get_defined_setting( 'object-prefix', false ) ) {
254
+ return 0;
255
+ }
256
} else {
257
return 1;
258
}
259
}
260
261
+ // Region
262
+ if ( false !== ( $region = $this->get_setting_region( $settings, $key, $default ) ) ) {
263
return $region;
264
}
265
266
// Domain setting since 0.8
267
+ if ( 'domain' === $key && ! isset( $settings['domain'] ) ) {
268
if ( $this->get_setting( 'cloudfront' ) ) {
269
$domain = 'cloudfront';
270
} elseif ( $this->get_setting( 'virtual-host' ) ) {
271
+ $domain = $this->upgrade_virtual_host();
272
} else {
273
+ $domain = 'path';
274
}
275
276
return $domain;
277
}
278
279
+ // 1.1 Update 'Bucket as Domain' to new CloudFront/Domain UI
280
+ if ( 'domain' === $key && 'virtual-host' === $settings[ $key ] ) {
281
+ return $this->upgrade_virtual_host();
282
+ }
283
+
284
// SSL radio buttons since 0.8
285
if ( 'ssl' == $key && ! isset( $settings['ssl'] ) ) {
286
if ( $this->get_setting( 'force-ssl', false ) ) {
294
295
$value = parent::get_setting( $key, $default );
296
297
+ // Bucket
298
+ if ( false !== ( $bucket = $this->get_setting_bucket( $key, $value ) ) ) {
299
+ return $bucket;
300
+ }
301
+
302
+ return apply_filters( 'as3cf_setting_' . $key, $value );
303
+ }
304
+
305
+ /**
306
+ * Get the region setting
307
+ *
308
+ * @param array $settings
309
+ * @param string $key
310
+ * @param mixed $default
311
+ *
312
+ * @return bool|string|WP_Error
313
+ */
314
+ public function get_setting_region( $settings, $key, $default ) {
315
+ // Region of bucket if not already retrieved
316
+ if ( 'region' === $key && ! isset( $settings['region'] ) ) {
317
+ $bucket = $this->get_setting( 'bucket' );
318
+ $region = $default;
319
+ if ( $bucket ) {
320
+ $region = $this->get_bucket_region( $bucket );
321
+ }
322
+
323
+ // Store the region for future use
324
+ parent::set_setting( 'region', $region );
325
+ $this->save_settings();
326
+
327
+ return $region;
328
+ }
329
+
330
+ // Region of bucket translation
331
+ if ( 'region' === $key && isset( $settings['region'] ) ) {
332
+
333
+ return $this->translate_region( $settings['region'] );
334
+ }
335
+
336
+ return false;
337
+ }
338
+
339
+ /**
340
+ * Get the bucket and if a constant save to database and clear region
341
+ *
342
+ * @param string $key
343
+ * @param string $value
344
+ * @param string $constant
345
+ *
346
+ * @return string|false
347
+ */
348
+ public function get_setting_bucket( $key, $value, $constant = 'AS3CF_BUCKET' ) {
349
+ if ( 'bucket' === $key && defined( $constant ) ) {
350
+ $bucket = constant( $constant );
351
352
if ( $bucket !== $value ) {
353
// Save the defined bucket
360
return $bucket;
361
}
362
363
+ return false;
364
+ }
365
+
366
+ /**
367
+ * Filter in defined settings with sensible defaults.
368
+ *
369
+ * @param array $settings
370
+ *
371
+ * @return array $settings
372
+ */
373
+ function filter_settings( $settings ) {
374
+ $defined_settings = $this->get_defined_settings();
375
+
376
+ // Bail early if there are no defined settings
377
+ if ( empty( $defined_settings ) ) {
378
+ return $settings;
379
+ }
380
+
381
+ foreach ( $defined_settings as $key => $value ) {
382
+ $allowed_values = array();
383
+
384
+ if ( 'domain' === $key ) {
385
+ $allowed_values = array(
386
+ 'subdomain',
387
+ 'path',
388
+ 'virtual-host',
389
+ 'cloudfront',
390
+ );
391
+ }
392
+
393
+ if ( 'ssl' === $key ) {
394
+ $allowed_values = array(
395
+ 'request',
396
+ 'https',
397
+ 'http',
398
+ );
399
+ }
400
+
401
+ $checkboxes = array(
402
+ 'copy-to-s3',
403
+ 'serve-from-s3',
404
+ 'enable-object-prefix',
405
+ 'remove-local-file',
406
+ 'object-versioning',
407
+ );
408
+
409
+ if ( in_array( $key, $checkboxes ) ) {
410
+ $allowed_values = array( '0', '1' );
411
+ }
412
+
413
+ // Unexpected value, remove from defined_settings array.
414
+ if ( ! empty( $allowed_values ) && ! in_array( $value, $allowed_values ) ) {
415
+ $this->remove_defined_setting( $key );
416
+ continue;
417
+ }
418
+
419
+ // Value defined successfully
420
+ $settings[ $key ] = $value;
421
+ }
422
+
423
+ return $settings;
424
}
425
426
/**
457
return $domain;
458
}
459
460
+ /**
461
+ * Disables the save button if all settings have been defined.
462
+ *
463
+ * @param string $defined_settings
464
+ *
465
+ * @return string
466
+ */
467
+ function maybe_disable_save_button( $defined_settings = array() ) {
468
+ $attr = 'disabled="disabled"';
469
+ $defined_settings = ! empty( $defined_settings ) ? $defined_settings : $this->get_defined_settings();
470
+ $whitelisted_settings = $this->get_settings_whitelist();
471
+ $settings_to_skip = array(
472
+ 'bucket',
473
+ 'region',
474
+ 'permissions',
475
+ 'virtual-host',
476
+ );
477
+
478
+ foreach ( $whitelisted_settings as $setting ) {
479
+ if ( in_array( $setting, $settings_to_skip ) ) {
480
+ continue;
481
+ }
482
+
483
+ if ( 'object-prefix' === $setting ) {
484
+ if ( isset( $defined_settings['enable-object-prefix'] ) && '0' === $defined_settings['enable-object-prefix'] ) {
485
+ continue;
486
+ }
487
+ }
488
+
489
+ if ( 'cloudfront' === $setting ) {
490
+ if ( isset( $defined_settings['domain'] ) && 'cloudfront' !== $defined_settings['domain'] ) {
491
+ continue;
492
+ }
493
+ }
494
+
495
+ if ( ! isset( $defined_settings[ $setting ] ) ) {
496
+ // If we're here, there's a setting that hasn't been defined.
497
+ return '';
498
+ }
499
+ }
500
+
501
+ return $attr;
502
+ }
503
+
504
/**
505
* Return the default object prefix
506
*
534
* @param null|string $interval Defaults to hook if not supplied
535
* @param array $args
536
*/
537
+ public function schedule_event( $hook, $interval = null, $args = array() ) {
538
if ( is_null( $interval ) ) {
539
$interval = $hook;
540
}
541
+
542
+ // Always schedule events on primary blog
543
+ $this->switch_to_blog();
544
+
545
if ( ! wp_next_scheduled( $hook ) ) {
546
wp_schedule_event( time(), $interval, $hook, $args );
547
}
548
+
549
+ $this->restore_current_blog();
550
}
551
552
/**
554
*
555
* @param string $hook
556
*/
557
+ public function clear_scheduled_event( $hook ) {
558
$timestamp = wp_next_scheduled( $hook );
559
if ( $timestamp ) {
560
wp_unschedule_event( $timestamp, $hook );
561
}
562
+
563
+ if ( is_multisite() ) {
564
+ // Always clear schedule events on primary blog
565
+ $this->switch_to_blog();
566
+
567
+ $timestamp = wp_next_scheduled( $hook );
568
+ if ( $timestamp ) {
569
+ wp_unschedule_event( $timestamp, $hook );
570
+ }
571
+
572
+ $this->restore_current_blog();
573
+ }
574
}
575
576
/**
628
* @param bool $return_on_error
629
* @param bool $force_new_s3_client if we are deleting in bulk, force new S3 client
630
* to cope with possible different regions
631
+ *
632
+ * @return bool
633
*/
634
function delete_s3_objects( $region, $bucket, $objects, $log_error = false, $return_on_error = false, $force_new_s3_client = false ) {
635
+ $chunks = array_chunk( $objects, 1000 );
636
+
637
try {
638
+ foreach ( $chunks as $chunk ) {
639
+ $this->get_s3client( $region, $force_new_s3_client )->deleteObjects( array(
640
+ 'Bucket' => $bucket,
641
+ 'Objects' => $chunk,
642
+ ) );
643
+ }
644
} catch ( Exception $e ) {
645
if ( $log_error ) {
646
+ AS3CF_Error::log( 'Error removing files from S3: ' . $e->getMessage() );
647
}
648
+
649
+ return false;
650
}
651
+
652
+ return true;
653
}
654
655
/**
819
$time = date( 'Y/m', $time );
820
}
821
822
+ $prefix = $this->get_file_prefix( $time );
823
824
// use bucket from settings
825
$bucket = $this->get_setting( 'bucket' );
846
$s3client = $this->get_s3client( $region, $force_new_s3_client );
847
848
$args = array(
849
+ 'Bucket' => $bucket,
850
+ 'Key' => $prefix . $file_name,
851
+ 'SourceFile' => $file_path,
852
+ 'ACL' => $acl,
853
+ 'ContentType' => $type,
854
+ 'CacheControl' => 'max-age=31536000',
855
+ 'Expires' => date( 'D, d M Y H:i:s O', time() + 31536000 ),
856
);
857
858
+ // Handle gzip on supported items
859
+ if ( $this->should_gzip_file( $file_path, $type ) && false !== ( $gzip_body = gzencode( file_get_contents( $file_path ) ) ) ) {
860
+ unset( $args['SourceFile'] );
861
+
862
+ $args['Body'] = $gzip_body;
863
+ $args['ContentEncoding'] = 'gzip';
864
}
865
+
866
$args = apply_filters( 'as3cf_object_meta', $args, $post_id );
867
868
do_action( 'as3cf_upload_attachment_pre_remove', $post_id, $s3object, $prefix, $args );
933
$s3client->putObject( $args );
934
}
935
catch ( Exception $e ) {
936
+ AS3CF_Error::log( 'Error uploading ' . $args['SourceFile'] . ' to S3: ' . $e->getMessage() );
937
}
938
}
939
979
return $s3object;
980
}
981
982
+ /**
983
+ * Should gzip file
984
+ *
985
+ * @param string $file_path
986
+ * @param string $type
987
+ *
988
+ * @return bool
989
+ */
990
+ protected function should_gzip_file( $file_path, $type ) {
991
+ $mimes = $this->get_mime_types_to_gzip( true );
992
+
993
+ if ( in_array( $type, $mimes ) && is_readable( $file_path ) ) {
994
+ return true;
995
+ }
996
+
997
+ return false;
998
+ }
999
+
1000
+ /**
1001
+ * Get mime types to gzip
1002
+ *
1003
+ * @param bool $media_library
1004
+ *
1005
+ * @return array
1006
+ */
1007
+ protected function get_mime_types_to_gzip( $media_library = false ) {
1008
+ $mimes = apply_filters( 'as3cf_gzip_mime_types', array(
1009
+ 'css' => 'text/css',
1010
+ 'eot' => 'application/vnd.ms-fontobject',
1011
+ 'html' => 'text/html',
1012
+ 'ico' => 'image/x-icon',
1013
+ 'js' => 'application/javascript',
1014
+ 'json' => 'application/json',
1015
+ 'otf' => 'application/x-font-opentype',
1016
+ 'rss' => 'application/rss+xml',
1017
+ 'svg' => 'image/svg+xml',
1018
+ 'ttf' => 'application/x-font-ttf',
1019
+ 'woff' => 'application/font-woff',
1020
+ 'woff2' => 'application/font-woff2',
1021
+ 'xml' => 'application/xml',
1022
+ ), $media_library );
1023
+
1024
+ return $mimes;
1025
+ }
1026
+
1027
/**
1028
* Helper to return meta data on upload error
1029
*
1037
return new WP_Error( 'exception', $error_msg );
1038
}
1039
1040
+ AS3CF_Error::log( $error_msg );
1041
1042
return $return;
1043
}
1049
*/
1050
function remove_local_files( $file_paths ) {
1051
foreach ( $file_paths as $path ) {
1052
+ if ( false !== ( $pre = apply_filters( 'as3cf_preserve_file_from_local_removal', false, $path ) ) ) {
1053
+ continue;
1054
+ }
1055
+
1056
if ( ! @unlink( $path ) ) {
1057
+ AS3CF_Error::log( 'Error removing local file ' . $path );
1058
}
1059
}
1060
}
1061
1062
/**
1063
* Helper to apply a suffix to a file path
1064
*
1076
/**
1077
* Get the object versioning string prefix
1078
*
1079
* @return string
1080
*/
1081
+ function get_object_version_string() {
1082
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
1083
$date_format = 'dHis';
1084
} else {
1085
$date_format = 'YmdHis';
1086
}
1087
1088
+ // Use current time so that object version is unique
1089
+ $time = current_time( 'timestamp' );
1090
1091
$object_version = date( $date_format, $time ) . '/';
1092
$object_version = apply_filters( 'as3cf_get_object_version_string', $object_version );
1333
* @return mixed
1334
*/
1335
function get_attachment_s3_info( $post_id ) {
1336
+ return apply_filters( 'as3cf_get_attachment_s3_info', get_post_meta( $post_id, 'amazonS3_info', true ), $post_id );
1337
}
1338
1339
/**
1442
* Get the file prefix
1443
*
1444
* @param null|string $time
1445
*
1446
* @return string
1447
*/
1448
+ function get_file_prefix( $time = null ) {
1449
$prefix = ltrim( trailingslashit( $this->get_object_prefix() ), '/' );
1450
$prefix .= ltrim( trailingslashit( $this->get_dynamic_prefix( $time ) ), '/' );
1451
1452
if ( $this->get_setting( 'object-versioning' ) ) {
1453
+ $prefix .= $this->get_object_version_string();
1454
}
1455
1456
return $prefix;
1604
}
1605
}
1606
1607
+ $file = $this->encode_filename_in_path( $s3object['key'], $post_id );
1608
$url = $scheme . '://' . $domain_bucket . '/' . $file;
1609
1610
return apply_filters( 'as3cf_get_attachment_url', $url, $s3object, $post_id, $expires, $headers );
1635
}
1636
1637
$img_src = $matches[1];
1638
+ $encoded_src = $this->encode_filename_in_path( $img_src, $id );
1639
1640
return str_replace( $img_src, $encoded_src, $html );
1641
}
1656
}
1657
1658
if ( isset( $image[0] ) ) {
1659
+ $image[0] = $this->encode_filename_in_path( $image[0], $attachment_id );
1660
}
1661
1662
return $image;
1677
}
1678
1679
if ( isset( $response['url'] ) ) {
1680
+ $response['url'] = $this->encode_filename_in_path( $response['url'], $attachment->ID );
1681
}
1682
1683
if ( isset( $response['sizes'] ) && is_array( $response['sizes'] ) ) {
1684
foreach ( $response['sizes'] as $key => $value ) {
1685
+ $response['sizes'][ $key ]['url'] = $this->encode_filename_in_path( $value['url'], $attachment->ID );
1686
}
1687
}
1688
1704
}
1705
1706
if ( isset( $data['url'] ) ) {
1707
+ $data['url'] = $this->encode_filename_in_path( $data['url'], $post_id );
1708
}
1709
1710
return $data;
1736
* Encode file names according to RFC 3986 when generating urls
1737
* As per Amazon https://forums.aws.amazon.com/thread.jspa?threadID=55746#jive-message-244233
1738
*
1739
+ * @param string $file
1740
+ * @param null|int $attachment_id
1741
*
1742
* @return string Encoded filename with path prefix untouched
1743
*/
1744
+ function encode_filename_in_path( $file, $attachment_id = null ) {
1745
$url = parse_url( $file );
1746
1747
if ( ! isset( $url['path'] ) ) {
1749
return $file;
1750
}
1751
1752
+ if ( in_array( $this->normalize_file_path( $url['path'], $attachment_id ), $this->encode_files ) ) {
1753
// Already encoded, return original
1754
return $file;
1755
}
1765
return $file;
1766
}
1767
1768
+ $normalized_file_path = $this->normalize_file_path( $encoded_file_path, $attachment_id );
1769
1770
if ( ! in_array( $normalized_file_path, $this->encode_files ) ) {
1771
$this->encode_files[] = $normalized_file_path;
1777
/**
1778
* Normalize file path
1779
*
1780
+ * @param string $path
1781
+ * @param null|int $attachment_id
1782
*
1783
* @return string mixed
1784
*/
1785
+ public function normalize_file_path( $path, $attachment_id = null ) {
1786
$url = parse_url( $path );
1787
1788
if ( isset( $url['scheme'] ) ) {
1789
$path = str_replace( $url['scheme'] . '://', '', $path );
1790
+ } else {
1791
+ $path = ltrim( $path, '/' );
1792
+
1793
+ if ( ! is_null( $attachment_id ) ) {
1794
+ // Attempt to remove bucket from path using amazonS3_info key
1795
+ $s3info = $this->get_attachment_s3_info( $attachment_id );
1796
+ $bucket = $s3info['bucket'];
1797
+ } else {
1798
+ // Attempt to remove bucket from path using tantan key
1799
+ $bucket = $this->get_setting( 'bucket' );
1800
+ }
1801
+
1802
+ $preg = '/^' . preg_quote( $bucket ) . '/';
1803
+ $path = preg_replace( $preg, '', $path );
1804
}
1805
1806
return '/' . ltrim( $path, '/' );
2160
} catch ( Exception $e ) {
2161
$error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'amazon-s3-and-cloudfront' ) . '</strong> &mdash;';
2162
$error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2163
+ AS3CF_Error::log( $error_msg );
2164
2165
return new WP_Error( 'exception', $error_msg_title . $error_msg );
2166
}
2312
// if we encounter an error that isn't access denied, throw that error
2313
if ( ! $e instanceof Aws\Common\Exception\ServiceResponseException || 'AccessDenied' !== $e->getExceptionCode() ) {
2314
$error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2315
+ AS3CF_Error::log( $error_msg );
2316
2317
return new WP_Error( 'exception', $error_msg );
2318
}
2344
* Register modal scripts and styles so they can be enqueued later
2345
*/
2346
function register_modal_assets() {
2347
+ $version = $this->get_asset_version();
2348
+ $suffix = $this->get_asset_suffix();
2349
2350
$src = plugins_url( 'assets/css/modal.css', $this->plugin_file_path );
2351
wp_register_style( 'as3cf-modal', $src, array(), $version );
2355
}
2356
2357
function plugin_load() {
2358
+ $version = $this->get_asset_version();
2359
+ $suffix = $this->get_asset_suffix();
2360
2361
$src = plugins_url( 'assets/css/styles.css', $this->plugin_file_path );
2362
wp_enqueue_style( 'as3cf-styles', $src, array( 'as3cf-modal' ), $version );
2407
'region',
2408
'domain',
2409
'virtual-host',
2410
'permissions',
2411
'cloudfront',
2412
'object-prefix',
2414
'serve-from-s3',
2415
'remove-local-file',
2416
'ssl',
2417
'object-versioning',
2418
'use-yearmonth-folders',
2419
'enable-object-prefix',
2473
'page' => self::$plugin_page,
2474
);
2475
2476
+ $args = array_merge( $default_args, $args );
2477
2478
switch ( $url_method ) {
2479
case 'self':
2544
}
2545
2546
/**
2547
+ * Get the prefix path for the files. Ignores WP media library
2548
+ * year month subdirectory setting and just uses S3 setting
2549
*
2550
* @param string $time
2551
*
2553
*/
2554
function get_dynamic_prefix( $time = null ) {
2555
$prefix = '';
2556
+ $subdir = '';
2557
+
2558
+ // If multisite (and if not the main site in a post-MU network)
2559
+ if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
2560
+ if ( ! get_site_option( 'ms_files_rewriting' ) ) {
2561
+ /*
2562
+ * If ms-files rewriting is disabled (networks created post-3.5), it is fairly
2563
+ * straightforward: Append sites/%d if we're not on the main site (for post-MU
2564
+ * networks). (The extra directory prevents a four-digit ID from conflicting with
2565
+ * a year-based directory for the main site. But if a MU-era network has disabled
2566
+ * ms-files rewriting manually, they don't need the extra directory, as they never
2567
+ * had wp-content/uploads for the main site.)
2568
+ */
2569
+
2570
+ if ( defined( 'MULTISITE' ) ) {
2571
+ $prefix = '/sites/' . get_current_blog_id();
2572
+ } else {
2573
+ $prefix = '/' . get_current_blog_id();
2574
+ }
2575
+ } elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) {
2576
+ /*
2577
+ * Handle the old-form ms-files.php rewriting if the network still has that enabled.
2578
+ * When ms-files rewriting is enabled, then we only listen to UPLOADS when:
2579