WP Offload S3 Lite - Version 1.0.1

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.1
Comparing to
See all releases

Code changes from version 0.9.12 to 1.0.1

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.12
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.12 - 2016-02-03 ###
77
* Improvement: Compatibility with WP Offload S3 Assets 1.1
78
* Bug fix: Object versioned responsive images in post content not working when served from S3 on WordPress 4.4+
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.1
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.1 - 2016-03-08 ###
77
+ * Bug fix: Fatal error on plugin activation
78
+ * Bug fix: Unable to activate Pro upgrade
79
+
80
+ ### WP Offload S3 Lite 1.0 - 2016-03-07 ###
81
+ * New: Plugin renamed to "WP Offload S3 Lite"
82
+ * New: Define any and all settings with a constant in wp-config.php
83
+ * New: Documentation links for each setting
84
+ * Improvement: Simplified domain setting UI
85
+ * Improvement: Far future expiration header set by default
86
+ * Improvement: Newly created bucket now immediately appears in the bucket list
87
+ * Improvement: Cleanup user meta on uninstall
88
+ * Improvement: WP Retina 2x integration [removed](https://deliciousbrains.com/wp-offload-s3/doc/copy-hidpi-2x-images-support/)
89
+ * 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
90
+ * Bug fix: Responsive srcset PHP notices
91
+ * Bug fix: Compatibility addon notices displayed to non-admin users
92
+ * Bug fix: Potential PHP fatal error in MySQL version check in diagnostic log
93
+ * Bug fix: Missing image library notices displaying before plugin is setup
94
+
95
### WP Offload S3 0.9.12 - 2016-02-03 ###
96
* Improvement: Compatibility with WP Offload S3 Assets 1.1
97
* Bug fix: Object versioned responsive images in post content not working when served from S3 on WordPress 4.4+
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}.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}
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
@@ -6,17 +6,17 @@
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
} );
@@ -34,4 +34,4 @@
34
$link.closest( '.as3cf-notice' ).find( '.as3cf-notice-toggle-content' ).toggle();
35
} );
36
37
- })( jQuery );
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
} );
34
$link.closest( '.as3cf-notice' ).find( '.as3cf-notice-toggle-content' ).toggle();
35
} );
36
37
+ })( 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
/**
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
/**
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
*
@@ -361,9 +538,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
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
/**
@@ -376,6 +559,18 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
376
if ( $timestamp ) {
377
wp_unschedule_event( $timestamp, $hook );
378
}
379
}
380
381
/**
@@ -448,7 +643,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
448
}
449
} catch ( Exception $e ) {
450
if ( $log_error ) {
451
- error_log( 'Error removing files from S3: ' . $e->getMessage() );
452
}
453
454
return false;
@@ -624,7 +819,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
624
$time = date( 'Y/m', $time );
625
}
626
627
- $prefix = $this->get_file_prefix( $time, $post_id );
628
629
// use bucket from settings
630
$bucket = $this->get_setting( 'bucket' );
@@ -651,19 +846,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
651
$s3client = $this->get_s3client( $region, $force_new_s3_client );
652
653
$args = array(
654
- 'Bucket' => $bucket,
655
- 'Key' => $prefix . $file_name,
656
- 'SourceFile' => $file_path,
657
- 'ACL' => $acl,
658
- 'ContentType' => $type,
659
);
660
661
- // If far future expiration checked (10 years)
662
- if ( $this->get_setting( 'expires' ) ) {
663
- $args['CacheControl'] = 'max-age=315360000';
664
- $args['Expires'] = date( 'D, d M Y H:i:s O', time() + 315360000 );
665
- }
666
-
667
// Handle gzip on supported items
668
if ( $this->should_gzip_file( $file_path, $type ) && false !== ( $gzip_body = gzencode( file_get_contents( $file_path ) ) ) ) {
669
unset( $args['SourceFile'] );
@@ -671,6 +862,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
671
$args['Body'] = $gzip_body;
672
$args['ContentEncoding'] = 'gzip';
673
}
674
$args = apply_filters( 'as3cf_object_meta', $args, $post_id );
675
676
do_action( 'as3cf_upload_attachment_pre_remove', $post_id, $s3object, $prefix, $args );
@@ -741,7 +933,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
741
$s3client->putObject( $args );
742
}
743
catch ( Exception $e ) {
744
- error_log( 'Error uploading ' . $args['SourceFile'] . ' to S3: ' . $e->getMessage() );
745
}
746
}
747
@@ -845,7 +1037,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
845
return new WP_Error( 'exception', $error_msg );
846
}
847
848
- error_log( $error_msg );
849
850
return $return;
851
}
@@ -857,25 +1049,16 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
857
*/
858
function remove_local_files( $file_paths ) {
859
foreach ( $file_paths as $path ) {
860
if ( ! @unlink( $path ) ) {
861
- error_log( 'Error removing local file ' . $path );
862
}
863
}
864
}
865
866
- /**
867
- * Add HiDPi suffix to a file path
868
- *
869
- * @param string $orig_path
870
- *
871
- * @return string
872
- */
873
- function get_hidpi_file_path( $orig_path ) {
874
- $hidpi_suffix = apply_filters( 'as3cf_hidpi_suffix', '@2x' );
875
-
876
- return $this->apply_file_suffix( $orig_path, $hidpi_suffix );
877
- }
878
-
879
/**
880
* Helper to apply a suffix to a file path
881
*
@@ -893,18 +1076,17 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
893
/**
894
* Get the object versioning string prefix
895
*
896
- * @param int $post_id
897
- *
898
* @return string
899
*/
900
- function get_object_version_string( $post_id ) {
901
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
902
$date_format = 'dHis';
903
} else {
904
$date_format = 'YmdHis';
905
}
906
907
- $time = $this->get_attachment_folder_time( $post_id );
908
909
$object_version = date( $date_format, $time ) . '/';
910
$object_version = apply_filters( 'as3cf_get_object_version_string', $object_version );
@@ -1151,7 +1333,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1151
* @return mixed
1152
*/
1153
function get_attachment_s3_info( $post_id ) {
1154
- return get_post_meta( $post_id, 'amazonS3_info', true );
1155
}
1156
1157
/**
@@ -1260,16 +1442,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1260
* Get the file prefix
1261
*
1262
* @param null|string $time
1263
- * @param null|int $post_id
1264
*
1265
* @return string
1266
*/
1267
- function get_file_prefix( $time = null, $post_id = null ) {
1268
$prefix = ltrim( trailingslashit( $this->get_object_prefix() ), '/' );
1269
$prefix .= ltrim( trailingslashit( $this->get_dynamic_prefix( $time ) ), '/' );
1270
1271
if ( $this->get_setting( 'object-versioning' ) ) {
1272
- $prefix .= $this->get_object_version_string( $post_id );
1273
}
1274
1275
return $prefix;
@@ -1423,7 +1604,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1423
}
1424
}
1425
1426
- $file = $this->encode_filename_in_path( $s3object['key'] );
1427
$url = $scheme . '://' . $domain_bucket . '/' . $file;
1428
1429
return apply_filters( 'as3cf_get_attachment_url', $url, $s3object, $post_id, $expires, $headers );
@@ -1454,7 +1635,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1454
}
1455
1456
$img_src = $matches[1];
1457
- $encoded_src = $this->encode_filename_in_path( $img_src );
1458
1459
return str_replace( $img_src, $encoded_src, $html );
1460
}
@@ -1475,7 +1656,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1475
}
1476
1477
if ( isset( $image[0] ) ) {
1478
- $image[0] = $this->encode_filename_in_path( $image[0] );
1479
}
1480
1481
return $image;
@@ -1496,12 +1677,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1496
}
1497
1498
if ( isset( $response['url'] ) ) {
1499
- $response['url'] = $this->encode_filename_in_path( $response['url'] );
1500
}
1501
1502
if ( isset( $response['sizes'] ) && is_array( $response['sizes'] ) ) {
1503
foreach ( $response['sizes'] as $key => $value ) {
1504
- $response['sizes'][ $key ]['url'] = $this->encode_filename_in_path( $value['url'] );
1505
}
1506
}
1507
@@ -1523,7 +1704,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1523
}
1524
1525
if ( isset( $data['url'] ) ) {
1526
- $data['url'] = $this->encode_filename_in_path( $data['url'] );
1527
}
1528
1529
return $data;
@@ -1555,11 +1736,12 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1555
* Encode file names according to RFC 3986 when generating urls
1556
* As per Amazon https://forums.aws.amazon.com/thread.jspa?threadID=55746#jive-message-244233
1557
*
1558
- * @param string $file
1559
*
1560
* @return string Encoded filename with path prefix untouched
1561
*/
1562
- function encode_filename_in_path( $file ) {
1563
$url = parse_url( $file );
1564
1565
if ( ! isset( $url['path'] ) ) {
@@ -1567,7 +1749,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1567
return $file;
1568
}
1569
1570
- if ( in_array( $this->normalize_file_path( $url['path'] ), $this->encode_files ) ) {
1571
// Already encoded, return original
1572
return $file;
1573
}
@@ -1583,7 +1765,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1583
return $file;
1584
}
1585
1586
- $normalized_file_path = $this->normalize_file_path( $encoded_file_path );
1587
1588
if ( ! in_array( $normalized_file_path, $this->encode_files ) ) {
1589
$this->encode_files[] = $normalized_file_path;
@@ -1595,15 +1777,30 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1595
/**
1596
* Normalize file path
1597
*
1598
- * @param string $path
1599
*
1600
* @return string mixed
1601
*/
1602
- function normalize_file_path( $path ) {
1603
$url = parse_url( $path );
1604
1605
if ( isset( $url['scheme'] ) ) {
1606
$path = str_replace( $url['scheme'] . '://', '', $path );
1607
}
1608
1609
return '/' . ltrim( $path, '/' );
@@ -1963,7 +2160,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
1963
} catch ( Exception $e ) {
1964
$error_msg_title = '<strong>' . __( 'Error Getting Bucket Region', 'amazon-s3-and-cloudfront' ) . '</strong> &mdash;';
1965
$error_msg = sprintf( __( 'There was an error attempting to get the region of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
1966
- error_log( $error_msg );
1967
1968
return new WP_Error( 'exception', $error_msg_title . $error_msg );
1969
}
@@ -2115,7 +2312,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2115
// if we encounter an error that isn't access denied, throw that error
2116
if ( ! $e instanceof Aws\Common\Exception\ServiceResponseException || 'AccessDenied' !== $e->getExceptionCode() ) {
2117
$error_msg = sprintf( __( 'There was an error attempting to check the permissions of the bucket %s: %s', 'amazon-s3-and-cloudfront' ), $bucket, $e->getMessage() );
2118
- error_log( $error_msg );
2119
2120
return new WP_Error( 'exception', $error_msg );
2121
}
@@ -2147,8 +2344,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2147
* Register modal scripts and styles so they can be enqueued later
2148
*/
2149
function register_modal_assets() {
2150
- $version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->plugin_version;
2151
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
2152
2153
$src = plugins_url( 'assets/css/modal.css', $this->plugin_file_path );
2154
wp_register_style( 'as3cf-modal', $src, array(), $version );
@@ -2158,8 +2355,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2158
}
2159
2160
function plugin_load() {
2161
- $version = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->plugin_version;
2162
- $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
2163
2164
$src = plugins_url( 'assets/css/styles.css', $this->plugin_file_path );
2165
wp_enqueue_style( 'as3cf-styles', $src, array( 'as3cf-modal' ), $version );
@@ -2210,7 +2407,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2210
'region',
2211
'domain',
2212
'virtual-host',
2213
- 'expires',
2214
'permissions',
2215
'cloudfront',
2216
'object-prefix',
@@ -2218,7 +2414,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2218
'serve-from-s3',
2219
'remove-local-file',
2220
'ssl',
2221
- 'hidpi-images',
2222
'object-versioning',
2223
'use-yearmonth-folders',
2224
'enable-object-prefix',
@@ -2278,7 +2473,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2278
'page' => self::$plugin_page,
2279
);
2280
2281
- $args = array_merge( $args, $default_args );
2282
2283
switch ( $url_method ) {
2284
case 'self':
@@ -2349,7 +2544,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2349
}
2350
2351
/**
2352
- * Get the prefix path for the files
2353
*
2354
* @param string $time
2355
*
@@ -2357,9 +2553,50 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2357
*/
2358
function get_dynamic_prefix( $time = null ) {
2359
$prefix = '';
2360
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
2361
- $uploads = wp_upload_dir( $time );
2362
- $prefix = str_replace( $this->get_base_upload_path(), '', $uploads['path'] );
2363
}
2364
2365
// support legacy MS installs (<3.5 since upgraded) for subsites
@@ -2367,33 +2604,38 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2367
$details = get_blog_details( get_current_blog_id() );
2368
$legacy_ms_prefix = 'sites/' . $details->blog_id . '/';
2369
$legacy_ms_prefix = apply_filters( 'as3cf_legacy_ms_subsite_prefix', $legacy_ms_prefix, $details );
2370
- $prefix = '/' . trailingslashit( ltrim( $legacy_ms_prefix, '/' ) ) . ltrim( $prefix, '/' );
2371
}
2372
2373
return $prefix;
2374
}
2375
2376
/**
2377
- * Get the base upload path
2378
- * without the multisite subdirectory
2379
*
2380
* @return string
2381
*/
2382
- function get_base_upload_path() {
2383
- if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
2384
- return ABSPATH . UPLOADS;
2385
}
2386
2387
- $upload_path = trim( get_option( 'upload_path' ) );
2388
2389
- if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) {
2390
- return WP_CONTENT_DIR . '/uploads';
2391
- } elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
2392
- // $dir is absolute, $upload_path is (maybe) relative to ABSPATH
2393
- return path_join( ABSPATH, $upload_path );
2394
- } else {
2395
- return $upload_path;
2396
}
2397
}
2398
2399
/**
@@ -2453,9 +2695,15 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2453
* @param int $post_id
2454
* @param array $s3object
2455
* @param string $acl
2456
*/
2457
function set_attachment_acl_on_s3( $post_id, $s3object, $acl ) {
2458
- // set ACL as private
2459
$args = array(
2460
'ACL' => $acl,
2461
'Bucket' => $s3object['bucket'],
@@ -2469,49 +2717,84 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2469
$s3client->PutObjectAcl( $args );
2470
$s3object['acl'] = $acl;
2471
2472
- // Add attachment to ACL update notice
2473
- $message = $this->make_acl_admin_notice_text( $s3object );
2474
- $this->notices->add_notice( $message );
2475
-
2476
// update S3 meta data
2477
if ( $acl == self::DEFAULT_ACL ) {
2478
unset( $s3object['acl'] );
2479
}
2480
update_post_meta( $post_id, 'amazonS3_info', $s3object );
2481
} catch ( Exception $e ) {
2482
- error_log( 'Error setting ACL to ' . $acl . ' for ' . $s3object['key'] . ': ' . $e->getMessage() );
2483
}
2484
}
2485
2486
/**
2487
- * Make admin notice text for when object ACL has changed
2488
*
2489
* @param array $s3object
2490
- *
2491
- * @return string
2492
*/
2493
- function make_acl_admin_notice_text( $s3object ) {
2494
$filename = basename( $s3object['key'] );
2495
- $acl = $this->get_acl_display_name( $s3object['acl'] );
2496
2497
- return sprintf( __( 'The file %s has been given %s permissions on Amazon S3.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl}</strong>" );
2498
}
2499
2500
/**
2501
* Check if PHP GD and Imagick is installed
2502
*/
2503
function check_for_gd_imagick() {
2504
$gd_enabled = $this->gd_enabled();
2505
$imagick_enabled = $this->imagick_enabled();
2506
2507
if( ! $gd_enabled && ! $imagick_enabled ) {
2508
$this->notices->add_notice(
2509
- __( '<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' ),
2510
array( 'flash' => false, 'only_show_to_user' => false, 'only_show_in_settings' => true )
2511
);
2512
}
2513
}
2514
2515
/**
2516
* Diagnostic information for the support tab
2517
*
@@ -2541,6 +2824,9 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2541
echo bloginfo( 'version' );
2542
if ( is_multisite() ) {
2543
echo ' Multisite';
2544
}
2545
echo "\r\n";
2546
@@ -2555,7 +2841,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2555
echo "\r\n";
2556
2557
echo 'MySQL: ';
2558
- echo esc_html( empty( $wpdb->use_mysqli ) ? mysql_get_server_info() : mysqli_get_server_info( $wpdb->dbh ) );
2559
echo "\r\n";
2560
2561
echo 'ext/mysqli: ';
@@ -2590,10 +2876,26 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2590
echo esc_html( get_locale() );
2591
echo "\r\n";
2592
2593
- echo 'Debug Mode: ';
2594
echo esc_html( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No' );
2595
echo "\r\n";
2596
2597
echo 'WP Max Upload Size: ';
2598
echo esc_html( size_format( wp_max_upload_size() ) );
2599
echo "\r\n";
@@ -2678,6 +2980,48 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2678
echo number_format_i18n( $sizes );
2679
echo "\r\n\r\n";
2680
2681
echo 'Bucket: ';
2682
echo $this->get_setting( 'bucket' );
2683
echo "\r\n";
@@ -2720,12 +3064,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2720
echo "\r\n";
2721
echo 'Object Versioning: ';
2722
echo $this->on_off( 'object-versioning' );
2723
- echo "\r\n";
2724
- echo 'Far Future Expiration Header: ';
2725
- echo $this->on_off( 'expires' );
2726
- echo "\r\n";
2727
- echo 'Copy HiDPI (@2x) Images: ';
2728
- echo $this->on_off( 'hidpi-images' );
2729
echo "\r\n\r\n";
2730
2731
do_action( 'as3cf_diagnostic_info' );
@@ -2733,6 +3071,18 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2733
echo "\r\n";
2734
}
2735
2736
echo "Active Plugins:\r\n";
2737
$active_plugins = (array) get_option( 'active_plugins', array() );
2738
$plugin_details = array();
@@ -2838,6 +3188,8 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2838
* @return string
2839
*/
2840
function get_acl_display_name( $acl ) {
2841
return ucwords( str_replace( '-', ' ', $acl ) );
2842
}
2843
@@ -2902,23 +3254,27 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
2902
* - If the site is MS
2903
* - If the blog is not the current blog defined
2904
*
2905
- * @param $blog_id
2906
*/
2907
- function switch_to_blog( $blog_id ) {
2908
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
2909
switch_to_blog( $blog_id );
2910
}
2911
}
2912
2913
/**
2914
* Helper to restore to the current Multisite blog
2915
- * - If the site is MS
2916
- * - If the blog is not the current blog defined
2917
- *
2918
- * @param $blog_id
2919
*/
2920
- function restore_current_blog( $blog_id ) {
2921
- if ( is_multisite() && ! $this->is_current_blog( $blog_id ) ) {
2922
restore_current_blog();
2923
}
2924
}
@@ -3003,13 +3359,6 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
3003
}
3004
}
3005
3006
- // HiDPI
3007
- if ( $this->get_setting( 'hidpi-images' ) ) {
3008
- foreach ( $paths as $path ) {
3009
- $paths[] = $this->get_hidpi_file_path( $path );
3010
- }
3011
- }
3012
-
3013
// Allow other processes to add files to be uploaded
3014
$paths = apply_filters( 'as3cf_attachment_file_paths', $paths, $attachment_id, $meta );
3015
@@ -3036,7 +3385,7 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
3036
* @return string
3037
*/
3038
function get_access_denied_notice_message( $single = true ) {
3039
- $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' ) );
3040
3041
$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 );
3042
if ( ! $single ) {
@@ -3185,16 +3534,38 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
3185
return $attachment_counts;
3186
}
3187
3188
/**
3189
* Throw error
3190
*
3191
* @param string $code
3192
* @param string $message
3193
*
3194
* @return WP_Error
3195
*/
3196
- public function _throw_error( $code, $message = '' ) {
3197
- return new WP_Error( $code, $message );
3198
}
3199
3200
/**
@@ -3216,6 +3587,101 @@ class Amazon_S3_And_CloudFront extends AWS_Plugin_Base {
3216
$url .= '#' . $hash;
3217
}
3218
3219
- return sprintf( '<a class="more-info" href="%s">%s</a> &raquo;', esc_url( $url ), __( 'More info', 'amazon-s3-and-cloudfront' ) );
3220
}
3221
}
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
*
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
/**
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
/**
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;
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'] );
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
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
+ * 1) We are not on the main site in a post-MU network, as wp-content/uploads is used
2580
+ * there, and
2581
+ * 2) We are not switched, as ms_upload_constants() hardcodes these constants to reflect
2582
+ * the original blog ID.
2583
+ *
2584
+ * Rather than UPLOADS, we actually use BLOGUPLOADDIR if it is set, as it is absolute.
2585
+ * (And it will be set, see ms_upload_constants().) Otherwise, UPLOADS can be used, as
2586
+ * as it is relative to ABSPATH. For the final piece: when UPLOADS is used with ms-files
2587
+ * rewriting in multisite, the resulting URL is /files. (#WP22702 for background.)
2588
+ */
2589
+ if ( defined( 'BLOGUPLOADDIR' ) ) {
2590
+ $prefix = untrailingslashit( BLOGUPLOADDIR );
2591
+ } else {
2592
+ $prefix = ABSPATH . UPLOADS;
2593
+ }
2594
+ }
2595
+ }
2596
+
2597
if ( $this->get_setting( 'use-yearmonth-folders' ) ) {
2598
+ $subdir = $this->get_year_month_directory_name( $time );
2599
+ $prefix .= $subdir;
2600
}
2601
2602
// support legacy MS installs (<3.5 since upgraded) for subsites
2604
$details = get_blog_details( get_current_blog_id() );
2605
$legacy_ms_prefix = 'sites/' . $details->blog_id . '/';
2606
$legacy_ms_prefix = apply_filters( 'as3cf_legacy_ms_subsite_prefix', $legacy_ms_prefix, $details );
2607
+ $prefix = '/' . trailingslashit( ltrim( $legacy_ms_prefix, '/' ) ) . ltrim( $subdir, '/' );
2608
}
2609
2610
return $prefix;
2611
}
2612
2613
/**
2614
+ * Generate the year and month sub-directory from $time if provided,
2615
+ * then POST time if available, otherwise use current time
2616
+ *
2617
+ * @param string $time
2618
*
2619
* @return string
2620
*/
2621
+ function get_year_month_directory_name( $time = null ) {
2622
+ if ( ! $time && isset( $_POST['post_id'] ) ) {
2623
+ $time = get_post_field( 'post_date', $_POST['post_id'] );
2624
}
2625
2626
+ if ( ! $time ) {
2627
+ $time = current_time( 'mysql' );
2628
+ }
2629
2630
+ $y = substr( $time, 0, 4 );
2631
+ $m = substr( $time, 5, 2 );
2632
+ $subdir = "/$y/$m";
2633
+
2634
+ if ( false === strpos( $subdir, '//' ) ) {
2635
+ return $subdir;
2636
}
2637
+
2638
+ return '';
2639
}
2640
2641
/**
2695
* @param int $post_id
2696
* @param array $s3object
2697
* @param string $acl
2698
+ *
2699
+ * @return array|bool|WP_Error
2700
*/
2701
function set_attachment_acl_on_s3( $post_id, $s3object, $acl ) {
2702
+ // Return early if already set to the desired ACL
2703
+ if ( isset( $s3object['acl'] ) && $acl === $s3object['acl'] ) {
2704
+ return false;
2705
+ }
2706
+
2707
$args = array(
2708
'ACL' => $acl,
2709
'Bucket' => $s3object['bucket'],
2717
$s3client->PutObjectAcl( $args );
2718
$s3object['acl'] = $acl;
2719
2720
// update S3 meta data
2721
if ( $acl == self::DEFAULT_ACL ) {
2722
unset( $s3object['acl'] );
2723
}
2724
update_post_meta( $post_id, 'amazonS3_info', $s3object );
2725
} catch ( Exception $e ) {
2726
+ $msg = 'Error setting ACL to ' . $acl . ' for ' . $s3object['key'] . ': ' . $e->getMessage();
2727
+ AS3CF_Error::log( $msg );
2728
+
2729
+ return new WP_Error( 'acl_exception', $msg );
2730
}
2731
+
2732
+ return $s3object;
2733
}
2734
2735
/**
2736
+ * Make admin notice for when object ACL has changed
2737
*
2738
* @param array $s3object
2739
*/
2740
+ function make_acl_admin_notice( $s3object ) {
2741
$filename = basename( $s3object['key'] );
2742
+ $acl = ( isset( $s3object['acl'] ) ) ? $s3object['acl'] : self::DEFAULT_ACL;
2743
+ $acl_name = $this->get_acl_display_name( $acl );
2744
+ $text = sprintf( __( '<strong>WP Offload S3</strong> &mdash; The file %s has been given %s permissions on Amazon S3.', 'amazon-s3-and-cloudfront' ), "<strong>{$filename}</strong>", "<strong>{$acl_name}</strong>" );
2745
2746
+ $this->notices->add_notice( $text );
2747
}
2748
2749
/**
2750
* Check if PHP GD and Imagick is installed
2751
*/
2752
function check_for_gd_imagick() {
2753
+ if ( ! $this->is_plugin_setup() ) {
2754
+ // No notice until plugin is setup
2755
+ return;
2756
+ }
2757
+
2758
$gd_enabled = $this->gd_enabled();
2759
$imagick_enabled = $this->imagick_enabled();
2760
2761
if( ! $gd_enabled && ! $imagick_enabled ) {
2762
$this->notices->add_notice(
2763
+ __( '<strong>WP Offload S3 Requirement 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' ),
2764
array( 'flash' => false, 'only_show_to_user' => false, 'only_show_in_settings' => true )
2765
);
2766
}
2767
}
2768
2769
+ /**
2770
+ * Output image size names and dimensions to a string
2771
+ *
2772
+ * @return string
2773
+ */
2774
+ function get_image_sizes_details() {
2775
+ global $_wp_additional_image_sizes;
2776
+
2777
+ $size_details = '';
2778
+ $get_intermediate_image_sizes = get_intermediate_image_sizes();
2779
+
2780
+ // Create array with sizes
2781
+ foreach ( $get_intermediate_image_sizes as $size ) {
2782
+ if ( in_array( $size, array( 'thumb', 'thumbnail', 'medium', 'large', 'post-thumbnail' ) ) ) {
2783
+ // Run checks for dimension and name values
2784
+ if ( ( $width = get_option( $size . '_size_w' ) ) && ( $height = get_option( $size . '_size_h' ) ) ) {
2785
+ $size_details .= $size . ' (' . $width . 'x' . $height . ')' . "\r\n";
2786
+ } else {
2787
+ $size_details .= $size . ' (none)' . "\r\n";
2788
+ }
2789
+ } elseif ( isset( $_wp_additional_image_sizes[ $size ] ) ) {
2790
+ $size_details .= $size . ' (' . $_wp_additional_image_sizes[ $size ]['width'] . 'x' . $_wp_additional_image_sizes[ $size ]['height'] . ')' . "\r\n";
2791
+ }
2792
+
2793
+ }
2794
+
2795
+ return $size_details;
2796
+ }
2797
+
2798
/**
2799
* Diagnostic information for the support tab
2800
*
2824
echo bloginfo( 'version' );
2825
if ( is_multisite() ) {
2826
echo ' Multisite';
2827
+ echo "\r\n";
2828
+ echo 'Multisite Site Count: ';
2829
+ echo esc_html( get_blog_count() );
2830
}
2831
echo "\r\n";
2832
2841
echo "\r\n";
2842
2843
echo 'MySQL: ';
2844
+ echo esc_html( $wpdb->db_version() );
2845
echo "\r\n";
2846
2847
echo 'ext/mysqli: ';
2876
echo esc_html( get_locale() );
2877
echo "\r\n";
2878
2879
+ echo 'Organize uploads by month/year: ';
2880
+ echo esc_html( get_option( 'uploads_use_yearmonth_folders' ) ? 'Enabled' : 'Disabled' );
2881
+ echo "\r\n";
2882
+
2883
+ echo 'WP_DEBUG: ';
2884
echo esc_html( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No' );
2885
echo "\r\n";
2886
2887
+ echo 'WP_DEBUG_LOG: ';
2888
+ echo esc_html( ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) ? 'Yes' : 'No' );
2889
+ echo "\r\n";
2890
+
2891
+